Redis 设计与实现---第三章:字典

Redis数据库构建k-v键值对时(任何类型),就是通过字典实现,也基本的hash键底层实现之一(当hash类型中键值比较多,或者键值元素比较长时)

但是键值多少以及长短的具体分界线是多少呢??

字典的实现:

Redis的字典使用hash表作为底层实现,一个hash表里面包含多个hash表节点,而每个hash表节点剧保存了字典中的一个键值对

     

链地址法解决冲突,就是当两个key的索引相同时,把多个hash表节点串起来,通过next指针遍历直到找到目标key

 

Hash算法:

    添加一个值到hash键中:

           1.    redis使用murmurhash2算法,计算出索引值

           2. 正常情况直接将hash表节点添加到ht[0] hash表数组的对应索引上,如果正在执行rehash操作,则直接添加到ht[1]hash表里

Hash表收缩与扩展的条件:

      1. 当前未执行BGSAVE 或者BFGREWRITEAOF命令,并且负载因子大于1

      2. 当前正在执行BGSAVE 或者BFGREWRITEAOF命令,并且负载因子大于5

           为什么在执行BGSAVE或BGREWRITEAOF时负载因子大于5才扩展:因为执行这两个命令需要fork子进程,采用写时复制(写时复制:多个进程调用相同资源使用同一个指针,除非有新的更改时才会复制副本,就是共用时尽量别乱动)技术,优化子进程使用效率,尽量减少在这个时候扩展。

      3. 当hash表的负载因子小于0.1时,执行收缩

    负载因子=已保存节点数量/哈希表大小     (就是利用率

 

渐进式rehash:

          当键值很少时,rehash可以瞬间完成,但是当键值很多时(几百万个),一次完成就会影响服务器性能,导致一段时间内停止对外访问。

        redis采用渐进式,就是一点一点转移,ht[0] 和ht[1]共存一段时间,将rehasidx改为0,表示rehash正式开始,当客户端有更新,查找,删除等操作时,分别作用ht[0]和ht[1]上,先找ht[0]如果没有则到ht[1]中查找进行操作,但是新增的数据直接添加到ht[1]上,保证ht[0]只减不增。执行完客户端的操作,顺便搞几个rehash动作,就是这样捎带着把活干完的。最终将rehashidx改为-1,表示rehash已完成,删除ht[0],将ht[1]改为ht[0]

 

总结一下子:

    1. redis数据库和hash键都使用了字典

     2. 每个字典包含两个hash表一个平时用,一个rehash时用

     3. redis使用murmurhash2算法来计算键的hash值

      4.redishash表使用链地址法解决冲突

     5. 采用渐进式rehash

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值