问题

分布式哈希一致性的动机是什么?

相比其他有什么好处

概述

我们谈论的分布式哈希一致性常常使用在负载均衡,权衡一个策略的好坏,我们常常谈到扩展性和容错性。我们可以从以下两个方面来考量

扩展性 :水平扩展和垂直扩展,加减一台cluster 是否对整个集群有影响。

容错性 :假如一台cluster 是否会影响到其他的 cluster,是否可以用比较小的代价进行恢复。

负载均衡

负载均衡使用的策略 :

随机访问策略。系统随机访问,服务器负载压力不均衡,所以有可能分配的不合理。

轮询策略。请求均匀分配,如果服务器有性能差异,则无法实现性能好的服务器能够多承担一部分。

权重轮询策略。权值需要静态配置,无法自动调节,不适合对长连接和命中率有要求的场景。

Hash取模策略。不稳定,如果列表中某台服务器宕机,则会导致路由算法产生变化,由此导致命中率的急剧下降。 一致性哈希策略。

Hash取模策略

hash取模可以定义为 “ key % n = 目标cluster ”,key可以相当于 java 中的hashcode ,n 则为当前所有集群机器的数量。 但是它的缺点很明显,假如使用hash取模策略,若增加台cluster,(图片来自参考资料)

减少台机器

可以看到增加台机器,会导致key 重新映射,那么迁移工作将是巨大的,而减少一台也是同样的道理,最重要的原因是该策略是依赖机器的数量进行分配目标机器。

分布式一致性hash算法

直接上图(来源见参考资料)

上面是hash环,cluster 分布在hash环上,请求经过hash 等到的key沿着顺时针,第一个到达的节点就是目标cluster .

扩展性和容错性

假如增加/减少了一台机器,对其他的cluster并没有什么影响,而某台cluster发生故障后,恢复的时候只需要将故障节点的keys 放在沿着hash环下一台节点就可以了。

虚拟节点

但是我们将节点分布在hash 环上的时候有可能分布不均,例如

上图,服务器1接受的请求在平等条件下肯定比其他的多,我们可以通过增设虚拟节点的方式来解决这个问题,虚拟节点并不是真实的物理节点,是虚构出来的,这样可以解决节点在hash 环中不平衡的问题,同时也是根据权重不同可以分配多几个虚拟节点。

运用

rocketmq 集群消费端 和 dubbo (RPC) 对服务提供者负载均衡的时候会使用

MySQL 分库分表的实现也是可以使用一致性Hash 算法 (这个在后续的文章中会提到)

这里的dubbo中的一致性hash 算法的运用和 数据库的运用有点不同,为什么呢? dubbo 是 RPC ,某个节点down 或是增加了节点,并没有影响,而数据库就不同了,数据库存储的是数据,某个节点down 了数据就找不到了,后续文章再详细说明。

具体实现

我们看一下 dubbo 中关于hash 一致性算法的实现,,主要的实现是依靠  TreeMap 的 ceilingEntry  方法, 该方法的注解 :

The ceilingEntry(K key) method is used to return a key-value mapping associated with the least key greater than or equal to the given key, or null if there is no such key.

就是返回最相近的值,这和 一致性 hash 算法的key 绕着圈走到最近的节点思路一致。 dubbo 中的一致性hash实现在 ConsistentHashLoadBalance 类,我们直接看 doSelect 方法,其中 invokers 就是候选的节点,invocation 是调用者的封装,最后返回的 Invoker 自然就是目标 invoker .

