题目
工程师常使用服务集群来设计和实现数据缓存,以下是常见的策略。
- 无论是添加、查询还是删除数据,都先将数据的id通过哈希函数转换成一个哈希值,记为key。
- 如果目前机器有N台,则计算key%N的值,这个值就是该数据所属的机器编号,无论是添加、查询还是删除操作,都只在这台机器上进行。
分析这种缓存策略可能带来的问题,并提出解决方案。
解答
首先说这种方法的问题,如果N变化,代价会很高,所有的数据不得不根据id重写计算一遍哈希值,并将哈希值对新的机器数进行取模操作,然后进行大规模的数据迁移。
为了解决这些问题,就要用到一致性哈希算法:
- 假设数据的id通过哈希函数转换成的哈希值范围是232,也就是0~(232)-1的数字空间中。现在我们可以将这些数字头尾相连,想象成一个闭合的环形,那么一个数据id在计算出哈希值之后认为对应到环中的一个位置上。
- 接下来想象有三台机器也处在这样一个换种,这三台机器在环中的位置根据机器id计算出的哈希值来决定。然后是将数据归属到机器上,,根据数据的id计算出哈希值,并映射到环中相应的位置,然后顺时针找寻离这个位置最近的机器,那台机器就是数据的归属。
- 所以在环中添加一台机器,只需要把新机器与逆时针的寻到的那台机器之间的数据迁移到新机器即可。
ps:这个过程可能出现数据倾斜问题,可以通过引入虚拟节点机制来解决