华企号 软件设计 Redis数据结构(一):对外数据类型和底层数据结构

Redis数据结构(一):对外数据类型和底层数据结构

Redis数据结构系列:

Redis数据结构(一):对外数据类型和底层数据结构;

Redis数据结构(二):简单动态字符串

Redis数据结构(三):双向链表和压缩链表

 1.结构对应关系

redis的基本数据类型:String(字符串)、List(列表)、 Hash(哈希)、Set(集合)和 Sorted Set(有序集合),底层数据结构一共有 6 种,分别是简单动态字符串、双向链表、压缩列表、哈希表、跳表和整数数组。其对应关系如下图所示:

Redis数据结构(一):对外数据类型和底层数据结构插图

   2.全局字典(全局hash表)

我们总是可以通过一个key去关联string,list,set等等,为什么会有这么多丰富的类型呢?从宏观角度分析如下:

字典是redis服务器中出现最频繁的复合型数据结构,除了hash结构的数据会用到字典外,整个redis数据库的所有key和value也组成了一个全局字典,还有待过期时间的key集合也是一个字典。zset集合中存储value和score值的映射关系也是字典结构,伪代码如下:

复制代码
struct RedisDb {
    dict* dict;            //全局字典
    dict* expires;        //过期字典
    ...
}
struct zset {
    dict *dict;            //存放value和score的映射关系
    zskiplist *zsl;
}
复制代码

 

redis中全局字典表的结构与java中的HashMap结构类似(redis叫做hashtable),但是没有用到红黑树结构,如图所示:

Redis数据结构(一):对外数据类型和底层数据结构插图2

但凡碰见hash表的,就一定会有一个碰撞问题,并且碰撞问题是不能避免的,那么redis采用的呢就是向后探测的方法,也就是说,如果两个key通过hash算法散列到数组里面的时候刚好是同一个位置,那么entry2就会通过next指针挂在entry1之后(类比hashmap中的单项链表)。

那么链式hash的弊端都知道的,就像单链表一样,一个一个往后探测是比较费时间的。redis中也有自己的rehash过程,就是二次散列,redis默认使用两个全局hash表,在源码中是可以看到的。dictht ht[2];初始条件之下是使用hash表1的,随着插入的数据越来越多,在到达一定的条件之下,他会将hash表1中的内容再次映射进hash表2中,将原来的比较臃肿的表再舒展开。很明显rehash的过程就是一次再散列扩容的过程(类似于java中hashMap的长度扩容,不同的是java会有链表变红黑树的逻辑)。
众所周知,redis是单线程的,如果说触发了rehash这个过程,用户总不能一直阻塞等他reash完毕吧,于是redis出现了这样的技术:incremental rehashing,他们都叫渐进式rehash。简单来描述下:

redis正常处理请求,处理第一次请求,就顺便把hash表1第一个索引位置上的entry进行散列,映射到hash表2中,再处理一个请求,就把hash表1第二个索引位置上的entry进行散列

 2.过期字典

除了全局字典之外,redis还维护了一套过期字典,value存放的是对应key的过期时间,其结构与全局字典表类似

redis提供了以下三种删除策略,可以根据实际业务场景选择合适的删除策略

  •   定时删除 对内存友好,对CPU不友好

定时是为每一个key都设置一个定时器,所以对cpu的负荷相当大

  •   惰性删除 对内存不友好,对CPU友好

放任键过期不管, 但是每次从键空间中获取键时, 都检查取得的键是否过期, 如果过期的话, 就删除该键;如果没有过期,      就返回该键

  •   定期删除 折中方案

定期就对数据库进行检查, 删除里面的过期键,不像定时那样为每一个key都设置定时器,也不像惰性删除那样等很久才删掉

 总结:

  •   redis主要由 dict和 expires两个字典构成, 其中 dict字典负责保存键值对,而 expires字典则负责保存键的过期时间;
  •   redis的键总是一个string对象, 而值则可以是任意一种Redis对象类型;
  •   redis会采用rehash来解决扩容问题,为防止rehash过程中造成阻塞,采用渐进式rehash分多次迁移数据;
  •   Redis提供了三种过期键删除策略,实际工作中建议采取惰性删除+定期删除的组合方式进行配置。

后面章节我们针对每一种底层数据类型进行总结,并不定时更新本篇文章,敬请期待……

如发现文章中有错误的知识点,欢迎在评论区指正。

上一篇
下一篇

发表回复

联系我们

联系我们

028-84868647

在线咨询: QQ交谈

邮箱: tech@68v8.com

工作时间:周一至周五,9:00-17:30,节假日休息

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部