写在前面
  在学习Redis的集群内容时,看到这么一句话:Redis并没有使用一致性hash算法,而是引入哈希槽的概念。而分布式缓存Memcached则是使用分布式一致性hash算法来实现分布式存储。所以就专门学习了一下

什么是分布式?什么是一致性?什么是哈希?
  1)分布式(distributed)是指在多台不同的服务器中部署不同的服务模块,通过远程调用协同工作,对外提供服务。“分布式一致性hash算法”中的“分布式”就是指缓存数据的分布性。

  集中式将一个系统的所有服务模块部署到了不同的服务器上,构成一个集群,通过负载均衡设备对外提供服务。集中式部署就像茶水间同时有多个饮水机提供服务,服务冗余部署。分布式部署则将系统拆分成不同的服务模块,然后将不同的服务模块部署在不同的服务器上。

  2)一致性Wiki的定义:

  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. In contrast, in most traditional hash tables, a change in the number of array slots causes nearly all keys to be remapped because the mapping between the keys and the slots is defined by a modular operation.

  大概意思就是“一致性哈希是一种特殊的哈希算法,提供了这样的一个哈希表,当重新调整大小的时候,平均只有部分(k/n)key需要重新映射哈希槽,而不像传统哈希表那样几乎所有key需要需要重新映射哈希槽”。一致性hash能保证在分布式环境中,对key进行哈希的结果或者说key与节点之间的映射关系不会受节点的增加和删除而产生重大的变化。

  3)hash,俗称“哈希”,也叫散列,是一种将任意长度的消息(数据)压缩到某一固定长度的消息摘要(数据)的算法。常见的hash算法有MD5,SHA等。hash算法具有几个重要的特性:不可逆性(即从hash值反推出原消息是不可能的)、抗冲突性(即给定消息M1,不存在另一个消息M2,使得Hash(M1)=Hash(M2))和分布均匀性(即hash的结果是均匀分布的)。Memcached中,存取数据时都要进行哈希映射。正是这几个特性,保证了memcached缓存中key值得唯一性。

分布式一致性hash算法使用背景
  我们已经知道,memcached的分布式主要在于客户端的分布式算法。memcached客户端就像一个网络中的路由,经过特定的算法将数据分散的存在到memcached服务端的机器上,又从分散的memcached服务端的机器上提取数据。实际中,常见的存储和提取数据的算法有取模算法和本文分析的一致性hash算法。

  取模算法算法的原理是:

hash(key)%N
1
  其中key 代表数据的键,N 代表memcached服务器的数量。取模的结果就是memcached客户端要定位的memcached服务器。取模算法很明显,结果受N的影响,当服务器数量N增加或者减少的时候,原先的缓存数据定位几乎失效,缓存数据定位失效意味着要到数据库重新查询,这对于高并发的系统来说是致命的。于是,人们提出了一致性hash算法,最终目的是实现在移除、添加一个memcached服务器时对已经存在的缓存数据的定位影响尽可能的降到最小。

环形hash空间
  通常,一个缓存数据的key经过hash后会得到一个32位的值,也就是0~2^32 - 1数值范围。我们可以把这个数值范围抽象成一个首尾相连环形的空间,我们称这个空间为环形hash空间。如下图所示:

映射key、server节点到环形hash空间
  有了环形hash空间之后,缓存数据的key经过hash后得到的值就映射到了环形hash空间。假设有key1、key2、key3、key4,经过hash后,映射到环形hash空间如下图所示。同理,我们可以把memcached服务器抽象成网络上的节点经过hash后映射到环形hash空间。假设有server1(可以是服务器的某些唯一标志信息,如ip等)、server2、server3

映射key到server节点
  现在缓存key和server节点都经过一致性hash算法映射到了环形hash空间,现在就可以将缓存key和server节点的关系进行映射了。顺时针沿着环形hash空间,从某个缓存key开始,直到遇到一个server节点,那么该缓存key就存储到这个server节点上。如图:

  了解了key、server节点、hash空间之间的映射关系之后,已经清楚了缓存数据是怎样分布的存储到memcached服务器了。查找缓存数据的时候,也采用同样的映射方法来定位。

删除server节点
  当在server集群中删除server2节点时,受影响的也仅是server1~server2之间的缓存数据Key3,这部分数据需要重新到数据库查找再次映射到server3节点上。如下图所示:

添加server节点
  现在我们已经知道memcached存储和访问数据的策略了。那么当在server集群中增加一个server节点时,对数据访问的命中率又有什么影响呢。如下图,在server1和server2节点之间增加一个节点server4

  从上图可以看出,增加server4节点后,原有的缓存数据分布中,仅有server1和server4节点之间的数据进行了重新分布,这部分数据需要重新到数据库查找再次映射到新添加的server4节点上。尽管不能命中的缓存数据仍然存在,但相对于取模算法,已经是最大限度地抑制了hash键的重新分布。

虚拟节点的引入
  我们已经知道,添加和删除节点都会影响缓存数据的分布。尽管hash算法具有分布均匀的特性,但是当集群中server数量很少时,他们可能在环中的分布并不是特别均匀,进而导致缓存数据不能均匀分布到所有的server上。

  为解决这个问题,需要使用虚拟节点的思想:为每个物理节点(server)在环上分配100~200个点,这样环上的节点较多,就能抑制分布不均匀。当为cache定位目标server时,如果定位到虚拟节点上,就表示cache真正的存储位置是在该虚拟节点代表的实际物理server上。另外,如果每个实际server节点的负载能力不同,可以赋予不同的权重,根据权重分配不同数量的虚拟节点。

  虚拟节点的hash计算可以采用对应节点的 IP 地址加数字后缀的方式。例如假设 serverA 的 IP 地址为 127.0.0.1 。

  引入虚拟节点前,计算serverA 的 hash 值:

