10.MC是怎么定位key以及如何淘汰冷key和失效key的

key定位

哈希表
Mc 将数据存储在 Item 中,然后这些 Item 会被 slabclass 的 4 个 LRU 管理。这些 LRU 都是通过双向链表实现数据记录的。双向链表在进行增加、删除、修改位置时都非常高效,但其获取定位 key 的性能非常低下,只能通过链表遍历来实现。因此,Mc 还通过 Hashtable,也就是哈希表,来记录管理这些 Item,通过对 key 进行哈希计算,从而快速定位和读取这些 key/value 所在的 Item,如下图所示。
在这里插入图片描述
哈希表也称散列表,可以通过把 key 映射到哈希表中的一个位置来快速访问记录,定位 key 的时间复杂度只有 O(1)。Mc 的哈希表实际是一个一维指针数组,数组的每个位置称作一个 bucket,即一个桶。性能考虑的需要,Mc 的哈希表的长度设置为 2 的 N 次方。Mc 启动时,默认会构建一个拥有 6.4万 个桶的哈希表,随着新 key 的不断插入,哈希表中的元素超过阀值后,会对哈希表进行扩容,最大可以构建 2 的 32 次方个桶的哈希表,也就是说 Mc 哈希表经过多次扩容后,最多只能有不超过 43亿 个桶。

哈希表设计
对于哈希表设计,有 2 个关键点,一个是哈希算法,一个是哈希冲突解决方案。Mc 使用的哈希算法有 2 种,分别是 Murmur3 Hash 和 Jenkins Hash。Mc 当前版本,默认使用 Murmur3 Hash 算法。不同的 key 通过 Hash 计算,被定位到了相同的桶,这就是哈希冲突。Mc 是通过对每个桶启用一个单向链表,来解决哈希冲突问题的。

定位 key
Memcached 定位 key 时,首先根据 key 采用 Murmur3 或者 Jenkins 算法进行哈希计算,得到一个 32 位的无符号整型输出,存储到变量 hv 中。因为哈希表一般没有 2^32 那么大,所以需要将 key 的哈希值映射到哈希表的范围内。Mc 采用最简单的取模算法作为映射函数,即采用 hv%hashsize 进行计算。由于普通的取模运算比较耗时,所以 Mc 将哈希表的长度设置为 2 的 n 次方,采用位运算进行优化,即采用 hv&hashmask 来计算。hashmask 即 2 的 n 次方 减 1。

定位到 key 所在的桶的位置后,如果是插入一个新数据,则将数据 Item 采用头部插入法插入桶的单向链表中。如果是查找,则轮询对应哈希桶中的那个单向链表,依次比对 key 字符串,key 相同则找到数据 Item。
在这里插入图片描述
如果哈希表桶中元素太多

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值