需求
工程师常使用服务器集群来设计和实现数据缓存,以下是常见的策略.
1.无论是添加\查询还是删除数据,都先将数据的id通过哈希函数转换成一个哈希值,记为key.
2.如果目前机器有N台,则计算key % N的值,这个值就是该数据所属的机器编号,无论是添加\删除还是查询操作,都只在这台机器上进行.
请分析这种缓存策略可能带来的问题,并提出改进的方案.
解答
需求中描述的缓存策略的潜在问题是如果增加或删除机器(N变化),代价会很高,所有数据都不得不根据id重新一遍哈希值,并将哈希值对新的机器数进行取模操作,然后进行大规模的数据迁移.
为了解决这些问题,下面介绍一致性哈希算法,这是一种很好的数据缓存设计方案.我们假设数据的id通过哈希函数转换成的哈希值范围是2^(32),也就是0 ~ (2^(32))-1的数字空间中.现在我们可以将这些数字头尾相连,想象成一个闭合的环形,那么一个数据id在计算出哈希值之后认为对应到环中的一个位置上,如图1所示
接下来想象有三台机器也处在这样一个环中,这三台机器在环中的位置根据机器id计算出的哈希值来决定.那么一条数据如何确定归属哪台机器呢?首先把该数据的id用哈希函数算出哈希值,并映射到环中相应的位置,然后顺时针找寻离这个位置最近的机器,那台机器就是该数据的归属,如图2所示.
在图2中,data1根据其哈希值为key1,顺时针的第一台机器是machine2,所以data1归属machine2.同理,data2归属machine3,data3和data4