加入收藏 | 设为首页 | 会员中心 | 我要投稿 云计算网_泰州站长网 (http://www.0523zz.com/)- 视觉智能、AI应用、CDN、行业物联网、智能数字人!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

面试官:你看过Redis数据结构底层实现吗?

发布时间:2019-06-22 04:22:53 所属栏目:MySql教程 来源:奔头哥
导读:副标题#e# 面试中,redis也是很受面试官亲睐的一部分。我向在这里讲的是redis的底层数据结构,而不是你理解的五大数据结构。你有没有想过redis底层是怎样的数据结构呢,他们和我们java中的HashMap、List、等使用的数据结构有什么区别呢。 1. 字符串处理(str

引用https://segmentfault.com/a/1190000016901154中的两个图:

面试官:你看过Redis数据结构底层实现吗?

面试官:你看过Redis数据结构底层实现吗?

6.1 源码

ziplist没有明确定义结构体,这里只作大概的演示。

  1. typedef struct entry {  
  2.      /*前一个元素长度需要空间和前一个元素长度*/  
  3.     unsigned int prevlengh;  
  4.      /*元素内容编码*/  
  5.     unsigned char encoding;  
  6.      /*元素实际内容*/  
  7.     unsigned char *data;  
  8. }zlentry;  
  1. typedef struct ziplist{  
  2.      /*ziplist分配的内存大小*/  
  3.      uint32_t zlbytes;  
  4.      /*达到尾部的偏移量*/  
  5.      uint32_t zltail;  
  6.      /*存储元素实体个数*/  
  7.      uint16_t zllen;  
  8.      /*存储内容实体元素*/  
  9.      unsigned char* entry[];  
  10.      /*尾部标识*/  
  11.      unsigned char zlend;  
  12. }ziplist; 

第一次看可能会特别蒙蔽,你细细的把我这段话看完就一定能懂。

Entry的分析

entry结构体里面有三个重要的字段:

  1.  previous_entry_length: 这个字段记录了ziplist中前一个节点的长度,什么意思?就是说通过该属性可以进行指针运算达到表尾向表头遍历,这个字段还有一个大问题下面会讲。
  2.  encoding:记录了数据类型(int16? string?)和长度。
  3.  data/content: 记录数据。

连锁更新

previous_entry_length字段的分析

上面有说到,previous_entry_length这个字段存放上个节点的长度,那默认长度给分配多少呢?redis是这样分的,如果前节点长度小于254,就分配1字节,大于的话分配5字节,那问题就来了。

如果前一个节点的长度刚开始小于254字节,后来大于254,那不就存放不下了吗? 这就涉及到previous_entry_length的更新,但是改一个肯定不行阿,后面的节点内存信息都需要改。所以就需要重新分配内存,然后连锁更新包括该受影响节点后面的所有节点。

除了增加新节点会引发连锁更新、删除节点也会触发。

7. 快速列表(quicklist)

一个由ziplist组成的双向链表。但是一个quicklist可以有多个quicklist节点,它很像B树的存储方式。是在redis3.2版本中新加的数据结构,用在列表的底层实现。

面试官:你看过Redis数据结构底层实现吗?

结构体源码

表头结构:

  1. typedef struct quicklist { 
  2.     //指向头部(最左边)quicklist节点的指针 
  3.     quicklistNode *head;  
  4.     //指向尾部(最右边)quicklist节点的指针 
  5.     quicklistNode *tail;  
  6.     //ziplist中的entry节点计数器 
  7.     unsigned long count;        /* total count of all entries in all ziplists */  
  8.     //quicklist的quicklistNode节点计数器 
  9.     unsigned int len;           /* number of quicklistNodes */  
  10.     //保存ziplist的大小,配置文件设定,占16bits 
  11.     int fill : 16;              /* fill factor for individual nodes */  
  12.     //保存压缩程度值,配置文件设定,占16bits,0表示不压缩 
  13.     unsigned int compress : 16; /* depth of end nodes not to compress;0=off */ 
  14. } quicklist; 

(编辑:云计算网_泰州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读