1 public class ConsistentHashLoadBalance extendsAbstractLoadBalance {2 public static final String NAME = "consistenthash";3

4 /**

5 * Hash nodes name6 */

7 public static final String HASH_NODES = "hash.nodes";8

9 /**

10 * Hash arguments name11 */

12 public static final String HASH_ARGUMENTS = "hash.arguments";13

14 private final ConcurrentMap> selectors = new ConcurrentHashMap>();15

16 @SuppressWarnings("unchecked")17 @Override18 protected Invoker doSelect(List>invokers, URL url, Invocation invocation) {19 String methodName =RpcUtils.getMethodName(invocation);20 String key = invokers.get(0).getUrl().getServiceKey() + "." +methodName;21 //using the hashcode of list to compute the hash only pay attention to the elements in the list

22 int invokersHashCode =invokers.hashCode();23 ConsistentHashSelector selector = (ConsistentHashSelector) selectors.get(key);24 if (selector == null || selector.identityHashCode !=invokersHashCode) {25 selectors.put(key, new ConsistentHashSelector(invokers, methodName, invokersHashCode));26 selector = (ConsistentHashSelector) selectors.get(key);27 }28 //该给 ConsistentHashSelector 方法

29 returnselector.select(invocation);30 }31

32 private static final class ConsistentHashSelector{33

34 private final TreeMap>virtualInvokers;35

36 private final intreplicaNumber;37

38 private final intidentityHashCode;39

40 private final int[] argumentIndex;41

42 ConsistentHashSelector(List> invokers, String methodName, intidentityHashCode) {43 this.virtualInvokers = new TreeMap>();44 this.identityHashCode =identityHashCode;45 URL url = invokers.get(0).getUrl();46 this.replicaNumber = url.getMethodParameter(methodName, HASH_NODES, 160);47 String[] index = COMMA_SPLIT_PATTERN.split(url.getMethodParameter(methodName, HASH_ARGUMENTS, "0"));48 argumentIndex = new int[index.length];49 for (int i = 0; i < index.length; i++) {50 argumentIndex[i] =Integer.parseInt(index[i]);51 }52 //replicaNumber就是复制的节点,默认是 160 ,假如invokers 的数量是 5 ,那么总的节点数就是 5*160

53 for (Invokerinvoker : invokers) {54 String address =invoker.getUrl().getAddress();55 for (int i = 0; i < replicaNumber / 4; i++) {56 byte[] digest = md5(address +i);57 for (int h = 0; h < 4; h++) {58 long m =hash(digest, h);59 //virtualInvokers 是个 TreeMap

60 virtualInvokers.put(m, invoker);61 }62 }63 }64 }65

66 public Invokerselect(Invocation invocation) {67 String key =toKey(invocation.getArguments());68 byte[] digest =md5(key);69 return selectForKey(hash(digest, 0));70 }71

72 privateString toKey(Object[] args) {73 StringBuilder buf = newStringBuilder();74 for (inti : argumentIndex) {75 if (i >= 0 && i

82 private Invoker selectForKey(longhash) {83 //看这里!!调用 ceilingEntry 方法

84 Map.Entry> entry =virtualInvokers.ceilingEntry(hash);85 if (entry == null) {86 entry =virtualInvokers.firstEntry();87 }88 returnentry.getValue();89 }90

91 private long hash(byte[] digest, intnumber) {92 return (((long) (digest[3 + number * 4] & 0xFF) << 24)93 | ((long) (digest[2 + number * 4] & 0xFF) << 16)94 | ((long) (digest[1 + number * 4] & 0xFF) << 8)95 | (digest[number * 4] & 0xFF))96 & 0xFFFFFFFFL;97 }98

99 private byte[] md5(String value) {100 MessageDigest md5;101 try{102 md5 = MessageDigest.getInstance("MD5");103 } catch(NoSuchAlgorithmException e) {104 throw newIllegalStateException(e.getMessage(), e);105 }106 md5.reset();107 byte[] bytes =value.getBytes(StandardCharsets.UTF_8);108 md5.update(bytes);109 returnmd5.digest();110 }111

112 }113

114 }

上面使用了hash 算法 ,在和 https://github.com/RJ/ketama 该地址下看到的有点相似,这里我们只需要知道hash 的作用是使得使值均匀分布。

总结

通过本文了解了分布式哈希一致性相对与其他的负载均衡策略的优势。

参考资料

https://www.acodersjourney.com/system-design-interview-consistent-hashing/

https://www.cnblogs.com/jajian/p/10896624.html

mysql分布式一致性hash_分布式哈希一致性相关推荐

  1. mysql 一致性hash_韩信大招:一致性哈希

    ![封面,图片来源王者荣耀](https://img-blog.csdnimg.cn/img_convert/e5950a8e0eefebcc4632a728c520d256.png) 这是悟空的第 ...

  2. 一致 先验分布 后验分布_分布式事务常见解决方案与最终一致性

    小编推荐:互联网大背景下,微服务盛行,平时开发中难免会遇到分布式事务问题.大家经常会听到CAP原理,即一致性(Consistency).可用性(Availability).分区容错性(Partitio ...

  3. 数据库事务、分布式一致性和分布式事务

    文章目录 什么是事务 事务(ACID)的特性 对事务一致性的理解 分布式一致性 CAP BASE 分布式事务 本地事务 柔性事务和刚性事务 分布式一致性和分布式事务的理解 一致性协议 向量时钟 NWR ...

  4. 分布式理论和分布式一致性协议

    分布式理论 关键词 分布式,各副本中的数据是一致 强一致性/弱一致性(最终一致性) cap定理(P分区容错性:允许节点挂掉:对于分布式系统,是必须的) 互联网:AP (得能访问,偶尔没有一致性能接受) ...

  5. 一致 先验分布 后验分布_「分布式技术」分布式事务最终一致性解决方案,下篇...

    各位志同道合的朋友们大家好,我是一个一直在一线互联网踩坑十余年的编码爱好者,现在将我们的各种经验以及架构实战分享出来,如果大家喜欢,就关注我,一起将技术学深学透,我会每一篇分享结束都会预告下一专题 上 ...

  6. 分布式一致性协议三部曲-深入理解一致性协议Paxos

    在理解分析分布式一致性协议前,我们必须先看下CAP理论 CAP CAP是指在一个分布式系统中,一致性(Consistency).可用性(Availability).分区容错性(Partition to ...

  7. 【分布式】关于分布式“一致性”的讨论

    文章目录 一.写在前面的话 二.数据库的事务 三.分布式环境的各种问题 三.CAP和BASE理论 四.一致性协议 (1)两阶段提交 (2)三阶段提交 (3)Paxos算法 五.写在最后的话 一.写在前 ...

  8. [分布式]:关于分布式一致性的探究

    声明以下分布式系列的文章大多转自Hollis 随着大型网站的各种高并发访问.海量数据处理等场景越来越多,如何实现网站的高可用.易伸缩.可扩展.安全等目标就显得越来越重要.为了解决这样一系列问题,大型网 ...

  9. MySQL数据库主从同步的3种一致性方案实现,及优劣比较

    数据主从同步的由来 互联网的很多业务,特别是在高并发的场景下,基本都是读远远大于写,如果数据库读和写的压力都同在一台主机上,这显然不太合理. 于是,把一台数据库主机分为单独的一台写主库(主要负责写操作 ...

最新文章

  1. 解决django.db.utils.InternalError: (1049, Unknown database 'exam_db')
  2. ROS学习(十一):ROS URDF-model
  3. hdu6000 Wash 思维、贪心
  4. 打造“新基建”核心支柱 数据中心产业期待提速提质
  5. 【机器学习基础】(五):通俗易懂决策树与随机森林及代码实践
  6. jquery之ajax请求工具类
  7. linux 日志切割 自带,[日志分割回滚] 使用linux自带的logrotate对nginx日志进行分割...
  8. 用ANSYS画矩形_用SolidWorks画一个带波浪纹路的瓶子
  9. 平庸程序员的成长笔记
  10. 高效的敏捷测试第十三课 自动化测试、用例测试、接口测试、大数据测试
  11. 电脑蓝牙耳机无法调节用关闭绝对音量来解决
  12. 阿里巴巴、腾讯投资Barefoot,助力C轮融资8000万美元
  13. 阿里云如何提供接口 生成api?
  14. 20P37 Premiere预设200种文字标题介绍动画合集包 200 Titles Collection下载
  15. CAD绘制二维码(网页版)
  16. vue3中导出excel表格
  17. 王慧文清华产品课(一)
  18. 计算机在材料化学中的应用论文,【多媒体技术论文】网络多媒体技术在材料化学中的应用(共2815字)...
  19. 有道 - 词典在线发音API链接(日语)
  20. 服务器一键部署可道云KODBOX网盘云盘

热门文章

  1. MySQL操作权限整理
  2. 5、jeecg 笔记之 minidao 条件判断
  3. 公司网页添加旺旺,状态不正确
  4. Android 获取经纬度,地理位置,省市区
  5. codeblocks如何导入项目_T3如何利用系统工具导入导出复制存货档案
  6. div添加html链接,DIV添加超链接小记
  7. linux如何记录测试时长,如何测试Linux命令运行时间?
  8. ubuntu mysql混合开发_mysql5.7主从同步 ubuntu
  9. (三)ElasticSearch的基本概念
  10. java spring druid_Spring配置Druid连接池