Redis 设计与实现 (二)--数据库

复制代码
typedef struct redisDb {
    dict *dict;                 /* The keyspace for this DB */
    dict *expires;              /* Timeout of keys with a timeout set */
    dict *blocking_keys;        /* Keys with clients waiting for data (BLPOP) */
    dict *ready_keys;           /* Blocked keys that received a PUSH */
    dict *watched_keys;         /* WATCHED keys for MULTI/EXEC CAS */
    struct evictionPoolEntry *eviction_pool;    /* Eviction pool of keys */
    int id;                     /* Database ID */
    PORT_LONGLONG avg_ttl;          /* Average TTL, just for stats */
} redisDb;
复制代码

一、数据库  默认是16个

二、切换数据库:select 0~15

三、数据库键空间  *dict  

  保存了数据库中的所有键值对,它是一个字典称之为键空间

  键空间的键 =数据库的键;

  键空间的值=数据库的值;

  3.1 添加新键:新键添加到键空间字典中

  3.2 删除键:键空间 删除键所对应的键值对对象

  3.3 更新键:对键空间的键对应的值进行更新

四、读写键控件时的维护操作

  4.1 读取一个键之后,判断键是否存在,更新服务器的键空间命中次数或者键空间未命中次数。 

复制代码
127.0.0.1:6379> INFO stats
# Stats
total_connections_received:3
total_commands_processed:20
instantaneous_ops_per_sec:0
total_net_input_bytes:1026
total_net_output_bytes:31711
instantaneous_input_kbps:0.00
instantaneous_output_kbps:0.00
rejected_connections:0
sync_full:0
sync_partial_ok:0
sync_partial_err:0
expired_keys:0
evicted_keys:0
keyspace_hits:8  //命中次数
keyspace_misses:0 //未命中次数
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:261
migrate_cached_sockets:0
slave_expires_tracked_keys:0
active_defrag_hits:0
active_defrag_misses:0
active_defrag_key_hits:0
active_defrag_key_misses:0
复制代码

 

  4.2  服务器会更新LRU(最后一次使用)时间,用于计算键的空闲时间

    OBJECT idletime key   毫秒

127.0.0.1:6379> OBJECT idletime sun
(integer) 827

 

    4.3 如果发现键过期,先删除这个键,然后执行后续操作

  4.4 如果这个键被监视 WATCH key  ,标记为脏(dirty)。服务器每次修改一个键,都会对脏键进行+1

  4.5 数据库开通通知功能,每次修改键,都会发送通知。

 

 五、设置键的生存时间或者过期时间 

   EXPIRE key ttl    秒数

   PEXPIRE key ttl   毫秒数

   EXPIREAT key timestamp  秒数时间戳

   PEXPIREAT  key timestamp  毫秒数时间戳

 六、保存过期时间

   dict *expires 过期时间键的集合
   过期字典键-指针,指向数据库的键
   过期字典值-long,毫秒精度时间戳

七、移除过期时间
  PERSIST
  在过期字典集合中,查询键,解除过期设置。
  TTL
  秒为单位键的剩余生存周期
  PTTL 毫秒级
复制代码
127.0.0.1:6379> get msg
(nil)
127.0.0.1:6379> set msg "sun"
OK
127.0.0.1:6379> PEXPIREAT msg 1161680467300000
(integer) 1
127.0.0.1:6379> get msg
"sun"
127.0.0.1:6379> TTL msg
(integer) 1160163662408
127.0.0.1:6379> PERSIST msg
(integer) 1
127.0.0.1:6379> TTL msg
(integer) -1
复制代码

 

八、过期键的删除策略
惰性删除+定期删除

九、过期键的影响
9.1 RDB文件 -- SAVA 和 BGSAVE,已经过期的键不保存
  主服务器载入RDB--忽略过期间
  从服务器载入RDB--全局导入,主从同步时,从数据会被清空。
9.2 AOF文件
 AOF文件写入
  执行惰性或者定期删除之前 -- 过期间不受影响
  执行惰性或者定期删除之后 -- 追加一条删除记录
AOF重写
  过期键不会写入到AOF文件中
9.3 复制
  复制模式,从服务器依赖于主服务器,从服务器即便接收到删除命令,也不会删除。

十、数据库通知
  客户端订阅指定的变化通知
  
127.0.0.1:6379> SUBSCRIBE __KEYSPACE@0__:MSG
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "__KEYSPACE@0__:MSG"
3) (integer) 1

posted @   K战神  阅读(323)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
点击右上角即可分享
微信分享提示