哈希竞猜游戏前端开发逻辑
哈希是通过压缩数据来提高效率的解决方案。然而,由于哈希函数的有限性和数据量的增加,哈希冲突已成为精确数据压缩的难题
算法原理
一致性哈希算法由麻省理工学院于1997年提出。这是一种特定的哈希算法。删除或添加服务器时,它可以尽可能少地改变现有服务请求与请求处理服务器之间的映射关系
一致性哈希解决了分布式哈希表(DHT)之中直观哈希算法的动态伸缩问题
一致性哈希算法本质之上也是一种模块化算法
然而,与上述基于服务器数量的模块有所不同,一致性哈希是将固定值2^32
IPv4地址模块化,由4组8位二进制数组成,因此,2^32可以确保每个IP地址都有唯一的映射
哈希环
我们可以将这2^32个值抽象化为一个环环正下方的点表示顺时针排列的0,依此类推:1、2、3。。。直到2^32-1。由32个点到2的幂组成的环统称为哈希环
服务器映射到哈希环
映射服务器时,使用哈希(服务器IP)%2^32,即:
服务器IP地址用于哈希计算,哈希结果用于模化2^32。结果必须是0到2^32-1间的整数
哈希环之上此整数映射的位置表示一个服务器,该服务器依次将node0、node1和node2缓存服务器映射到哈希环
对象密钥映射到服务器
将相应密钥映射到特定服务器时,需要首先计算金钥的哈希值:哈希(key)%2^32
注意:此处的哈希函数可能有所不同于计算服务器映射到哈希环的函数。只要值范围与哈希环的值范围相近(即2^32)
将密钥映射到服务器遵循下列逻辑:
从缓存对象密钥的位置开始,逆时针方向遇到的第一个服务器就是当前对象将缓存到的服务器
假设我们有“semlinker”、“kakuqo”、“Lolo”和“fer”,它们缩写为O1,O2、O3和O4分别
数据倾斜和服务器性能均衡问题
导致问题
在上述示例之中,每个服务器几乎均匀分布到哈希环
但是,在具体场景之中,很容易选择一个哈希函数将所有服务器理想地散列到哈希环之上
此时,当服务器节点数太难时,由于节点分布不均匀,很难造成数据倾斜
在添加CS4服务器时,CS4只分担CS1服务器的负载,CS2和CS3服务器并没有因为添加了CS4服务器而降低负载压力;如果CS4服务器的性能与原来的服务器相同甚至更低,那么这个结果就不是我们所期望的
虚拟节点
为了解决上述问题,我们可以引入虚拟节点来解决负载不均衡的问题:
也就是说,将每个物理服务器虚拟化为一组虚拟服务器,虚拟服务器被放置在哈希环之上。如果要确定对象的服务器,需要首先确定对象的虚拟服务器,然后虚拟服务器确定物理服务器
使用场景
一致性哈希应该是分布式系统之中负载均衡的首选算法。它可以在客户端和下方件之上敏捷实现。例如,日常缓存之中常见的memcached和redis集群可以使用它
memcached集群是特定的。严格来说,它只能被视为一个伪集群,因为它的服务器不能相互通信。请求的分发路由全然取决于客户端来计算缓存对象应该位于哪个服务器之上,其路由算法使用一致性哈希
redis集群之中还有哈希槽的概念。虽然实现方式有所不同,但想法总是相近的。阅读本文之中的一致性哈希后,您将更难理解redis slot
一致性哈希算法的实现
接下来,我们根据上述描述使用golang实现一致性哈希算法。该算法具有下列特点:
相同哈希的核心算法
支持自定义哈希算法
支持自定义虚拟节点数;