Redis底层原理-Key存储结构
Redis的基本数据结构,总体来说都是按照key-value的形式,熟悉后端的朋友可以感受到其实他的使⽤就像JAVA中的HashMap<K,V>和C#中的Dictionary<K,V>,只不过区别在于Redis只有⼀层,⽽事实上,Redis的Key的存储也就是按照这样的结构来的,⼀个HashMap。
作为⼀个HashMap,他的总体索引结构是⼀个数组,⽽每个索引下标对应的则是⼀个链表,如下图所⽰,⼀个hashmap就是⼀个【数组+链表】组合的⼆位数据结构。
当需要去查询⼀个key时,⾸先利⽤预设的哈希计算出key的数组位置,然后到数组的位置,再去链表中遍历中寻到相关的节点进⾏返回,它的节点存储结构⼤致如下:
从上述的数据结构中可以看出,在使⽤hashmap的时候,需要数组⼤⼩和链表的长度平衡,理论上来说,应当做到尽量少的哈希碰撞(hash每个下标对应的链表长度⼩),当碰撞较多到⼀定的阈值的时候,我们应当对HashMap进⾏扩容,扩容的原理时通过增⼤hash产⽣的数组长度来达到平衡存储和哈希碰撞的⽬的,最理想则是没有哈希碰撞,具体前后变化如下所⽰:
在JAVA的策略中,hashmap扩容时,会将hashmap⼀次性转换为新的数组结构,但是当我们在使⽤⼀个较⼤的hashmap时,这样的操作会让线程处于卡顿状态,这种问题可以通过在初始化hashmap的时候redis五种数据结构
传⼊⼀个预计使⽤的长度来减少hashmap扩容的可能性,以【空间】换【时间】,但是Redis是⼀个难以像在使⽤编程代码时能够预计到初始化容量的“动态HashMap”,所以Redis的扩容在数据量急速增⼤的时候会⾃动出现,对此Redis给出的策略时“渐进式rehash”,这种⽅法,会同时保留旧数组和新数组,在后台任务和新的hash指令中,⽆感应的去将旧的元素迁移到新的数组中,等到迁移完毕旧的数组则不存在了。但是这种⽅式意味着会存在两个数组,所以在我们访问⼀个key的时候,将会同时在旧和新两个数组中进⾏查询。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论