zoukankan      html  css  js  c++  java
  • .net的一致性哈希实现

    最近在项目的微服务架构推进过程中,一个新的服务需要动态伸缩的弹性部署,所有容器化示例组成一个大的工作集群,以分布式处理的方式来完成一项工作,在集群中所有节点的任务分配过程中,由于集群工作节点需要动态增减,因此需要利用etcd(或zk)来管理集群,同时用一致性哈希算法来定位每个工作项的具体工作节点,一致性哈希算法的实现(.NET)为如下地址:

    https://github.com/cerasumat/ConsistentHash/tree/develop

    算法的原理不再赘述,用baidu都能够在第一页直接检索到,原理很简单,这个实现中哈希空间只有2^32-1,已经能够满足我的业务场景(只处理最近某一段时长的对象实体,这个空间已够用)。源码也很简单,结合原理中那个桶的图示,一看就明白。

    简单说说用法:

    1:以物理节点初始化哈希路由器

    PhysicalNode node1 = new PhysicalNode("SituationAnalysis", "10.202.1.1", 80);
    PhysicalNode node2 = new PhysicalNode("SituationAnalysis", "10.202.1.2", 80);
    PhysicalNode node3 = new PhysicalNode("SituationAnalysis", "10.202.1.3", 80);
    var pNodes = new List<PhysicalNode>();
    pNodes.Add(node1);
    pNodes.Add(node2);
    pNodes.Add(node3);
    var router = new Router(pNodes, 3);

    初始化得到一个物理节点*虚拟副本数的虚拟节点集群,分布在哈希环上

    2:以该路由器提供的GetNode方法,对目标资源进行哈希路由

    int count85 = 0;
    int count86 = 0;
    int count87 = 0;
    
    Stopwatch sw = new Stopwatch();
    sw.Start();
    for (int i = 1; i < 100000; i++)
    {
        var dataKey = string.Format("SA-20161115-Issue232-{0}", i.ToString().PadLeft(5, '0'));
        var node = router.GetNode(dataKey);
        switch (node.Ip)
        {
            case "10.202.1.1":
                Interlocked.Increment(ref count85);
                break;
            case "10.202.1.2":
                Interlocked.Increment(ref count86);
                break;
            case "10.202.1.3":
                Interlocked.Increment(ref count87);
                break;
        }
    }
    sw.Stop();
    TimeSpan elapse = sw.Elapsed;
    int total = count85 + count86 + count87;
    Assert.IsTrue(total == 99999);

    上述代码只是UT代码中的片段,主要测试用第1步获取的router对99999个key进行哈希定位的耗时(在我笔记本上500ms左右)以及目标keys是否无遗漏地分布到每个节点。

    3:集群动态伸缩

    IRouter提供了集群伸缩的接口(AddNode,RemoveNode)等,可供使用过程中集群动态伸缩需求使用(可以考虑采取监控etcd或zookeeper中集群信息的方式来实时更新当前集群信息,达到动态伸缩的目的,具体实现这篇帖子不再表述)

    以上就是一致性哈希算法的一个简单实现,可根据实际需求引入项目使用,适用于分布式处理的场景。

  • 相关阅读:
    [转]用异或交换两个整数的陷阱
    线索化二叉树
    [转]Socket编程中,阻塞与非阻塞的区别
    两个链表的归并
    [转] std::string and stl 算法
    类图
    leetcode 答案
    about raw socket
    54. Spiral Matrix【数组】
    矩阵乘法问题的实现
  • 原文地址:https://www.cnblogs.com/you-you-111/p/6068937.html
Copyright © 2011-2022 走看看