hash(“127.0.0.1”);
1
  引入虚拟节点后,计算虚拟节点serverA1 和 serverA2 的 hash 值:

hash(“127.0.0.1#1”);
hash(“127.0.0.1#2”);
1
2
一致性hash算法与取模算法的比较
  取模算法的方法简单,数据的分散性也可以,但其主要缺点是当添加或移除server节点时,缓存重新映射的代价相当巨大。添加或移除server节点时,余数就会产生巨变,这样就无法定位与存储时相同的server节点,从而影响缓存的命中率。

  而一致性hash算法则最大限度的减少了server节点变化带来的影响,当节点变化时,只影响一个server节点的部分数据,且hash算法能够保证需要重新分布的缓存数据能映射到新的server节点中。
---------------------
原文:https://blog.csdn.net/u011489043/article/details/78944985

分布式一致性hash算法相关推荐

  1. 【java】分布式一致性hash算法

    1.概述 本文是视频 视频 的笔记 2. 一致性hash算法哪里用? 一般情况下如果我们的数据很多,一台机器装不下,我们一般会采用分布式缓存,但是因为是分布式,我们要解决3个问题 数据怎么存储到分布式 ...

  2. memcached 分布式 一致性hash算法demo

    一致性Hash分布算法分4个步骤: 步骤1:将一个32位整数[0 ~ (2^32-1)]想象成一个环,0 作为开头,(2^32-1) 作为结尾,当然这只是想象. 步骤2:通过Hash函数把KEY处理成 ...

  3. memcache分布式 [一致性hash算法] 的php实现

    以前一般用的是最原始的hash取模做分布式,当生产过程中添加或删除一台memcache都会造成数据的全部失效,一致性hash就是为了解决这个问题,把失效数据降到最低,相关资料可以google一下! p ...

  4. php 一致性hash,【转载】memcache分布式 [一致性hash算法] 的php实现

    最近在看一些分布式方面的文章,所以就用php实现一致性hash来练练手,以前一般用的是最原始的hash取模做分布式,当生产过程中添加或删除一台memcache都会造成数据的全部失效,一致性hash就是 ...

  5. 「分布式专题」分布式系统中一致性hash算法

    近年来B2C.O2O等商业概念的提出和移动端的发展,使得分布式系统流行了起来.分布式系统相对于单系统,解决了流量大.系统高可用和高容错等问题.功能强大也意味着实现起来需要更多技术的支持.例如系统访问层 ...

  6. hash,bloomfilter,分布式一致性hash

    场景 使用word 文档时,判断某个单词是否拼写正确 垃圾邮件过滤算法 Redis缓存穿透 bitcoin core中交易校验 需求 从海量数据中查询某个字符串是否存在? 平衡二叉搜索树 增删改查时间 ...

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

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

  8. 一致性 Hash 算法学习(分布式或均衡算法)

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

  9. 分布式缓存原理——一致性hash算法(hash环)、Hash槽

    一.一致性哈希算法:一种特殊的哈希算法,目前主要应用于分布式缓存当中,可以有效地解决分布式存储结构下动态增加和删除节点所带来的问题. 一致性Hash算法是对2^32取模,2^32个点组成的圆环称为Ha ...

最新文章

  1. linux oracle 脚本,Linux的Oracle服务脚本
  2. python 列出出当前目录及所有子目录下的文件
  3. Mac上Chrome浏览器跨域解决方案
  4. Page cache和Buffer cache[转1]
  5. Java 关键字和语句
  6. jira在linux下面的安装和配置
  7. python的全局变量能暂存数据吗_【Python】Python之全局变量
  8. 读书笔记(从0到1)
  9. 【电子书下载】《Android应用程序开发与典型案例》完整版!!
  10. 2022年最佳的9种逆向工程工具[持续更新]
  11. 《3D游戏与计算机图形学中的数学方法》读书笔记--四元数
  12. c语言网吧计费管理小项目,c语言网吧计费系统小项目.doc
  13. linux capability
  14. 小米手机刷机工具MiFlash怎么用
  15. 美国电话号码格式化的Objective-C代码
  16. 分布式WLAN全双工链路加权调度算法
  17. Python中制表符\t的使用
  18. 企业研发人员配备比例_一般公司职能结构及人员分布比例配备
  19. EXCEL的嵌套if及时间处理
  20. 基础知识 | es6的知识点

热门文章

  1. OpenCV长方形squares探测器的实例(附完整代码)
  2. C++用二进制交换二个数的实现算法(附完整源码)
  3. OpenGL 几何着色器细分的实例
  4. OpenGL背景照明
  5. C语言二个多项式的加法poly add算法(附完整源码)
  6. n 个整数的无序数组,找到每个元素后面比它大的第一个数,要求时间复杂度为 O(N)
  7. C/C++extern关键字
  8. C++11 - 返回类型后置
  9. C语言获取mysql表数据结构_【数据结构】实现顺序表(c语言)
  10. 19_clickhouse,数据查询与写入优化,分布式子查询优化,外部聚合/排序优化,基于JOIN引擎的优化,SQL优化案例,物化视图提速,查询优化常用经验法则,选择和主键不一样的排序键,数据入库优化