hash存储在redis底层存储空间结构有两种,分别是ziplist和hashtable,这俩的先后顺序是先创建ziplist,当ziplist中的某个value大于设置的阈值或者整个ziplist的长度大于某个阈值,则ziplist会转换成hashtable,
ziplist数据结构图
采用的就是数组的方式
hashtable数据结构图
采用的是数组加链表的方式
这样做的原因
如果你学过java,那就应该知道hashmap在JDK1.8及之后时,使用的是数组+链表+红黑树
的数据结构,它转换的条件:
- 当阈值是默认阈值0.75,链表的深度大于等于8,数组容量大于等于64时,扩容的时候会把链表转成红黑树,时间复杂度从O(n)变成O(logN)
- 当红黑树的节点深度小于等于6时,红黑树会转为链表结构。
hashmap这样做的原因:
- put和remove过程中,红黑树要通过左旋,右旋、变色这些操作来保持平衡,另外构造红黑树要比构造链表复杂,在链表的节点不多的时候,从整体的性能看来, 数组+链表+红黑树的结构可能不一定比数组+链表的结构性能高。就好比杀鸡焉用牛刀的意思
- HashMap频繁的扩容,会造成底部红黑树不断的进行拆分和重组,这是非常耗时的。因此,也就是链表长度比较长的时候转变成红黑树才会显著提高效率。
从java的hashMap可以侧方面类比出redis为什么这样做的原因
参考:hashmap为什么用红黑树_10个HashMap问题搞定面试官
Redis5设计与源码分析 (第12章 散列表相关命令的实现)