Redis 学习

以下内容来自:《Redis 设计与实现》

数据库键空间

Redis 是一个键值对(key-value pair)数据库服务器,服务器中的每个数据库都由I个 redis/redisDb 结构表示,其中,redisDb 结构的 dict 字典保存了数据库中的所有键值对,这个字典称为键空间(key space)。

1
2
3
4
5
6
7
8
9
10
11
12
13
typedef struct redisDb {

// ...

// 数据库键空间,保存着数据库中所有键值对
dict *dict;

// 过期字典,保存着键的过期时间
dict *expires;

// ...

} redisDb;

键空间和用户所见的数据库是直接对应的:

  • 键空间的键也就是数据库的键,每个键都是一个字符串对象。
  • 键空间的值也就是数据库的值,每个值可以是字符串对象、列表对象、哈希表对象、集合对象和有序集合对象中的任意一种 Redis 对象。

设置建的生存时间和过期时间

过期字典

redisDb 结构的 expires 字典保存了数据库中所有键的过期时间,我们称这个字典为过期字典:

  • 过期字典的键是一个指针,这个指针指向键空间中的某个键对象(即某个数据库键)。
  • 过期字典的值是一个 long long 类型的整数,这个整数保存了键所指向的数据库键的过期时间——一个毫秒精度的 UNIX 时间戳。

EXPIRE/PEXPIRE

给数据库中某个键设置生存时间(Time To Live,TTL),即键可以存在多久。

Redis PEXPIRE 命令和 EXPIRE 命令的作用类似,都是为数据库中某个键设置生存时间(在经过指定的秒数或者毫秒数之后,服务器就会自动删除生存时间为 0 的键),但是 PEXPIRE 命令 以毫秒为单位, EXPIRE 命令以秒为单位。

  • EXPIRE 命令用于将键 key 的生存时间设置为 ttl 秒。
  • PEXPIRE 命令用于将键 key 的生存时间设置为 ttl 毫秒。

EXPIREAT/PEXPIREAT

给数据库中某个键设置过期时间(Expire Time),即键什么时候会被删除。

  • EXPIREAT 命令用于将键 key 的过期时间设置为 timestamp 所指定的秒数时间戳。
  • PEXPIREAT 命令用于将键 key 的过期时间设置为 timestamp 所指定的毫秒数时间戳。

过期键的判定

  1. 检查给定键是否存在于过期字典中:如果存在,那么取得键的过期时间。
  2. 检查当前 UNIX时间戳是否大于键的过期时间:如果是,那么键已经过期,否则,键未过期。

TTL/PTTL

查询数据库中某个键的剩余生存时间。TTL 和 PTTL 两个命令都是通过计算键的过期时间和当前时间之间的差来实现的。

TTL 命令以秒为单位返回键的剩余生存时间,而 PTTL 命令则以毫秒为单位返回剩余键的剩余生存时间。

PERSIST

移除过期时间。PERSIST 命令是 PEXPIREAT 命令的反操作:PERSIST 命令在过期字典中查找给定的键,并解除键和值(过期时间)在过期字典中的关联。

过期键的删除策略

删除过期键的三种可能的策略:

  • 定时删除:在设置键的过期时间的同时,创建一个定时器(Timer),让定时器在键的过期时间来临时,立即执行对键的删除操作。该策略对 CPU 不友好,对内存友好。
  • 惰性删除:放任键过期不管,但是每次从键空间中获取键时,都检查取得的键是否过期,如果过期的话,就删除该键;如果没有过期,就返回该键。该策略对 CPU 友好,对内存不友好。
  • 定期删除:每隔一段时间,程序就对数据库进行一次检查,删除里面的过期键。至于要删除多少过期键,以及要检查多少个数据库,则有算法决定。该策略是上面两种策略的折中。

在上面的三种策略中,第一种和第三种为主动删除策略,而第二种则为被动删除策略。

Redis 服务器实际使用的是惰性删除和定期删除两种策略。

内存淘汰策略

定期删除和惰性删除都不能及时删除掉已经过期的键,所以当某时刻大量键堆积在内存里,导致 Redis 内存快耗尽了,还需要用到 Redis 的内存淘汰策略。

eviction policy:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
volatile-lru:在所有设置了过期时间的键中,淘汰掉最近最少使用(LRU,least recently used) 的一个键。

allkeys-lru:在所有键中,淘汰掉最近最少使用(LRU,Least Recently Used)的一个键。

volatile-lfu:在所有设置了过期时间的键中,淘汰掉最近最不常被访问(LFU,Least Frequently Used)的一个键。

allkeys-lfu:在所有键中,淘汰掉最近最不常被访问(LFU,Least Frequently Used)的一个键。

volatile-random:在所有设置了过期时间的键中,随机淘汰掉一个键。

allkeys-random:在所有的键中,随机淘汰掉一个键。

volatile-ttl:淘汰具有最小存活时间(TTL)的键。

noeviction :不淘汰任何一个键,当有写入操作时,直接报错。
分享到:
Disqus 加载中...

如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理