在大规模的缓存应用中,应运而生了分布式缓存系统。key-value如何均匀的分散到集群中?最常规的方式莫过于hash取模的方式。好比集群中可用机器适量为N,那么key值为K的的数据请求很简单的应该路由到hash(K) mod N对应的机器。可是在一些高速发展的web系统中,这样的解决方案仍有些缺陷。随着系统访问压力的增加,缓存系统不得不经过增长机器节点的方式提升集群的相应速度和数据承载量。增长机器意味着按照hash取模的方式,在增长机器节点的这一时刻,大量的缓存命不中,缓存数据须要从新创建,甚至是进行总体的缓存数据迁移,瞬间会给DB带来极高的系统负载,设置致使DB服务器宕机。node
若是不是缓存数据,而是持久化的数据,那么当扩容的时候,绝大部分数据都要迁移(取模的基数N变化了),这也是不能忍受的。web
一致性哈希平衡负载算法
引入一致性哈希,解决以上增减机器致使负载瞬间总体增大问题缓存
经过在整数范围内负责各区域的方式,节点负责区域的负载不会随着增减节点发生大规模的迁移服务器
可是最简单的一致性哈希,在增减物理机的时候,彷佛要增长一倍节点或减去一半节点才能保证各个节点的负载均衡负载均衡
虚拟节点对一致性哈希的改进分布式
对于一致性哈希的负载分布不平均问题,因此提出:虚拟节点对一致性哈希的改进ide
4个物理节点能够变成不少个虚拟节点,每一个虚拟节点支持连续的哈希环上的一段。而这时若是加入一个物理节点,就会相应加入不少虚拟节点,这些新的虚拟节点是相对均匀地插入到整个哈希环上,这样,就能够很好的分担现有物理节点的压力了;若是减小一个物理节点,对应的不少虚拟节点就会失效,这样,就会有不少剩余的虚拟节点来承担以前虚拟节点的工做,可是对于物理节点来讲,增长的负载相对是均衡的。函数
因此能够经过一个物理节点对应很是多的虚拟节点,而且同一个物理节点的虚拟节点尽可能均匀分布的方式来解决增长或减小节点时负载不均衡的问题。blog
至于一个物理节点对应多少的虚拟节点才能达到比较好的均衡效果,有一个图
x轴表示的是须要为每台物理服务器扩展的虚拟节点倍数(scale),y轴是实际物理服务器数,能够看出,当物理服务器的数量很小时,须要更大的虚拟节点,反之则须要更少的节点,从图上能够看出,在物理服务器有10台时,差很少须要为每台服务器增长100~200个虚拟节点才能达到真正的负载均衡。
映射表与规则自定义计算方式
映射表示根据分库分表字段的值的查表法来肯定数据源的方法,通常用于对热点数据的特殊处理,或者在一些场景下对不彻底符合规律的规则进行补充。
能够经过自定义函数实现来计算最终的分库,举例来讲,假设根据id取模分红了4个库,可是对于一些热点id,咱们但愿将其独立到另外的库,那么经过相似下面的表达式能够完成:
if (id in hotset) {return nodes;}return hash(id);