本文来说下关于一致性hash算法的几个问题

文章目录

  • 分布式系统的基本概念
    • 分布式系统与高并发高可用
    • 集群和分布式的区别与联系
  • 分布式系统的分发
    • 常用负载均衡策略
    • Hash取模策略
    • Hash取模的弊端
  • 一致性哈希
    • 一致性哈希实例
    • 一致性哈希的定义
    • 解决思路是什么
    • 一致性Hash算法的神秘面纱
    • 一致性Hash算法的容错性和可扩展性
    • Hash环的数据倾斜问题
  • 本文小结

分布式系统的基本概念

分布式系统与高并发高可用

当今高并发和海量数据处理等场景越来越多,实现服务应用的高可用、易扩展、短延时等成为必然。在此情况下分布式系统应运而生,互联网的场景无外乎存储和计算,因此分布式系统可以简单地分为:

  • 分布式存储
  • 分布式计算

所谓分布式系统就是一批计算机组合起来共同对外提供服务,对于用户来说具体有多少规模的计算机完成了这次请求,完全是无感知的。分布式系统中的计算机越多,意味着计算和存储资源等也就越多,能够处理的并发访问量也就越大,响应速度也越快。如图为简单整体架构图:


集群和分布式的区别与联系

集群和分布式的区别与联系

集群是从原来的单机演变来的,单台机器扛不住就加机器,直到服务负载、稳定性、延时等指标都满足,集群中的N台机器上部署一样的程序,就像一台机器被复制多份一样,这种形式就是集群化。

分布式是将一个完整的系统,按照业务功能拆分成一个个独立的子系统,这些服务之间使用更高效的通信协议比如RPC来完成调度,各个子服务就像在一台机器上一样,实现了业务解耦,同时提高了并发能力确实不赖。一个大的分布式系统可以理解拆分之后的子服务使用集群化,一个个子服务之间使用类似于RPC的协议串联,组成一个庞大的存储和计算网络。如图为简单的分布式系统结构:


分布式系统的分发

常用负载均衡策略

以分布式系统中的存储和缓存为例,如果存储集群中有5台机器,如果这时有请求,就需要考虑从哪台机器获取数据,一般有几种方法:

  1. 随机访问
  2. 轮询策略
  3. 权重轮询策略
  4. Hash取模策略
  5. 一致性哈希策略

各种方法都有各自的优缺点:随机访问可能造成服务器负载压力不均衡;轮询策略请求均匀分配,但当服务器有性能差异,无法按性能分发; 权值需要静态配置,无法自动调节;哈希取模如果机器动态变化会导致路由产生变化,数据产生大量迁移。


Hash取模策略

Hash取模策略是其中常用的一种做法,它可以保证相同请求相同机器处理,这是一种并行转串行的方法,工程中非常常见。笔者在刚毕业做流量分析时就是按照报文的五元组信息做key来决定服务内的业务线程id,这样确保相同的TCP/HTTP连接被相同的线程处理,避免了线程间的通信和同步,实现了无锁化处理,所以还是很有用的。

index = hash_fun(key) % N

从上面的普通hash取模公式可以看到,如果N不变或者可以自己主动控制,就可以实现数据的负载均衡和无锁化处理,但是一旦N的变化不被控制,那么就会出现问题。


Hash取模的弊端

大数字取模分散不同桶,两个桶, 2、3、4、5 ,模 2 分桶:

扩容新桶,模 3 来结果:


每次扩展和收缩所有条目分布重新计算,某些场景不可接受。文件分布在哪台哈希算法决定,这个系统想要加一台机器时就需要停下来等所有文件重新分布一次才能对外提供服务,一台机器掉线尽管只掉一部分数据,所有数据访问路由都会出问题。无法平滑的扩缩容。


一致性哈希

一致性哈希实例

无状态化,用多个桶, 模 7个,开始只有两个 3 和 6。同样取模,分到不存在的桶,往下找第一个真实存桶。 2 和 3 分3 桶, 4 和 5分 6 桶。

添加新编号4桶,还是模 7:


