Redis这个低调而细微的设计,却隐含着优秀的架构设计思想

今天我们来学习下Redis中的字典。在此之前,我们已经分享了非常非常多的关于Redis的知识,可以说,Redis里面有非常多的优秀架构设计,可以讲好几本天。



字典,相信大家已经都不陌生,在之前我们介绍Redis基础数据结构的时候,已经介绍了Redis的字典。Redis的字典,类似于Java中的HashMap,采用的是开散列的实现方式。什么是开散列呢?首先我们是对key进行哈希,如果哈希的值相同的话,我们就使用链表进行表示。(所以,我们使用JAVA语言的时候,如果Key是一个类,要实现Hash与Equeals方法)



如果哈希函数没有设计好,那么可能会有很多个Key的哈希值相同,我们称之为哈希碰撞,如果被黑客发现,可能会被设计出一堆Key相同的值拖慢系统效率,我们称之为哈希攻击

随着key数量的增多,同一个键值上面的元素会越来越多,由于在同一个键值上面是通过链表存储,所以开散列的性能会越来越低,这个时候,需要扩容,我们称之为REHASH,一般会是原来哈希表的两倍。



上图中,原本为1的键值上面有3个元素,经过Rehash后,最多只有2个元素。

Redis的字典有两个开散列,正常情况下,只有一个生效。但在进行Rehash的时候,两个开散列都会同时生效。为什么会同时生效呢?这正是Redis的精髓设计,渐进式Rehash。因为在Rehash过程中,所有的key都要进行迁移,所以需要占用大量的系统资源,Redis服务又是单线程的,在3,5个key的时候Rehash还没有多大的开销,如果是几十万几百万个key呢?步子迈大了,就容易扯淡了。

什么是渐进式Rehash呢?顾名思义,即使慢慢地进行重新哈希操作,在旧的哈希表上,会维护一个下标index表示前index个键值已经被迁移到新的哈希表里面,每次字典进行增删改查操作时,如果判断字典正在进行重新哈希的动作,就会把index坐标上面的迁移到新的哈希表里面,然后把index增加1,最后才进行具体的命令执行。

那么执行一个index下标需要花多少时间呢?在哈希表中,理想情况下时一个哈希对应一个键值,所以理论上每次只需要迁移一个元素即可。

在迁移过程中,查询操作都会优先在新表进行查询,如果查询不到再去旧表进行查询。每次插入数据的时候,也是优先插入新表。就这样,如果有1024个键值,那么在1024次操作后,字典就会迁移到大小为2048的新表,同时新表覆盖旧表,等待下一次重新哈希。当然你可能会问,如果期间只操作了200次呢?Redis是有维护定时任务,即便客户端不再访问这个哈希表,也会定时完成重新哈希。



Redis的这种渐进式的设计,是我们架构中常用的一种设计。特别是在多用户,高并发的场景下,我们不可能一瞬间完成各种状态的更新,可以借鉴Redis的设计思路,逐步覆盖,最终保证最后状态的成功!好了,有关Redis字典我们就介绍到这里。欢迎大家关注我,近期还准备了一些AI相关的知识,整理后会和大家继续分享。大家的支持是我继续唠嗑的动力。同名公众号(沙茶敏碎碎念)

(此处已添加圈子卡片,请到今日头条客户端查看)
发表评论
留言与评论(共有 0 条评论)
   
验证码:

相关文章

推荐文章

'); })();