.net的一致性哈希实现

时间:2023-03-10 04:58:00
.net的一致性哈希实现

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

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

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

简单说说用法:

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

PhysicalNode node1 = );
PhysicalNode node2 = );
PhysicalNode node3 = );
var pNodes = new List<PhysicalNode>();
pNodes.Add(node1);
pNodes.Add(node2);
pNodes.Add(node3);
var router = new Router(pNodes, 3);

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

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

;
;
;

Stopwatch sw = new Stopwatch();
sw.Start();
; i < ; i++)
{
    , '));
    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 == );

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

3:集群动态伸缩

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

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