Redis——数据库
仅作为笔记,码字不易,转载请标明出处。
前言
仅作为笔记
一、服务器中的数据库
- Redis服务器默认会创建16个数据库。 可以根据服务器配置的database选项决定。
二、数据库键空间
- Redis是一个键值对(key-value pair)数据库服务器,服务器中的每个数据库都由redis.h/redisDb 结构表示,其中,redisDb结构的dict字典保存了数据库中的所有键值对,我们将这个字典称为键空间(key space)。
上图可以用来参照Redis数据库的底层设计,redisDb的数量由上面提到的database参数可以指定。 - 添加新键:添加一个新键值对到数据库,实际上就是将一个新键值对添加到键空间字典里面,其中键为字符串对象,而值为任意一种类型的Redis对象(之前提到过五种数据类型,每一种对应一种对象)。
- 删除键:在键空间(字典)里面删除键所对应的键值对对象。
- 更新键:对键空间里面键所对应的值对象进行更行。
- 对键取值:在键空间中取出键所对应的值对象。
三、设置键的生存时间或过期时间
- 使用EXPIRE命令或PEXPIRE命令设置键生存时间(键可以存在多久),生存时间为0会被服务器自动删除。
- 使用EXPIREAT命令或者PEXPIREAT(实际上另外三个命令都是由这个命令实现的)命令可以给某个键设置过期时间(键什么时候被删除)。当键的过期时间来临时,服务器会自动从数据库中删除这个键。
- 过期时间保存在expires字典里,叫做过期字典。
- PERSIST可以移除一个键的过期时间。执行这个后,过期字典中被移除过期时间的键的键值对就会消失。
- 过期键的判定:
1)检查给定键是否存在于过期字典中,如果存在,那么取得键的过期时间。 2)检查当前UNIX时间戳是否大于键的过期时间,如果是的话,那么键已经过期,否则没过期。
四、过期键删除策略
键判定了过期后就该删除,那么怎么删除呢?看下面的策略。
-
定时删除:在设置键的同时,创建一个定时器,让定时器在键过期时间来临时,立即执行对键的删除操作,并释放内存。 缺点:对cpu时间不友好,因为是立即执行,如果出现某一时刻有特别多的过期键,那么就会导致cpu去大量的处理这些过期键,但是这时候又不缺内存,那么如此使用cpu将会导致此时服务器的响应时间和吞吐量造成影响。 -
惰性删除:对CPU时间来说是最友好的,程序只会在取出键时才对键进行过期检查,这样可以保证删除过期键的操作只会在非做不可的情况下才进行,删除的目标仅限于当前处理的键,不会删除其他无关的过期键花费额外的CPU时间。 缺点:对内存不友好,因为只处理取出来的键的话会存在许多已经过期的键还存在内存中。 -
定期删除:这是一种定时删除(缺点是太花费cpu时间,影响服务器性能和吞吐量)和惰性删除(对内存不友好)的折中做法。 原理:每隔一段时间执行一次删除过期键的操作,并通过限制删除操作执行的时常和频率来减少删除操作对CPU时间的影响。并且由于是定期删除,有一定的执行时间,可以有效地减少因为过期键而带来的内存浪费。 注意:定期删除如果执行太频繁和执行时常过长,会退化成定时删除。如果执行频率很少且时常短,会退化成惰性删除。
五、AOF、RDB和复制功能对过期键的处理
- 如果服务器以主服务器模式运行:载入RDB文件时,程序会对文件保存的键进行检查,未过期的会被载入到数据库,过期的会被忽略,所以过期键不会对载入RDB文件的服务器造成什么影响。
- 如果以从服务器模式运行:载入RDB文件时,程序会把文件中保存的所有键都会载入,无论过期与否,但是因为主从服务器进行数据同步的时候,从服务器的数据库会被清空,所以过期键对载入RDB文件的从服务器也不会造成什么影响。
- 当服务器以AOF持久化模式运行,如果数据库中的某个键已经过期,但是还没被删除,那么AOF不会因为这个过期键而产生任何的影响。当过期键被删除后程序会向AOF文件追加一条DEL命令,显示的记录该键已被删除。
- AOF重写:和生成RDB文件时类似(和上面载入RDB文件时一样)。
- 复制:
1)主服务器在删除一个过期键之后,会显示地向所有从服务器发送一个DEL命令,告知从服务器删除这个过期键。 2)从服务器在执行客户端发送的读命令时,即使碰到过期键也不会将其删除,而是向处理未过期键一样处理。 3)从服务器只有在接到主服务器发来的DEL命令之后,才会删除过期键。
小结:通过由主服务器来控制从服务器统一删除过期键,可以保证主从服务器数据的一致性,也正是因为这个原因,当一个过期键任然存在于主服务器的数据库时,这个过期键在从服务器的复制品也会继续存在。
六、重点回顾
- Redis服务器的所有数据库都保存在redisServer . db数组中,而数据库的数量则由redisServer .dbnum属性保存。
- 客户端通过修改目标数据库指针,让它指向redisServer . db数组中的不同元素来切换不同的数据库。
- 数据库主要由dict和expires两个字典构成,其中dict字典负责保存键值对,而expires字典则负责保存键的过期时间。
- 因为数据库由字典构成,所以对数据库的操作都是建立在字典操作之上的。
- 数据库的键总是一个字符串对象,而值则可以是任意一种Redis对象类型,包括字符串对象、哈希表对象、集合对象、列表对象和有序集合对象,分别对应字符串键、哈希表键、集合键、列表键和有序集合键。
- expires字典的键指向数据库中的某个键,而值则记录了数据库键的过期时间,过期时间是一个以毫秒为单位的UNIX时间戳。
- Redis使用惰性删除和定期删除两种策略来删除过期的键:惰性删除策略只在碰到过期键时才进行删除操作,定期删除策略则每隔一段时间主动查找并删除过期键。
- 执行SAVE命令或者BGSAVE命令所产生的新RDB文件不会包含已经过期的键。
- 执行BGREWRITEAOF命令所产生的重写AOF文件不会包含已经过期的键。
- 当一个过期键被删除之后,服务器会追加一条DEL命令到现有AOF文件的末尾,显式地删除过期键。
- 当主服务器删除一个过期键之后, 它会向所有从服务器发送一条DEL命令,显式地删除过期键。
- 从服务器即使发现过期键也不会自作主张地删除它,而是等待主节点发来DEL命令,这种统一、中心化的过期键删除策略可以保证主从服务器数据的一致性。
- 当Redis命令对数据库进行修改之后,服务器会根据配置向客户端发送数据库通知。
|