首页 > Redis设计与实现读书笔记(6-10章)
头像
牛客6362853号
发布于 2018-10-30 11:20
+ 关注

Redis设计与实现读书笔记(6-10章)

Redis设计与实现读书笔记(6-10章)


Redis设计与实现读书笔记(6-10章)
第6章:整数集合
    整数集合(intset)是集合键的底层实现之一,当一个集合只包含整数值元素,并且这个集合的元素数量不多时,Redis就会使用整数集合作为集合键的底层实现。
    整数集合(intset)是Redis用于保存整数值的集合抽象数据结构,它可以保存类型为int16_t、int32_t或者int64_t的整数值。其底层实现为数组,这个数组以有序、无重复的方式保存集合元素,在有需要时,程序会根据新添加元素的类型,改变这个数组的类型。
   升级:每当需要将一个新元素添加到整数集合里面,并且新元素的类型比整数集合现有所有元素类型都要长时,整数集合需要先进行升级,然后才能将新元素添加到整数集合里面。
   升级整数集合并添加新元素共分为三步进行:
   1)根据新元素的类型,扩展整数集合底层数组的空间大小,并为新元素分配空间。
   2)将底层数组现有的所有元素都转换成与新元素相同的类型,并将类型转换后的元素放置到正确的位上,而且在放置元素的过程中,需要继续维持底层数组的有序性质不变。
   3)将新元素添加到底层数组里面。
    整数集合的升级操作的好处:1)提升整数集合的灵活性,2)尽可能地节约内存。
   整数集合只支持升级操作,不支持降级操作。
重点回顾
整数集合是集合键的底层实现之一。
整数集合的底层实现为数组,这个数组以有序、无重复的方式保存集合元素,在有需要时,程序会根据新添加元素的类型,改变这个数组的类型。
升级操作为整数集合带来了操作上的灵活性,并且尽可能地节约了内存。
整数集合只支持升级操作,不支持降级操作。
第7章:压缩列表
     压缩列表是列表键和哈希键的底层实现之一。
    1)当一个列表键只包含少量列表项,并且每个列表项要么就是小整数值,要么就是长度比较短的字符串,那么Redis就会使用使用压缩列表来做列表键的底层实现。
    2)当一个哈希键只包含少量键值对,并且每个键值对的键和值要么就是小整数值,要么就是长度比较短的字符串,那么Redis就会使用压缩列表来做哈希键的底层实现。
   压缩列表是Redis为了节约内存而开发的,是由一系列特殊编码的连续内存块组成的顺序型数据结构。一个压缩列表可以包含任意多个节点,每个节点可以保存一个字节数组或者一个整数值。
   添加新节点到压缩列表,或者从压缩列表中删除节点,可能会引发连锁更新操作,但这种操作出现的几率并不高。
