• 一致性哈希


    一致性哈希在分布式系统中被很多的使用,比如说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是为了查找是能够使用二分查找快速找到一个适合的节点。
  • 相关阅读:
    禁用LinkButton的方法
    Windows Server2008R2中导入Excel
    Viewport
    Firefox模拟手机访问手机网站
    关闭ReSharper中的[ Use 'var' ]提示(Disable C# “var” Recommendation in ReSharper)
    浏览器中如何获取想要的offsetwidth、、、clientwidth、、offsetheight、、、clientheight。。。
    JS中关于clientWidth offsetWidth scrollWidth 等的含义的详细介绍
    base64编码解码js
    scrollTop如何实现click后页面过渡滚动到顶部
    如何快速获取当前链接?后面的内容,location.search、页面滚动
  • 原文地址:https://www.cnblogs.com/songyanlei/p/3861060.html
Copyright © 2020-2023  润新知