文章目录
Redis数据库
1. 表示形式
Redis中所有的数据库都保存在服务器状态RedisServer结构的db数组中,db数组中的每一个元素表示一个具体的数据库,每个数据库又是使用redisDb结构表示。Redis默认初始化的数据库数量为16,该值会保存在redisServer的dbnum字段中。如下所示:
用于可以通过修改redis.conf中的databases来设置数据库的数量。
# Set the number of databases. The default database is DB 0, you can select
# a different one on a per-connection basis using SELECT <dbid> where
# dbid is a number between 0 and 'databases'-1
databases 16
用户在使用Redis时,默认操作的是0号数据库。如果用户想要操作其他的数据库,可以使用SELECT命令来进行转换,底层通过修改RedisClient结构的db指针来指向具体指定的数据库。
2. 键的操作
Redis是一个key-value形式的NoSQL数据库,其中键总是一个字符串,而value可以是所支持的其他任意类型。对于Redis的底层来说,redisDb中的dict字典(键空间)用来保存对应额key-value对,expires字典用来保存对应的key的过期时间。
针对于键的常见操作有:
- 添加:将一个新的键值对添加到dict字典中
- 删除:删除dict字典中对应的键所对应的键值对
- 更新:更新dict字典中指定的键所对应的值
- 取值:根据指定的键从dict中获取相应的值
Redis中提供了不同的命令来设置key的过期时间或是生存时间,如下所示:
- EXPIRE:将键的生存时间设置为ttl秒
- PEXPIRE:将键的生存时间设置为ttl毫秒
- EXPIREAT:将键的过期时间设置为timestamp所指定的秒数时间戳
- PEXPIREAT:将键的过期时间设置为timestamp所指定的毫秒数时间戳
但是,Redis底层最终都是使用PEXPIREAT命令来设置键的过期时间,具体的过期时间保存在redisDb的expires字典中。字典的键是一个指针,指向对应的键对象,值为对应的过期时间(毫秒精度的UNIX时间戳)。
具体判定一个键是否过期需要经过以下两步:
- 检查给定的键在expires中是否存在;如果存在,获取键的过期时间
- 检查当前UNIX时间戳是否大于过期时间;如果是,表示已经过期,否则,未过期
另外,用户也可以使用PERSIST命令移除指定键的过期时间,以及使用TTL和PTTL计算键的剩余生存时间。
3. 持久化对过期键的处理
Redis支持RDB和AOF两种持久化方式,它们针对于过期的键分别有不同的处理策略。对于RDB持久化来说:
- 生成RDB文件时,程序会对数据库中的键进行检查,已经过期的键是不会保存到生成的RDB文件中
- 主节点载入RDB文件时,程序会对键进行检查,已经过期的键不会被载入
- 从节点载入RDB文件时,不管键是否过期都会被载入
而对于AOF这种追加写命令的持久化方式来说:
- AOF写入时,当过期的键被删除之后,程序会向AOF文件追加一条DEL命令,显示记录键已被删除
- AOF重放时,程序会对键进行检查,已经过期的键不会被保存到重放后的AOF文件
4. 主从复制对过期键的处理
当主节点删除一个键之后,它会显式的向所有的从节点发送一个DEL命令,通知从节点也删除相应的键。对于从节点来说,它在处理除了主节点发来的DEL命令之外,即时碰到已经过期的键也不会删除,而是正常响应。只有它接受到的是主节点的DEL命令,才会删除对应的过期键。