重点回顾
压缩列表是一种为节约内存而开发的顺序型数据结构。
压缩列表被用作列表键和哈希键的底层实现之一。
压缩列表可以包含多个节点,每个节点可以保存一个字节数组或者整数值。
添加新节点到压缩列表,或者从压缩列表中删除节点,可能或引发连锁更新操作,但这种操作出现的几率并不高。
第8章:对象
    Redis使用对象来表示数据库中的键和值,每次当我们在Redis的数据库中新创建一个键值对时,我们至少会创建两个对象,一个对象用作键值对的键(键对象),另一个对象用作键值对的值(值对象)。
    对于Redis数据库保存的键值对来说,键总是一个字符串对象,而值则可以是字符串对象、列表对象、哈希对象、集合对象或者有序集合对象中的一种。
   1)字符串对象的编码可以是int、raw或者embstr。int编码的字符串对象和embstr编码的字符串对象在条件满足的情况下,会被转换为raw编码的字符串对象。embstr编码的字符串对象在执行修改命令之后,总会变成一个raw编码的字符串对象。字符串对象是Redis五种类型的对象中唯一一种会被其他四种对象嵌套的对象。
  2) 列表对象的编码可以是ziplist或者linkedlist。ziplist编码的列表对象使用压缩列表作为底层实现,每个压缩列表节点保存了一个列表元素。linkedlist编码的列表对象使用双端链表作为底层实现,每个双端链表节点都保存了一个字符串对象,而每个字符串对象都保存了一个列表元素。当列表对象可以同时满足以下两个条件时,列表对象使用ziplist编码:
          a)列表对象保存的所有字符串元素的长度都小于64字节;
          b)列表对象保存的元素数量小于512个;
     不能满足这两个条件的列表对象需要使用linkedlist编码。
  3)哈希对象的编码可以是ziplist或者hashtable。ziplist编码的哈希对象使用压缩列表作为底层实现,每当有新的键值对要加入到哈希对象时,程序会先将保存了键的压缩列表节点推入到压缩列表表尾,然后再将保存了值的压缩列表节点推入到压缩列表表尾。hashtable编码的哈希对象使用字典作为底层实现,哈希对象中的每个键值对都使用一个字典键值对来保存。字典的每个键都是一个字符串对象,对象中保存了键值对的键;字典的每个值都是一个字符串对象,对象中保存了键值对的值。当哈希对象可以同时满足以下两个条件时,哈希对象使用ziplist编码:
         a)哈希对象保存的所有键值对的键和值的字符串长度都小于64字节;
         b)哈希对象保存的键值对数量小于512个;
  不能满足这两个条件的哈希对象需要使用hashtable编码。
   4)集合对象的编码可以是intset或者hashtable。intset编码的集合对象使用整数集合作为底层实现,集合对象包含的所有元素都被保存在整数集合里面。hashtable编码的集合对象使用字典作为底层实现,字典的每个键都是一个字符串对象,每个字符串对象包含了一个集合元素,而字典的值则全部被设置为NULL。当集合对象可以同时满足一下两个条件时,对象使用intset编码:
        a)集合对象保存的所有元素都是整数值;
        b)集合对象保存的元素数量不超过512个;
    不能满足这两个条件的集合对象需要使用hashtable编码。
   5)有序集合的编码可以是ziplist或者skiplist。ziplist编码的有序集合对象使用压缩列表作为底层实现,每个集合元素使用两个紧挨在一起的压缩列表节点来保存,第一个节点保存元素的成员,而第二个元素则保存元素的分值。压缩列表内的集合元素按分值从小到大进行排序,分值较小的元素被放置在靠近表头的位置,而分值较大的元素则被放置在靠近表尾的位置。skiplist编码的有序集合对象使用zset结构作为底层实现,一个zset结构同时包含一个字典和一个跳跃表。当有序集合对象可以同时满足以下两个条件时,对象使用ziplist编码:
      a)有序集合保存的元素数量小于128个;
      b)有序集合保存的所有元素成员的长度都小于64字节;
  不能满足以上两个条件的有序集合对象将使用skiplist编码。
    服务器在执行某些命令之前,会先检查给定键的类型能否执行特定命令,而检查一个键的类型就是检查键的值对象的类型。
    Redis的对象系统带有引用计数实现的内存回收机制,当一个对象不再被使用时,该对象所占用的内存就会被自动释放。
    Redis会共享值为0到9999的字符串对象。
    对象会记录自己的最后一次被访问的时间,这个时间可以用于计算对象的空转时间。
第9章: 数据库
     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命令对数据库进行修改之后,服务器会根据配置向客户端发送数据库通知。

第10章:RDB持久化
    Redis是一个键值对数据库服务器,服务器中的非空数据库以及它们的键值对被统称为数据库状态。
    Redis提供的RDB持久化功能,可以将Redis在内存中的数据库状态保存到磁盘里面,避免数据意外丢失。RDB持久化既可以手动执行,也可以根据服务器配置选项定期执行,该功能可以将某个时间点上的数据库状态保存到一个RDB文件中,RDB持久化功能所生成的RDB文件是一个经过压缩的二进制文件,通过该文件可以还原成RDB文件时的数据库状态。
    SAVE命令由服务器进程直接执行保存操作,所以该命令会阻塞服务器。BGSAVE命令由子进程执行保存操作,所以该命令不会阻塞服务器。
    服务器状态中会保存所有用save选项设置的保存条件,当任意一个保存条件被满足时,服务器会自动执行BGSAVE命令。
    RDB文件是一个经过压缩的二进制文件,由多个部分组成。
    对于不同类型的键值对,RDB文件会使用不同的方式来保存它们。
重点回顾
RDB文件用于保存和还原Redis服务器所有数据库中的所有键值对数据。
SAVE命令有服务器进程直接执行保存操作,所有命令会阻塞服务器。
BGSAVE令由子进程执行保存操作,所以该命令不会阻塞服务器。
服务器状态中会保存所有用save选项设置的保存条件,当任意一个保存条件被满足时,服务器会自动执行BGSAVE命令。
RDB文件是一个经过压缩的二进制文件,由多个部分组成。
对于不同类型的键值对,RSB文件会使用不同的方式来保存它们。

全部评论

(0) 回帖
加载中...
话题 回帖