一致性 Hash 算法的实际应用(上)

简介: 分享过一篇《一致性 Hash 算法分析》,当时只是分析了这个算法的实现原理、解决了什么问题等。但没有实际实现一个这样的算法,本次就当前的一个路由需求来着手实现一次。

背景


看过《为自己搭建一个分布式 IM(即时通讯) 系统》的朋友应该对其中的登录逻辑有所印象。


先给新来的朋友简单介绍下 cim 是干啥的:



其中有一个场景是在客户端登录成功后需要从可用的服务端列表中选择一台服务节点返回给客户端使用。


而这个选择的过程就是一个负载策略的过程;第一版本做的比较简单,默认只支持轮询的方式。


虽然够用,但不够优雅😏。


因此我的规划是内置多种路由策略供使用者根据自己的场景选择,同时提供简单的 API 供用户自定义自己的路由策略。


先来看看一致性 Hash 算法的一些特点:


  • 构造一个 0 ~ 2^32-1 大小的环。


  • 服务节点经过 hash 之后将自身存放到环中的下标中。


  • 客户端根据自身的某些数据 hash 之后也定位到这个环中。


  • 通过顺时针找到离他最近的一个节点,也就是这次路由的服务节点。


  • 考虑到服务节点的个数以及 hash 算法的问题导致环中的数据分布不均匀时引入了虚拟节点。



自定义有序 Map


根据这些客观条件我们很容易想到通过自定义一个有序数组来模拟这个环。


这样我们的流程如下:


  1. 初始化一个长度为 N 的数组。


  1. 将服务节点通过 hash 算法得到的正整数,同时将节点自身的数据(hashcode、ip、端口等)存放在这里。


  1. 完成节点存放后将整个数组进行排序(排序算法有多种)。


  1. 客户端获取路由节点时,将自身进行 hash 也得到一个正整数;


  1. 遍历这个数组直到找到一个数据大于等于当前客户端的 hash 值,就将当前节点作为该客户端所路由的节点。


  1. 如果没有发现比客户端大的数据就返回第一个节点(满足环的特性)。


先不考虑排序所消耗的时间,单看这个路由的时间复杂度:


  • 最好是第一次就找到,时间复杂度为O(1)


  • 最差为遍历完数组后才找到,时间复杂度为O(N)


理论讲完了来看看具体实践。


我自定义了一个类:SortArrayMap


他的使用方法及结果如下:



可见最终会按照 key 的大小进行排序,同时传入 hashcode = 101 时会按照顺时针找到 hashcode = 1000 这个节点进行返回。


下面来看看具体的实现。


成员变量和构造函数如下:



其中最核心的就是一个 Node 数组,用它来存放服务节点的 hashcode 以及 value 值。


其中的内部类 Node 结构如下:



写入数据的方法如下:



相信看过 ArrayList 的源码应该有印象,这里的写入逻辑和它很像。


  • 写入之前判断是否需要扩容,如果需要则复制原来大小的 1.5 倍数组来存放数据。


  • 之后就写入数组,同时数组大小 +1。


但是存放时是按照写入顺序存放的,遍历时自然不会有序;因此提供了一个 Sort 方法,可以把其中的数据按照 key 其实也就是 hashcode 进行排序。



排序也比较简单,使用了 Arrays 这个数组工具进行排序,它其实是使用了一个 TimSort 的排序算法,效率还是比较高的。


最后则需要按照一致性 Hash 的标准顺时针查找对应的节点:



代码还是比较简单清晰的;遍历数组如果找到比当前 key 大的就返回,没有查到就取第一个。


这样就基本实现了一致性 Hash 的要求。


ps:这里并不包含具体的 hash 方法以及虚拟节点等功能(具体实现请看下文),这个可以由使用者来定,SortArrayMap 可作为一个底层的数据结构,提供有序 Map 的能力,使用场景也不局限于一致性 Hash 算法中。


相关文章
|
21天前
|
机器学习/深度学习 人工智能 算法
探索人工智能中的强化学习:原理、算法与应用
探索人工智能中的强化学习:原理、算法与应用
|
20天前
|
机器学习/深度学习 算法 数据挖掘
C语言在机器学习中的应用及其重要性。C语言以其高效性、灵活性和可移植性,适合开发高性能的机器学习算法,尤其在底层算法实现、嵌入式系统和高性能计算中表现突出
本文探讨了C语言在机器学习中的应用及其重要性。C语言以其高效性、灵活性和可移植性,适合开发高性能的机器学习算法,尤其在底层算法实现、嵌入式系统和高性能计算中表现突出。文章还介绍了C语言在知名机器学习库中的作用,以及与Python等语言结合使用的案例,展望了其未来发展的挑战与机遇。
39 1
|
20天前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
49 1
|
1月前
|
缓存 算法 网络协议
OSPF的路由计算算法:原理与应用
OSPF的路由计算算法:原理与应用
42 4
|
27天前
|
机器学习/深度学习 监控 算法
基于反光衣和检测算法的应用探索
本文探讨了利用机器学习和计算机视觉技术进行反光衣检测的方法,涵盖图像预处理、目标检测与分类、特征提取等关键技术。通过YOLOv5等模型的训练与优化,展示了实现高效反光衣识别的完整流程,旨在提升智能检测系统的性能,应用于交通安全、工地监控等领域。
|
1月前
|
存储 算法 网络协议
OSPF的SPF算法介绍:原理、实现与应用
OSPF的SPF算法介绍:原理、实现与应用
76 3
|
1月前
|
机器学习/深度学习 JSON 算法
二叉树遍历算法的应用场景有哪些?
【10月更文挑战第29天】二叉树遍历算法作为一种基础而重要的算法,在许多领域都有着不可或缺的应用,它为解决各种复杂的问题提供了有效的手段和思路。随着计算机科学的不断发展,二叉树遍历算法也在不断地被优化和扩展,以适应新的应用场景和需求。
40 0
|
21天前
|
机器学习/深度学习 人工智能 算法
探索人工智能中的强化学习:原理、算法及应用
探索人工智能中的强化学习:原理、算法及应用
|
2月前
|
存储 算法 搜索推荐
这些算法在实际应用中有哪些具体案例呢
【10月更文挑战第19天】这些算法在实际应用中有哪些具体案例呢
53 1
|
2月前
|
监控 算法 数据挖掘
HyperLogLog算法有哪些应用场景呢
【10月更文挑战第19天】HyperLogLog算法有哪些应用场景呢
21 0
下一篇
DataWorks