zoukankan      html  css  js  c++  java
  • 一致性哈希

    一致性哈希在分布式系统中被很多的使用,比如说memcached就是使用一致性哈希来做的。学习一下这个一致性哈希算法。

    下面这篇博客利用图解的形式,将一致性哈希算法讲述的非常清楚:

    博客:http://blog.codinglabs.org/articles/consistent-hashing.html

    参考代码,下面我列出了java和c#的两个代码实现,可以通过读代码更深刻的去理解一下这个算法。 代码:

    根据上述文章和代码,仿照着写了一个粗略版本的一致性哈希算法。

    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是为了查找是能够使用二分查找快速找到一个适合的节点。
  • 相关阅读:
    ① ts基础
    ⑦ 原型和原型链 作用域链
    ④ 小程序使用分包
    功能⑦ 小程序整合高德地图定位
    effective OC2.0 52阅读笔记(三 接口与API设计)
    effective OC2.0 52阅读笔记(二 对象、消息、运行期)
    effective OC2.0 52阅读笔记(一 熟悉Objective-C)
    perl的Getopt::Long和pod::usage ?
    安装你自己的perl modules
    Perl 之 use(), require(), do(), %INC and @INC
  • 原文地址:https://www.cnblogs.com/songyanlei/p/3861060.html
Copyright © 2011-2022 走看看