当我们在做数据库分库分表或者是分布式缓存时,不可避免的都会遇到一个问题:

如何将数据均匀的分散到各个节点中,并且尽量的在加减节点时能使受影响的数据最少。

Hash 取模

随机放置就不说了,会带来很多问题。通常最容易想到的方案就是 hash 取模了。

可以将传入的 Key 按照 index = hash(key) % N 这样来计算出需要存放的节点。其中 hash 函数是一个将字符串转换为正整数的哈希映射方法,N 就是节点的数量。

这样可以满足数据的均匀分配,但是这个算法的容错性和扩展性都较差。

比如增加或删除了一个节点时,所有的 Key 都需要重新计算,显然这样成本较高,为此需要一个算法满足分布均匀同时也要有良好的容错性和拓展性。

一致 Hash 算法

一致 Hash 算法是将所有的哈希值构成了一个环,其范围在 0 ~ 2^32-1。如下图:

之后将各个节点散列到这个环上,可以用节点的 IP、hostname 这样的唯一性字段作为 Key 进行 hash(key),散列之后如下:

之后需要将数据定位到对应的节点上,使用同样的 hash 函数 将 Key 也映射到这个环上。

这样按照顺时针方向就可以把 k1 定位到 N1节点,k2 定位到 N3节点,k3 定位到 N2节点

容错性

这时假设 N1 宕机了:

依然根据顺时针方向,k2 和 k3 保持不变,只有 k1 被重新映射到了 N3。这样就很好的保证了容错性,当一个节点宕机时只会影响到少少部分的数据。

拓展性

当新增一个节点时:

在 N2 和 N3 之间新增了一个节点 N4 ,这时会发现受印象的数据只有 k3,其余数据也是保持不变,所以这样也很好的保证了拓展性。

虚拟节点

到目前为止该算法依然也有点问题:

当节点较少时会出现数据分布不均匀的情况:

这样会导致大部分数据都在 N1 节点,只有少量的数据在 N2 节点。

为了解决这个问题,一致哈希算法引入了虚拟节点。将每一个节点都进行多次 hash,生成多个节点放置在环上称为虚拟节点:

计算时可以在 IP 后加上编号来生成哈希值。

这样只需要在原有的基础上多一步由虚拟节点映射到实际节点的步骤即可让少量节点也能满足均匀性。

号外

最近在总结一些 Java 相关的知识点,感兴趣的朋友可以一起维护。

地址: https://github.com/crossoverJie/Java-Interview

一致 Hash 算法分析的更多相关文章

  1. 一致性 Hash 算法分析

    当我们在做数据库分库分表或者是分布式缓存时,不可避免的都会遇到一个问题: 如何将数据均匀的分散到各个节点中,并且尽量的在加减节点时能使受影响的数据最少. Hash 取模 随机放置就不说了,会带来很多问 ...

  2. Cuckoo hash算法分析

    一 基本思想: cuckoo hash是一种解决hash冲突的方法,其目的是使用简单的hash 函数来提高hash table的利用率,同时保证O(1)的查询时间 基本思想是使用2个hash函数来处理 ...

  3. 【转】【java源码分析】Map中的hash算法分析

    全网把Map中的hash()分析的最透彻的文章,别无二家. 2018年05月09日 09:08:08 阅读数:957 你知道HashMap中hash方法的具体实现吗?你知道HashTable.Conc ...

  4. Cuckoo hash算法分析——其根本思想和bloom filter一致 增加hash函数来解决碰撞 节省了空间但代价是查找次数增加

    基本思想: cuckoo hash是一种解决hash冲突的方法,其目的是使用简单的hash 函数来提高hash table的利用率,同时保证O(1)的查询时间 基本思想是使用2个hash函数来处理碰撞 ...

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

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

  6. .Net 中HashTable,HashMap 和 Dictionary<key,value> 和List<T>和DataTable的比较

    参考资料 http://www.cnblogs.com/MichaelYin/archive/2011/02/14/1954724.html http://zhidao.baidu.com/link? ...

  7. C#中Dictionary,Hashtable,List的比较及分析

    一. Dictionary与Hashtable Dictionary与Hashtable都是.Net Framework中的字典类,能够根据键快速查找值 二者的特性大体上是相同的,有时可以把Dicti ...

  8. 【Java】留下没有基础眼泪的面试题

    前言 只有光头才能变强 本文力求简单讲清每个知识点,希望大家看完能有所收获 一.如何减少线程上下文切换 使用多线程时,不是多线程能提升程序的执行速度,使用多线程是为了更好地利用CPU资源! 程序在执行 ...

  9. hashTabel List 和 dic

    hashTabel  List  和 dic 原:https://www.cnblogs.com/jilodream/p/4219840.html .Net 中HashTable,HashMap 和 ...

随机推荐

  1. 防御xss 大致理解

    前端 发送留言内容 包含 js 代码 后台 管理员 查看 留言 代码被执行 拿到cookie 成功登陆 解决办法 对录入 进行相关的过滤处理 其他解决方法 正在学习中

  2. ISP PIPLINE (十一) color correction

    什么是color correction? 为什么要进行color correction? 转换后的色彩饱和度更加明显,更加符合人眼感官. 如何进行color correction? 下图是步骤: 第一 ...

  3. Shell 编程注意点

    (一)判断语句 [$# -lt 4 ]判断语句,格式[空格 比较对象1 比较符号 比较对象2] $# 启动脚本时携带参数个数;参数个数总数. $1 代表第一个参数. $? 最后一次执行名命令的退出状态 ...

  4. python中的矩阵、多维数组

    2. 创建一般的多维数组 import numpy as np a = np.array([1,2,3], dtype=int)  # 创建1*3维数组   array([1,2,3]) type(a ...

  5. vue-These relative modules were not found

    今天在做vue2.0+webpack的项目的时候,本来一切正常,整理了一下文件夹分类,就是把一些基础的组件新建了一个文件夹移进去,然后就报了以下的错误,其他东西都没改 最后网上找了很多资料,有说配置文 ...

  6. 用OleDb导入Excel时提示驱动错误问题解决办法

    导入格式为xls的excel文件,发生了错误 未处理System.Data.OleDb.OleDbException HResult=-2147467259 Message=外部数据库驱动程序 (1) ...

  7. hashlib模块,shutil,模块 ,,xml 文件解析,configparser,模块,类,什么是类

    1 什么是hash hash是一种算法,该算法接受传入的内容,经过运算得到一串hash值 如果把hash算法比喻为一座工厂 那传给hash算法的内容就是原材料 生成的hash值就是生产出的产品 2.为 ...

  8. Hive 本地调试方法

    关键词:hive, debug 本地调试(local debug) Hive 可分为 exec (hive-exec,主要对应源码里的ql目录) 和 metastore 两部分,其中exec对外有两种 ...

  9. [LeetCode] Maximize Distance to Closest Person 离最近的人的最大距离

    In a row of seats, 1 represents a person sitting in that seat, and 0 represents that the seat is emp ...

  10. Java语法细节 - try_finally和set相关

    目录 try-catch-finally的关系 TreeSet和HashSet的实现原理和区别 BigDecimal中的一些坑 当BigDecimal在HashSet/HashMap和TreeSet/ ...