加入收藏 | 设为首页 | 会员中心 | 我要投稿 河北网 (https://www.hebeiwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程 > 正文

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

发布时间:2019-06-23 09:36:26 所属栏目:编程 来源:奔头哥
导读:口试中,redis也是很受口试官亲睐的一部门。我向在这里讲的是redis的底层数据布局,而不是你领略的五大数据布局。你有没有想过redis底层是奈何的数据布局呢,他们和我们java中的HashMap、List、等行使的数据布局有什么区别呢。 1. 字符串处理赏罚(string) 我们

跳跃表:

  1. typedef struct zskiplist {  
  2.     // 表头节点和表尾节点  
  3.     struct zskiplistNode *header, *tail;  
  4.     // 表中节点的数目  
  5.     unsigned long length;  
  6.     // 表中层数最大的节点的层数  
  7.     int level;  
  8. } zskiplist; 

它有几个观念:

4.2.1 层(level[])

层,也就是level[]字段,层的数目越多,会见节点速率越快。(由于它相等于是索引,层数越多,它索引就越细,就能很快找到索引值)

4.2.2 提高指针(forward)

层中有一个forward字段,用于从表头向表尾偏向会见。

4.2.3 跨度(span)

用于记录两个节点之间的间隔

4.2.4 退却指针(backward)

用于从表尾向表头偏向会见。

案例

  1. level0    1---------->5  
  2. level1    1---->3---->5  
  3. level2    1->2->3->4->5->6->7->8 

好比我要找键为6的元素,在level0中直接定位到5,然后再今后走一个元素就找到了。

5. 整数荟萃(intset)

Reids对整数存储专门作了优化,intset就是redis用于生涯整数值的荟萃数据布局。当一个团结中只包括整数元素,redis就会用这个来存储。

  1. 127.0.0.1:6379[2]> sadd number 1 2 3 4 5 6  
  2. (integer) 6  
  3. 127.0.0.1:6379[2]> object encoding number  
  4. "intset" 

源码

intset数据布局:

  1. typedef struct intset {  
  2.     // 编码方法  
  3.     uint32_t encoding;  
  4.     // 荟萃包括的元素数目  
  5.     uint32_t length;  
  6.     // 生涯元素的数组  
  7.     int8_t contents[];  
  8. } intset; 

你必定很好奇编码方法(encoding)字段是干嘛用的呢?

  •  假如 encoding 属性的值为 INTSET_ENC_INT16 , 那么 contents 就是一个 int16_t 范例的数组, 数组里的每个项都是一个 int16_t 范例的整数值 (最小值为 -32,768 ,最大值为 32,767 )。
  •  假如 encoding 属性的值为 INTSET_ENC_INT32 , 那么 contents 就是一个 int32_t 范例的数组, 数组里的每个项都是一个 int32_t 范例的整数值 (最小值为 -2,147,483,648 ,最大值为 2,147,483,647 )。
  •  假如 encoding 属性的值为 INTSET_ENC_INT64 , 那么 contents 就是一个 int64_t 范例的数组, 数组里的每个项都是一个 int64_t 范例的整数值 (最小值为 -9,223,372,036,854,775,808 ,最大值为 9,223,372,036,854,775,807 )。

说白了就是按照contents字段来判定用哪个int范例更好,也就是对int存储作了优化。

说到优化,那redis怎样作的呢?就涉及到了进级。

5.1 encoding进级

假如我们有个Int16范例的整数荟萃,此刻要将65535(int32)加进这个荟萃,int16是存储不下的,以是就要对整数荟萃举办进级。

它是怎么进级的呢(进程)?

若是此刻有2个int16的元素:1和2,新插手1个int32位的元素65535。

  1.  内存重分派,新插手后应该是3个元素,以是分派3*32-1=95位。
  2.  选择最大的数65535, 放到(95-32+1, 95)位这个内存段中,然后2放到(95-32-32+1+1, 95-32)位...依次类推。

进级的甜头是什么呢?

  1.  进步了整数荟萃的机动性。
  2.  尽也许节省内存(能用小的就不消大的)。

5.2 不支持降级

凭证上面的例子,假如我把65535又删掉,encoding会不会又回到Int16呢,谜底是不会的。官方没有给出来由,我认为应该是低落机能耗损吧,事实调解一次是O(N)的时刻伟大度。

6. 压缩列表(ziplist)

ziplist是redis为了节省内存而开拓的次序型数据布局。它被用在列表键和哈希键中。一样平常用于小数据存储。

(编辑:河北网)

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

热点阅读