redis数据库组成
-
redis在启动时会启动
16
个数据库实例 -
redis客户端链接时, 默认链接的是
0
数据库 -
可以通过
select index
的方式切换数据库
数据存储方式
-
redis是键值对方式存储数据, 键是字符串对象; 值时具体对象,包括字符串对象, 列表对象, 集合对象, 哈希对象, 有序集合对象
-
redis在每个数据库中存储数据是采用的是
dict(字典)
数据结构进行存储-
key : 字符串对象
redisObject
-
value: 存储的是
redisObject
对象
-
读写键控件时的维护操作
-
在读取一个键(读操作和写操作都要对键进行读取), 服务器会根据键是否存在来更新服务器的键空间命中(hit)次数或键空间不命中(miss)次数. 这两个值可以在
info stats
命令的keyspace_hits
属性和keyspce_misses
属性查看 -
在读取一个键之后, 服务器会更新键的
LRU
时间。这个值可以用于计算键的闲置时间, 可以使用OBJECT idletime <key>
命令查看 -
如果服务器在读取一个键时发现该键已经过期, 那么服务器会先删除这个过期键. 再执行其他操作
-
如果客户端使用
WATCH
命令监视了某个键, 那么服务器在对呗监视的键进行修改之后, 会将这个键标记为脏(dirty), 从而让事务程序注意到这个键已经被修改过. -
如果服务器开启了数据库通知功能, 那么在对键进行修改之后, 服务器将按配置发送相应的数据通知.
设置过期时间
在redis中, 可以通过为key
设置过期时间, 达到在指定时间(毫秒或者秒为精度)之后, 将自动删除键.
-
EXPIRE <key> <ttl> 命令用于将键key的生存时间设置为ttl秒
-
EXPIREAT <key> <timestamp> 命令用于将键key的生存时间设置为timestamp所指定的秒数时间戳
-
PEXPIRE <key> <ttl> 用于将键key的生存时间设置为ttl毫秒
-
PEXPIREAT <key> <timestamp> 命令用于将键key的过期时间设置为timestamp所指定的毫秒数时间戳
NOTE: 对于以上的任何命令, 最终都是使用
PEXPIREAT
命令
保存过期时间
在redis中保存过期时间是通过dict
老保存, 保存格式为:
-
key: 为键值对的key对象, 与具体的键值对共享同一个字符串对象
-
value: 具体的过期时间,
NOTE: 因为存储的
key-value
和过期时间的key-value
中的key是共用对象, 所以不会造成内存浪费的情形.
移除过期时间
PERSIST
命令可以移除一个键的过期时间:
redis> PEXPIREAT message 122223232323 redis> TTL message redis> PERSIST message redis> TTL message
过期键的删除策略
-
定时删除: 在设置键的过期时间的同时 , 创建一个定时器(timer), 让定时器在键的过期时间来临时, 立即执行对键的删除操作
-
惰性删除: 放任键过期不管, 但是每次从键空间中获取键时, 都检查取的的键是否过期, 如果过期的话, 就删除该键; 如果没有过期, 就返回该键
-
定期删除: 每隔一段时间, 程序就对该数据库进行一次检查, 删除里面的过期键.
定时删除
-
定时删除对内存最友好, 可以保证过期的键会尽可能地被删除, 并释放过期键占用的内存.
-
对CPU时间时不友好的, 在过期键比较多的情况下, 删除过期键这一行为可能会占用相当一部分CPU时间, 在内存不紧张但是CPU时间非常紧张的情况下, 将CPU时间用在删除和当前任务无关的过期键上, 无疑对服务器响应时间和吞吐量造成影响
-
创建定时器需要用到
redis
服务器中的时间事件, 而当前时间事件实现方式-无序链表
, 查找一个事件的时间复杂度为O(N)
. 并不能处理大量的事件时间
惰性删除
-
惰性删除对CPU最友好, 因为不会花过多的时间在删除过期键的行为上, 只在有需要的时候执行必要的键删除操作.
-
堆内存来说很不友好, 如果一个键已经过期, 但是仍然在数据库中, 那么只要这个键不被删除, 它所占用的内存就不会释放。
定期删除
-
定时删除占用太多CPU时间, 影响服务器的响应时间和吞吐量
-
惰性删除浪费太多内存, 有内存泄露的危险
定期删除策略是抢两种策略的一种整合折中:
-
定期删除策略每个一段时间执行一次删除过期键操作, 并通过限制删除操作执行的时长和频率减少删除操作对CPU时间的影响
-
通过定期删除过期键, 定期删除策略有效地减少了因为过期键带来内存浪费
Redis的过期键删除策略
对于redis服务器实际使用的是惰性删除
和定义删除
两种策略: 通过配合使用这两种删除策略, 很好地在合理使用CPU时间和避免浪费内存之间取得平衡。
AOF, RDB和复制功能对过期键的处理
生成RDB文件
在执行SAVE命令或者BGSAVE
命令创建一个新的RDB文件时, 程序会对数据库中键进行检查, 已经过期的键不会被保存到新创建的RDB文件中.
载入RDB文件
在启动Redis服务器时, 如果服务器开启了RDB功能, 那么服务器将对RDB文件进行载入:
-
如果服务器以主服务器模型运行, 那么在载入RDB文件时, 程序会对文件中保存的键进行检查, 未过期的键将会载入到数据库中, 而过期键会被忽略, 所以过期键对载入RDB文件的主服务器不会造成影响。
-
如果服务器以
从服务器模式
运行, 那么在载入RDB文件时, 文件中保存的所有键, 不论是否过期, 都会被载入到数据库中. 不过因为主从服务器在进行数据同步的时候, 从服务器的数据库就会被清空. 所以过期键对载入RDB文件的从服务器也不会造成影响。
AOF文件写入
当服务器以AOF持久化模式运行时, 如果数据库中的某个键已经过期, 但它还没有被惰性删除或者定期删除, 那么AOF文件不会因为这个过期键而产生任何影响。
当过期键被惰性删除或者定期删除之后, 程序会向AOF文件追加一条DEL命令, 来显式地记录该键已被删除.
AOF重写
和生成RDB文件时类似, 在执行AOF重写的过程中, 程序会对数据库中的键进行检查, 已过期的键不会被保存到重写后的AOF文件中.
复制
当服务器运行在复制模式下时, 从服务器的过期键删除动作由主服务器控制:
-
主服务器在删除一个过期键之后, 会显示地向所有从服务器发送一个
DEL
命令, 告知从服务器删除这个过期键 -
从服务器在执行客户端发送的读命令时, 即使碰到过期键也不会将过期键删除, 而是继续像处理未过期的键一样处理过期键
-
从服务器只有在接到主服务器发来的
DEL
命令之后, 才会删除过期键.
数据库通知
数据库通知是Redis 2.8
版本新增加的功能, 这个功能可以让客户端通过订阅给定的频道或者模式, 来获知数据库中键的变化, 以及数据库中命令的执行情况.
服务器配置的notify-keyspace-events
选项决定了服务器所发送的通知类型:
-
想让服务器发送所有类型的键空间通知和键时间通知, 可以将选项设置为
AKE
-
想让服务器发送所有类型的键空间通知, 可以将选项的值设置为
AK
-
想让服务器发送所有类型的键时间通知, 可以将选项的值设置为
AE
-
想让服务器只发送和字符串键有关的键空间通知, 可以将选项的值设置为
K$
-
想让服务器只发送和列表键有关的键时间通知, 可以将选项设置为