缓存使用-2、Redis 内部结构

Redis的内部结构如下图所示:

各功能模块说明如下:

File Event: 处理文件事件(在多个客户端中实现多路复用,接受它们发来的命令请求(读事件),并将命令的执行结果返回给客户端(写事件))

Time Event: 时间事件(更新统计信息,清理过期数据,附属节点同步,定期持久化等)

AOF: 命令日志的数据持久化

RDB:实际的数据持久化

Lua Environment : Lua 脚本的运行环境. 为了让 Lua 环境符合 Redis 脚本功能的需求, Redis 对 Lua 环境进行了一系列的修改, 包括添加函数库、更换随机函数、保护全局变量, 等等

Command table(命令表):在执行命令时,根据字符来查找相应命令的实现函数。

Share Objects(对象共享):

主要存储常见的值:a.各种命令常见的返回值,例如返回值OK、ERROR、WRONGTYPE等字符;b. 小于 redis.h/REDIS_SHARED_INTEGERS (默认1000)的所有整数。通过预分配的一些常见的值对象,并在多个数据结构之间共享对象,程序避免了重复分配的麻烦。也就是说,这些常见的值在内存中只有一份。

Databases:

Redis数据库是真正存储数据的地方。当然,数据库本身也是存储在内存中的。

Databased的数据结构伪代码如下:

<span style="font-family:Microsoft YaHei;font-size:18px;">typedef struct redisDb {
    // 保存着数据库以整数表示的号码
    int id;
 
    // 保存着数据库中的所有键值对数据
    // 这个属性也被称为键空间(key space)
    dict *dict;
 
    // 保存着键的过期信息
    dict *expires;
 
    // 实现列表阻塞原语,如 BLPOP
    // 在列表类型一章有详细的讨论
    dict *blocking_keys;
    dict *ready_keys;
 
    // 用于实现 WATCH 命令
    // 在事务章节有详细的讨论
    dict *watched_keys;
} redisDb;
</span>

一个数据库,在内存中的数据结构如下图所示:

Database的内容要点包括:

  1. 数据库主要由 dict 和 expires 两个字典构成,其中 dict 保存键值对,而 expires 则保存键的过期时间。
  2. 数据库的键总是一个字符串对象,而值可以是任意一种 Redis 数据类型,包括字符串、哈希、集合、列表和有序集。
  3. expires 的某个键和 dict 的某个键共同指向同一个字符串对象,而 expires键的值则是该键以毫秒计算的 UNIX 过期时间戳。
  4. Redis 使用惰性删除和定期删除两种策略来删除过期的键。
  5. 更新后的 RDB 文件和重写后的 AOF 文件都不会保留已经过期的键。
  6. 当一个过期键被删除之后,程序会追加一条新的 DEL 命令到现有 AOF 文件末尾。
  7. 当主节点删除一个过期键之后,它会显式地发送一条 DEL 命令到所有附属节点。
  8. 附属节点即使发现过期键,也不会自作主张地删除它,而是等待主节点发来 DEL 命令,这样可以保证主节点和附属节点的数据总是一致的。

数据库的dict 字典和expires 字典的扩展策略和普通字典一样。它们的收缩策略是:当节点的填充百分比不足 10% 时,将可用节点数量减少至大于等于当前已用节点数量。

原文地址:https://www.cnblogs.com/chenxiaoxian/p/10426918.html