一致性hash之对象与缓存的映射

本文介绍了一致性哈希算法的原理及应用。通过将对象和缓存服务器映射到环形hash值空间,即使缓存服务器数量变化,也能保持大部分缓存数据的有效性。文章详细解释了算法背后的逻辑,并通过实例说明了其优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景

当有多台缓存机器,当把对象存储到这些缓存机器上时,必须考虑映射算法,以便保证当缓存服务器的数量有增减的时候,尽量保证请求的数据能够在缓存中找到。

映射算法 一

假设有一个对象objA需要存储到两台缓存服务器中,那么我们可以为objA分配一个key,例如叫objA-key,然后使用下面算法

hash(objA-key)%cacheServerCount

这里的cacheServerCount是指缓存服务器的数量,在这里它等于2。如果是使用java的朋友,想要得到对象的hash值,可以如下调用:

objA-key.hashCode();

这样可以得到一个32位的整形数字,假设这里得到的hash值是1。至于缓存服务器,可以使用一个对象数组来表达:

Object [] cacheArray = new Object[cacheServerCount];

cacheServerCount 表示缓存服务器的数量。

这样通过下面的方式,就可以建立objA和缓存服务器的映射了。

cacheArray[1] = objA;

如果缓存服务器的数量一直没变化,那么上面的算法是可以稳定的工作的。但是一旦缓存服务器的数量增加了或者减少了,那么使用objA-key去缓存服务器中查找时,是找不到objA的。原因见下文。

假设增加了一台缓存服务器,映射算法变成:

hash(objA-key)%(cacheServerCount + 1);

这个时候得到的objA-key的hash值就不是之前的1了,假设是2,根据2去cacheArray中查找,肯定找不到objA这个对象的。这样就导致了大量的key无法找到对应的缓存数据。必须找到另一种算法来解决这个问题。

一致性hash算法

当缓存服务器增加或者减少时,如何尽量让之前的缓存数据按照之前的key仍然可以找到呢?也就是之前的key和value的映射关系尽可能不变。

环形hash值空间

hash算法算出来的值是一个32位的整形数字,它可以表示0~2^32-1的数字空间,我们可以把这个数字空间用圆形数值空间来表示。
这里写图片描述

如果把缓存服务器的ip作为key,那么算出的hash值也是落在这个圆形数值空间里面的。这其实就是一致性hash的基本思想,把要存储的对象和缓存服务器都映射到同一个数值空间

在这里借用网络上的一些图片作为说明。
这里写图片描述

上图中,有四个对象Object1,Object2,Object3,Object4,给它们分配的key分别是key1,key2,key3,key4,需要存储到Cache A,Cache B和Cache C上,缓存服务器ip地址对应分别是Key A,Key B,Key C。

key1.hashCode();
key2.hashCode();
key3.hashCode();
key4.hashCode();

key A.hashCode();
key B.hashCode();
key C.hashCode();

这样的话缓存服务器ip和需要存储的对象就都映射在一个圆环数值空间里了。
现在的问题是,Object1,Object2,Object3,Object4 分别要存在哪个缓存服务器呢?

在这个环形空间中,如果沿着顺时针方向从对象的 key 值出发,直到遇见一个 cache ,那么就将该对象存储在这个 cache

那么根据上面的方法,对象 object1 将被存储到 cache A 上; object2 和 object3 对应到 cache C ; object4 对应到 cache B;

假设我们增加了一台缓存Cache D,并且它的key的hash值落在了key3和key2之间,那么受到影响的只有Object2。

本文引用参考的文章:

http://xiexiejiao.cn/java/memcached-consistent-hashing.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值