一致性哈希底层实现

一致性哈希的原理我就不总结了,一搜一大把!那我们就来分析一段简单的代码吧!
一、下面这段代码是在主函数中调用,产生hash对象,初始化hash函数。并生成真实服务器的节点,最终将真实节点及其对应的虚拟节点插入红黑树中。

    /*定义hash函数*/
    CHashFun * func = new CMD5HashFun();//图1
    /*创建一致性hash对象*/
    CConHash * conhash = new CConHash(func);//图2

    /*定义CNode*/
    CNode_s * node1 = new CNode_s("machineA",50,"10.3.0.201");//图3
    CNode_s * node2 = new CNode_s("machineB",80,"10.3.0.202");
    CNode_s * node3 = new CNode_s("machineC",20,"10.3.0.203");
    CNode_s * node4 = new CNode_s("machineD",100,"10.3.0.204");

    conhash->addNode_s(node1);
    conhash->addNode_s(node2);
    conhash->addNode_s(node3);
    conhash->addNode_s(node4);

<1>定义hash函数的节点:
图1:
一致性哈希底层实现_第1张图片
<2>创建一致性hash对象
图2:
一致性哈希底层实现_第2张图片
<3>生成真是服务器节点
图3:
一致性哈希底层实现_第3张图片
<4>接下来将真实节点产生的虚拟节点添加到conhash对应的红黑树中
图4:虚拟节点和真实节点的对应关系
一致性哈希底层实现_第4张图片
图5:红黑树节点
一致性哈希底层实现_第5张图片
重点看一下CConHash的成员函数addNode_s(),根据真实节点CNode_s中的虚拟节点个数来生成虚拟节点,根据真实服务器的名字后面加上i的值,生成hash值,根据hash值,在红黑树种查找,看是否存在key,如果存在,就不进行插入,如果不存在,生成红黑树节点,然后进行插入。
注意:这里只是插入真实节点对应的虚拟节点

int CConHash::addNode_s(CNode_s * pNode)
{
    if(pNode==NULL) return -1;
    int vCount = pNode->getVNodeCount();
    if(vCount<=0) return -1;
    CVirtualNode_s * virtualNode ;
    util_rbtree_node_t * rbNode;
    char str [1000];
    char num[10];
    strcpy(str,pNode->getIden());
    long hash = 0;
    /*生成虚拟结点并插入到红黑树中*/
    for(int i=0;inew CVirtualNode_s(pNode);
        /*采用str+“i”的方法产生不同的iden串,用于后面的hash值计算*/
        itoa(i,num,10);
        strcat(str,num);
        hash = func->getHashVal(str);
        virtualNode->setHash(hash);
        if(!util_rbtree_search(vnode_tree,hash))
        {
            /*生成红黑树结点*/
            rbNode = vNode2RBNode(virtualNode); 
            if(rbNode!=NULL)
            {
                /*将该结点插入到红黑树中*/
                util_rbtree_insert(vnode_tree,rbNode);
                this->vNodes++;
            }
        }
    }
    return 0;
}

对于删除节点,也只是删除虚拟节点。
没错,通过这么一段源码剖析,一致性哈希的底层实现是红黑树,并不是从字面理解中的哈希函数。
二、普通哈希函数与一致性哈希函数的比较
普通hash函数,每一个桶对应的都是一台真实的服务器,当客户端来请求以后,通过hash函数将客户端的请求映射到桶中,那么对应的桶的服务器就去处理客户端的请求;
一致性哈希底层实现_第6张图片
那么接下来,当3号服务器宕机了,那么桶的个数变了,hash函数的%的值就变了,接下来会变成这个样子:
一致性哈希底层实现_第7张图片
对于以上的例子,对于同一客户端的请求,全部的数据都发生了迁移,所以,这就是对于一致性哈希,一致性哈希会降低数据的迁移。
三、一致性哈希函数的特点
<1>平衡性
通过引入虚节点,降低了数据的迁移;
<2>单调性
当某一台主机宕机以后,通过顺时针找到下一台主机,处理客户端的请求,这样只是造成部分数据发生了迁移。

你可能感兴趣的:(算法)