Redis底层数据结构以及持久化部分知识总结

一. 对象的类型与编码
Redis使用对象来表示数据库中的键和值,每次在redis数据库中新创建一个键值对时,我们至少会创建两个对象,分别用作键值对的键和值
Redis中的每个对象都由一个redisObject结构表示,该结构和保存数据有关的三个属性分别是type,encoding,和ptr属性。
Type:包括五种:REDIS_STRING,REDIS_LIST,REDIS_HASH,REDIS_SET,REDIS_ZSET.
Ptr指向对象的底层实现数据结构,而这些数据结构由对象的encoding属性决定。
底层数据结构包括:
Int,long类型的整数;
Embstr,embstr编码的简单动态字符串。
Raw,简单动态字符串,
Ht,字典
Linkedlist,双端链表
Ziplist压缩列表
Intset整数集合
Skiplist跳跃表和字典
1.1字符串对象
字符串对象的编码可以是int,raw,或者embstr,对该对象改变值时会进行相应的编码转换。
如果该对象保存的是整数值,并且这个整数值可以用long类型来表示,就用int来存储。
如果保存的是字符串值,并且这个字符串长度大于32字节,用raw编码的简单动态字符串存储
如果保存的是一个长度小于32字节的字符串,就用embstr编码的方式来保存这个字符串值
可以用long double表示的浮点数也是先转换为embstr或raw编码的字符串再存储的
Embstr和raw比较:
embstr创建字符串所需的内存分配次数和释放内存调用的内存释放函数都为1次,而raw编码的需要两次。
Embstr编码的字符串对象的所有数据都保存在一块连续的内存里面,能更好的利用缓存带来的优势。
Embstr字符串实际上是只读的,因此对它进行修改时,它总会变成raw字符串。
1.2列表对象
编码可以是ziplist或者linkedlist
编码转换:同时满足以下条件:列表对象保存的所有字符串元素的长度都小于64字节,列表对象保存的元素数量小于512个。满足这个条件的使用ziplist编码,否则使用lingkedlist编码。
1.3哈希对象
哈希对象的编码可以是ziplist或者hashtable
使用ziplist时,保存同一个键值对的两个节点总是紧挨在一起,键在前,值在后先添加的在表头方向。
使用hashtable,每个对象都用一个字典键值对来保存
编码转换:同时满足以下条件:列表对象保存的所有字符串元素的长度都小于64字节,列表对象保存的元素数量小于512个。满足这个条件的使用ziplist编码,否则使用hashtable编码。
1.4集合对象set
Set编码可以是intset或者hashtable
Intset作为底层实现,集合所有元素都被保存在整数集合里面
Hashtable作为底层实现,字典的每个键都是一个字符串对象,值全被设置为null。
编码转换:集合保存的所有元素都是整数值,集合保存的元素数量不超过512个使用intset编码,否则使用hashtable编码
1.5有序集合对象
有序集合对象的编码可以是ziplist或者skiplist
使用ziplist,每个集合元素使用两个紧挨在一起的压缩列表节点保存,第一个节点保存成员,第二个保存元素的分值。集合元素按照从表头到表位从小到大的顺序排序。
Skiplist编码对象底层使用一个zset结构,zset结构包含一个字典和一个跳跃表。使用字典可以用O(1)的复杂度查找成员分值,由于字典以无序结构保存元素,进行范围操作时,比如使用ZRANK,ZRANGE等命令时复杂度提升,所有加入跳跃表。两种数据结构通过指针共享相同元素的成员和分值,所以不会有重复元素也不会浪费额外的内存。
编码的转换:元素数量小于128,所有元素成员的长度都小于64字节。使用ziplist编码,否则使用skiplist。
1.6命令多态。DEL,EXPIRE,RENAME,TYPE,OBJECT可以对任何类型的键执行。
1.7内存回收
Redis自己实现了一种引用计数的内存回收机制。这个引用计数属性还带有对象共享的作用。A和B都创建了相同的对象,服务器会让A和B共享对象,让引用计数增加1.
由于判断两个包含字符串值的字符串对象是否相同的时间复杂度太高。Redis只对包含整数值的字符串对象进行共享。
二 单机数据库实现
Redis服务器默认创建16个数据库
SELECT 2 切换为2号数据库。
Redis键值对的键都是字符串对象。
三 RDB持久化
有两个redis可以用于生产RDB文件,一个是SAVE:这个命令会阻塞redis服务器进程,直达RDB文件创建完毕为止。另一个是BGSAVE,这个命令会派生出一个子进程,然后由子进程负责创建RDB文件,服务器进程继续处理命令请求。
载入RDB:redis服务器启动时检测到RDB文件存在,它就会自动载入RDB文件。、
另外:如果服务器开启了AOF持久化功能,那么服务器会优先使用AOF文件来还原数据库状态,只有当AOF治酒后功能处于关闭状态,服务器才会使用RDB文件来还原数据库状态。
在服务器执行BGSAVE命令期间,服务器会拒绝SAVE和BGSAVE命令,防止产生竞争条件。
服务器在载入RDB文件期间,会一直阻塞直到载入完成。
四AOF持久化
与RDB持久化通过保存数据库中的键值对来记录数据库状态不同,AOF持久化是通过保存Redis服务器所执行的写命令来记录数据库状态的。

猜你喜欢

转载自blog.csdn.net/sinat_36748650/article/details/88691551