一致性哈希原理

经典的服务器

可以简单分为逻辑层和数据层

  • 逻辑端:逻辑端的服务器,不需要维持数据,而是需要向数据端服务器要数据,添加数据

  • 数据端:

    1. 数据端的服务器可以是一台整个大机器,如mysql,Postgre所有数据在一块,那么数据来了之后直接通过逻辑端的机器存入数据端的机器就OK,缺点就是数据量不大。

    2. 数据端的服务器可以是分布式的,比如有0号、1号、2号机器。每号机器都维持自己的专属数据,存的数据都是不同的。如果要存入一个数据,可以算出这个数据的哈希值在%m就知道要存进那一台的机器上。这样就确定了这个数据的底层数据归属。如果要求负载平衡就要:高频key、中频key、低频key,都会平均分配在这三台机器上。注意:什么样子的key适合这样的划分以此达到负载平衡:种类比较多的key,比如人名、身份证号。不适合的key:国家名,男女。因为中美绝对是最多的,这样导致其中的一些机器绝对满,另外一些基本没啥东西。

    3. 需要注意的问题(2.中的):如果在数据端增加机器和减少机器,那么就得对所有数据进行重新的%(新m)计算,减少机器的时候也是同理,所以增加机器和减少机器所带来的数据的迁移量是全量的
      /
      image.png
      //
      image.png
      //

相关思考

怎样可以避免去模(%),减少数据的全量迁移呢?这就要用到一致性哈希了。

一致性哈希初步

在一致性哈希中,不存在去模(%m)一个东西的,假如我们用的哈希函数是MD5,产生的哈希值的范围是
0 ~ 2^64 - 1,我们想象把整个哈希域成一个环。假设有三台机器,通过他们不同的机器信息做哈希函数,得出不同的位置来。这样三台机器会插到这个环里去。当一个数据进来的时候,通过哈希函数算出来它的哈希值,将它放到顺时针最近的这台机器上,作为数据的归属。

image.png
实现的方法是:逻辑端的每个机器会存着三台机器的哈希值排序的结果(有序数组),要存入的数据操作打到了逻辑端的某一个机器上,该机器计算得出该数据哈希值,在有序数组中做二分,找到大于这个哈希值的最左的位置,如果没有找到大于的最近的,就放进第一台,以此达到顺时针环状的效果。

优点与缺点

优点:

  • 数据的迁移代价很低:因为每一台机器都会管有环中的一段圆弧范围。当增加一个机器时,假设放到了2号和3号之间,那么只需将3号和4号之间的数据存入4号(本来属于2号的),同时将3号和4号之间的数据从2号中移除即可,而1号、3号不用动。看上图。减去一个机器也是同理。

缺点:

  • 当机器少的时候,可能做不到一上来机器就在环上均分。
  • 增加机器和减少机器的时候,这种机制负载会不均衡。

如何解决呢?一致性哈希最终。

一致性哈希最终

解决上面的两个问题的方式:虚拟节点技术。

虚拟节点技术

我们给1号机器分配1000个字符串,给2号机器分配1000个字符串,给3号机器分配1000个字符串。我们让虚拟节点去抢环,而不是一个机器只有一个哈希值了,每一台有1000个。这样3000个哈希值会平均分配这个环。我们随便选一段,这一段中属于1号、2号、3号字符串的哈希值点就是差不多的。存数据同上面分析的那样,顺时针存入。

当我们添加一个机器时,也给这个机器分配1000个字符串,重新去抢环,将对应的数据迁移过来,因为平均分配的缘故,所以负载是平衡的,原因就是因为这是按比例抢,就可以解决初始不均和加减机器后负载不均的问题。

这样的方式还有一个好处就是,如果一个机器很强,我们就可以给它多分配虚拟节点,如果一个机器不强,我们就给它少分配虚拟节点,这样可以根据实际情况管理负载。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值