3 号桶取模小于等于 3,4 号桶只需从 6 号桶拿走属于它数字就可,只调整一个桶重新分布。即使有 1 亿个桶,增加减少一个桶也只会影响一个桶的数据分布。

只需和后面机器同步数据就可工作,同步到后一台机器再下线。实现中可以让每台机器同步一份自己前面机器的数据,即使掉线也不影响这部分数据服务。

问题:编号 6 的机桶下线了,没有后一个桶了,哈希空间做成环状,数据给 3 :


一致性哈希还能实现部分的分布式系统无锁化,算法的确定性,分到哪个桶也是确定的就不存在争抢,不需要分布式锁了


一致性哈希的定义

In computer science, consistent hashing is a special kind of hashing such that when a hash table is resized, only K/n keys need to be remapped on average, where K is the number of keys, and n is the number of slots.维基百科-Consistent hashing

翻译一下:

一致哈希 是一种特殊的哈希算法。在使用一致哈希算法后,哈希表槽位数(大小)的改变平均只需要对K/n 个关键字重新映射,其中 K是关键字的数量,n是槽位数量。在传统的哈希表中,添加或删除一个槽位的几乎需要对所有关键字进行重新映射。维基百科-一致性哈希

从定义可以知道,一致性哈希是一种特殊的哈希算法,区别于哈希取模,这种特殊的哈希算法实现了少量数据的迁移,避免了几乎全部数据的移动,这样就解决了普通hash取模的动态调整带来的全量数据变动。


解决思路是什么

先不看算法的具体实现,先想想普通hash取模的问题根源是什么?

N的变动

没错!根源就在于N的变动,那么如果N被固定住呢?并且让N很大,那么每次被移动的key数就是K_all/Slot_n,也就是有槽位的概念,或者说是小分片的概念,直白一点就是鸡蛋放到了很多很多的固定数量的篮子里:

Key_all 存储的全部key的数量
Slot_n 总的槽位或者分片数
Min_Change 为最小移动数量
Min_change = Key_all/Slot_n
Min_change 也是数据的最小分片Shard

小分片的归属

这里还有一个问题要解决,将N固定且设置很大之后,数据分片shard变得非常小了,这时就有shard的所属问题,也就是比如N=100w,此时集群有10台,那么每台机器上理论上平均有10w,当然可以根据机器的性能来做差异化的归属配置,性能强的多分一些shard,性能差的少分一些shard。问题到这里,基本上已经守得云开见月明了,不过还是来看看1997年麻省理工发明的一致性哈希算法原理吧。

Karger的一致性哈希算法

一致性哈希算法在1997年由麻省理工学院的Karger等人在解决分布式Cache中提出的,设计目标是为了解决因特网中的热点(Hot spot)问题,初衷和CARP十分类似。一致性哈希修正了CARP使用的简单哈希算法带来的问题,使得DHT可以在P2P环境中真正得到应用。一致性哈希算法


一致性Hash算法的神秘面纱

一致性Hash算法也是使用取模的方法,只是,刚才描述的取模法是对服务器的数量进行取模,而一致性Hash算法是对2的32次方取模,什么意思呢?简单来说,一致性Hash算法将整个哈希值空间组织成一个虚拟的圆环,如假设某哈希函数H的值空间为0-2^32-1(即哈希值是一个32位无符号整形),整个哈希环如下:


整个空间按顺时针方向组织,圆环的正上方的点代表0,0点右侧的第一个点代表1,以此类推,2、3、4、5、6……直到2的32次方-1,也就是说0点左侧的第一个点代表2的32次方-1, 0和2的32次方-1在零点中方向重合,我们把这个由2^32个点组成的圆环称为Hash环。

下一步将各个服务器使用Hash进行一个哈希,具体可以选择服务器的IP或主机名作为关键字进行哈希,这样每台机器就能确定其在哈希环上的位置,这里假设将上文中四台服务器使用IP地址哈希后在环空间的位置如下:


接下来使用如下算法定位数据访问到相应服务器:将数据key使用相同的函数Hash计算出哈希值,并确定此数据在环上的位置,从此位置沿环顺时针“行走”,第一台遇到的服务器就是其应该定位到的服务器!

