一致性哈希学习
一致性哈希在分布式系统中被很多的使用,比如说memcached就是使用一致性哈希来做的。学习一下这个一致性哈希算法。
下面这篇博客利用图解的形式,将一致性哈希算法讲述的非常清楚:
博客:http://blog.codinglabs.org/articles/consistent-hashing.html
参考代码,下面我列出了java和c#的两个代码实现,可以通过读代码更深刻的去理解一下这个算法。 代码:
- https://code.google.com/p/consistent-hash/
- https://weblogs.java.net/blog/2007/11/27/consistent-hashing
根据上述文章和代码,仿照着写了一个粗略版本的一致性哈希算法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | public delegate int HashFunction( string val); public class ConsistentHash<T> where T : class { //this value used for generate virtual nodes private int _replica; //Hash fuction used to calculate hash code base on a string private HashFunction getHashCode; //image this as a big circle which store the node private SortedDictionary< int , T> circle = new SortedDictionary< int , T>(); public ConsistentHash(HashFunction hashFunc, ICollection<T> nodes, int replicaNum = 100) { _replica = replicaNum; getHashCode = hashFunc; Init(nodes); } public void Add(T node) { for ( int i = 0; i < _replica; i++) { int hash = getHashCode(node.GetHashCode().ToString() + i); circle[hash] = node; } } public void Remove(T node) { for ( int i = 0; i < _replica; i++) { int hash = getHashCode(node.GetHashCode().ToString() + i); circle.Remove(hash); } } public T GetNode( object key) { if (key == null ) return null ; int hashcode = getHashCode(key.GetHashCode().ToString()); int firstNode = GetFirst(circle.Keys.ToArray() , hashcode); return circle[firstNode]; } /// <summary> /// use binary search to search the first value in keys array /// which bigger than hashcode /// if not exist return first key in keys array /// </summary> /// <param name="keys">key array</param> /// <param name="hashcode"></param> /// <returns></returns> private int GetFirst( int [] keys, int hashcode) { int beg = 0, end = keys.Length - 1; circle.Keys.CopyTo(keys, keys.Length); if (hashcode < keys[beg] || hashcode > keys[end]) return keys[0]; while (end > beg) { int mid = (end + beg) / 2; if (keys[mid] >= hashcode) end = mid; else beg = mid; } return keys[end]; } private void Init(ICollection<T> nodes) { foreach (T node in nodes) { Add(node); } } } |
- 没有使用那个默认的Hash code,因为默认的哈希实现可能不够好。最好能够使用自己可以控制的一个好的哈希算法。
- _replica变量就是每一个结点对应的虚拟节点的个数。虚拟节点是为了解决数据倾斜的问题,也就是说节点分布的不够均匀导致最后分配到每一个节点上的负载不均衡。理论上来说如果实际节点越少,则需要的虚拟节点越多。
- 使用SortedDictionary是为了查找是能够使用二分查找快速找到一个适合的节点。
更多参考资料:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· SQL Server 2025 AI相关能力初探
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库