《redis》3-redis的数据结构

redis的访问速度为什么那么快,主要是redis使用了hash表来存储索引,索引的key是存储key-value的key,value是指针,指向了真正的key-value实体。hash表的主要特性就是根据key的hash值找到hash表的下标,然后访问下标指向的hash桶,而桶一般是个链表,保存的是hash之后相同下标的数据。

hash表有个缺点是,随着数据的增大或者是因为数据特性,造成hash冲突,在相同的hash桶后面又一个长长的数据链表。保存的是hash冲突的key-value数据的实体。我们知道在遍历链表的时候,查询数据的复杂度是O(n)。

比起hash表的O(1),速度的降低是redis不能接受的,所以,redis在冲突到达一定的比例时,会rehash。重新申请一个打得hash表,把原始hash表的数据经过重新put操作放置到新的hash表,然后回收老得hash表的数据。

一般步骤如下:

  1. 基于原始hash表A,新申请一个hash表B,是原始A的两倍大。
  2. 暂停服务,遍历A的数据,存储到Hash表B中,
  3. 使用B表提供服务,回收A表

这个过程很像jvm内存回收的复制算法,在GC的时候,也会产生stop the world 的停顿。这个时候不能提供服务。mysql中也有这样的场景,就是在刷脏页的时候,会暂停服务,把内存的数据刷新到磁盘中。针对这个暂停的过程。mysql有online模式,redis也有优化模式,

渐进式rehash

统一rehash需要暂停服务,rehash可以支持业务一边操作,一边进行rehash。

比如,

  1. hashtable A中的3号桶中的列表有 node1~node6 6个entity,5号桶有node27~node40几个entity。
  2. 当我们处理第一个外部请求时,例如put entity,entity是 node102,hash命中5号桶,则copy hashtable A中的5号桶中对应的链表中的node27~node40几个元素到hashtable B中,在B上执行put node102操作
  3. 处理第二个外部请求时,node509,命中3号桶的数据,copy hashtable A的3号桶的元素到 hashtable B中,在B中执行put node509
  4. 直到所有的A中数据都为空,收回A的空间。

存储实体entity的value中的数据结构

  1. 简单动态字符串
  2. 整数数组
  3. 双向链表
  4. hash表
  5. 压缩列表
  6. 跳表

其中,1是String,指的最基本的数据类型

2整数数组,3-双向链表,4-hash表,5-压缩列表,6-跳表这几个数据可以存储多个内嵌的数据,我们简称为集合类型

扫描二维码关注公众号,回复: 11938072 查看本文章

比如 我们用redis存储黑名单,key=black_list,value = ['zhangsan','lisi','wangwu']。这个entity的value就是一个链表。代表的是一个集合。

数组常见,双向链表常见,压缩列表不常见,跳表不常见

  • 压缩列表:平常的列表只存储基本信息,比如length,和['zhangsan','lisi','wangwu']两个部分,压缩链表要多存储四个节点。分别是:
  1. zlbytes:链表长度
  2. zltail:链表尾节点
  3. zllen:链表长度
  4. zlend;链表结束
demo:[zlbytes][zltail][zllen][zhangsan][lisi][wangwu][zlend]

这样的话,我们在访问列表头和列表尾都可以做到O(1)

  • 跳表

跳表也很神奇,感觉像是简约的B树

原始列表
2,9,14,56,98,143,653,876,1005,4873,9772,19375,20834

如果我们查找9772需要遍历列表,访问次数为11。我们可以使用索引,新建一个多余的列表,没两个元素选一个

原始列表
2,9,14,56,98,143,653,876,1005,4873,9772,19375,20834
索引列表-A
9,56,143,876,4873,19375

这个时候,我们优先访问索引列表A,访问到876,然后根据4873指向到原始列表的位置,向后遍历,查询到9772,访问次数6,

在索引列表A的基础上还可以再抽象一层跳表。这就是跳表带来的好处。

综合起来,redis提供了多种数据类型,为了提高访问速度做了不少思考

上面的两个彩图来源是蒋德钧老师在极客时间课程里面的,大家可以访问原始地址

https://time.geekbang.org/column/article/268253

猜你喜欢

转载自blog.csdn.net/David_lou/article/details/109000427