例如我们有Object A、Object B、Object C、Object D四个数据对象,经过哈希计算后,在环空间上的位置如下:


根据一致性Hash算法,数据A会被定为到Node A上,B被定为到Node B上,C被定为到Node C上,D被定为到Node D上。


一致性Hash算法的容错性和可扩展性

现假设Node C不幸宕机,可以看到此时对象A、B、D不会受到影响,只有C对象被重定位到Node D。一般的,在一致性Hash算法中,如果一台服务器不可用,则受影响的数据仅仅是此服务器到其环空间中前一台服务器(即沿着逆时针方向行走遇到的第一台服务器)之间数据,其它不会受到影响,如下所示:

下面考虑另外一种情况,如果在系统中增加一台服务器Node X,如下图所示:


此时对象Object A、B、D不受影响,只有对象C需要重定位到新的Node X !一般的,在一致性Hash算法中,如果增加一台服务器,则受影响的数据仅仅是新服务器到其环空间中前一台服务器(即沿着逆时针方向行走遇到的第一台服务器)之间数据,其它数据也不会受到影响。

综上所述,一致性Hash算法对于节点的增减都只需重定位环空间中的一小部分数据,具有较好的容错性和可扩展性。


Hash环的数据倾斜问题

一致性Hash算法在服务节点太少时,容易因为节点分部不均匀而造成数据倾斜(被缓存的对象大部分集中缓存在某一台服务器上)问题,例如系统中只有两台服务器,其环分布如下:


此时必然造成大量数据集中到Node A上,而只有极少量会定位到Node B上。为了解决这种数据倾斜问题,一致性Hash算法引入了虚拟节点机制,即对每一个服务节点计算多个哈希,每个计算结果位置都放置一个此服务节点,称为虚拟节点。具体做法可以在服务器IP或主机名的后面增加编号来实现。

例如上面的情况,可以为每台服务器计算三个虚拟节点,于是可以分别计算 “Node A#1”、“Node A#2”、“Node A#3”、“Node B#1”、“Node B#2”、“Node B#3”的哈希值,于是形成六个虚拟节点:


同时数据定位算法不变,只是多了一步虚拟节点到实际节点的映射,例如定位到“Node A#1”、“Node A#2”、“Node A#3”三个虚拟节点的数据均定位到Node A上。这样就解决了服务节点少时数据倾斜的问题。在实际应用中,通常将虚拟节点数设置为32甚至更大,因此即使很少的服务节点也能做到相对均匀的数据分布。


本文小结

一致性哈希算法是一种特殊的哈希算法,特殊之处在于将普通哈希取模的N进行固定,从而确保了相同的key必然是相同的位置,从而避免了牵一发而动全身的问题,这是理解一致性哈希的关键。

一致性哈希算法的另外一个要点就是将N固定且设置很大之后,实际上就是进行数据分片Sharding,分布的小片就要和实际的机器产生关联关系,也就是哪台机器负责哪些小分片。

但是一致性哈希算法并不是从彻底解决了由于动态调整服务器数据产生的数据迁移问题,而是将原来普通哈希取模造成的几乎全部迁移,降低为小部分数据的移动,是一种非常大的优化,在工程上基本上可以满足要求。

关于一致性hash算法的几个问题相关推荐

  1. 一致性 Hash 算法的实际应用

    前言 记得一年前分享过一篇<一致性 Hash 算法分析>,当时只是分析了这个算法的实现原理.解决了什么问题等. 但没有实际实现一个这样的算法,毕竟要加深印象还得自己撸一遍,于是本次就当前的 ...

  2. 不会一致性hash算法,劝你简历别写搞过负载均衡

    这两天看到技术群里,有小伙伴在讨论一致性hash算法的问题,正愁没啥写的题目就来了,那就简单介绍下它的原理.下边我们以分布式缓存中经典场景举例,面试中也是经常提及的一些话题,看看什么是一致性hash算 ...

  3. 什么是一致性 Hash 算法

    数据分片 先让我们看一个例子吧 我们经常会用 Redis 做缓存,把一些数据放在上面,以减少数据的压力. 当数据量少,访问压力不大的时候,通常一台Redis就能搞定,为了高可用,弄个主从也就足够了: ...

  4. hash算法_一致性hash算法简介

    一致性hash算法有什么用?我们为什么需要一致性hash算法?这两个问题的答案可以看这篇文章 分布式系统路由算法简介. 了解了一致性hash算法出现的背景,我们来看看什么是一致性hash算法.一致性h ...

  5. 一致性Hash算法(KetamaHash)的c#实现

    Consistent Hashing最大限度地抑制了hash键的重新分布.另外要取得比较好的负载均衡的效果,往往在服务器数量比较少的时候需要增加虚拟节点来保证服务器能均匀的分布在圆环上.因为使用一般的 ...

  6. 一致性hash算法_分布式寻址算法

    一.分布式寻址算法简介 分布式寻址算法是很重要的内容,不了解这些算法,也就不能透彻的了解各种分布式中间件的原理.简单说一下这些高大上的寻址到底是个啥意思,比如在elasticsearch中,采用的是多 ...

  7. Java算法之 一致性hash算法原理及实现

    为什么80%的码农都做不了架构师?>>>    一致性hash算法原理及实现 转载于:https://my.oschina.net/90888/blog/1645131

  8. php 实现一致性hash 算法 memcache

    散列表的应用 涉及到数据查找比对,首先考虑到使用HashSet.HashSet最大的好处就是实现查找时间复杂度为O(1).使用HashSet需要解决一个重要问题:冲突问题.对比研究了网上一些字符串哈希 ...

  9. 算法:五分钟了解一致性hash算法

    五分钟了解一致性hash算法 前言 一致性哈希算法的设计目标是为了解决因特网中的热点问题,现在也被广泛应用在分布式系统中. 比如针对负载均衡问题,对hash值取模的算法扩展性差,当增加或者减少服务器时 ...

  10. 一致性hash算法简介

    一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT)实现算法,设计目标是为了解决因特网中的热点(Hot spot)问题,初衷和CARP十分类似.一致性哈希修正了CARP使用的简单哈希 ...

最新文章

  1. 存储器里面的一个采用直接映射方式的32KB缓存-一个四路组相连的缓存,容量为16KB
  2. 为什么在Swift字符串中像‍‍‍这样的表情符号字符被如此奇怪地对待?
  3. PS基础教程[3]如何去除照片上的水印
  4. linux中的du 命令详解
  5. js跨域的各种方法总结。
  6. 微软编程一小时--微软2014实习生招募编程模拟测试感想
  7. Spanning Tree Protocol (STP) in NetScaler Appliance
  8. 2058. 笨拙的手指
  9. samba配置问题一则及配置详解
  10. Drools规则引擎讲解
  11. 互联网下载.deb安装包
  12. 坐在马桶上撸糖果---史上最全糖果等你来撸
  13. 【VBA研究】智力游戏-蓝色方块
  14. android多国语言---简写对应国家code
  15. 【生信MOOC】生物序列比对工具——多序列比对
  16. Hook函数三步走(SetWindowsHookEx、UnhookWindowsHookEx、CallNextHookEx)
  17. 定解问题(一)| 通解与特解 + 适定性 | 偏微分方程(五)
  18. 用Latex写IEEE格式的论文时如何取消页码
  19. Java 课程设计--数据库管理系统
  20. 推荐一些能提升工作幸福度的小工具

热门文章

  1. Mysql取分组中前N条记录
  2. ActiveMQ学习总结(5)——Java消息服务JMS详解
  3. hadoop2.2单节点集群的搭建
  4. Ubuntu网络配置相关相关
  5. MongoDB介绍与安装
  6. [转]云计算:SaaS、PaaS、IaaS、CaaS
  7. 高清接口芯片---gv7600、sii9135
  8. Android入门篇二:使用意图在Activity之间传递数据
  9. 微软、谷歌、百度等公司经典面试100题[第1-60题]——自己的实现[转]
  10. office2007右键doc,xls