C++实现一个简单的一致性hash

原理不解释了,网上都有。
实现要点:

  • 保持虚拟节点和物理节点的映射关系
  • 数据 hash 之后落在hash 环顺时针遇到的第一个节点上面
#include <bits/stdc++.h>

using namespace  std;

class ConsistentHash{
private:
    unordered_set<string> physicalServer; // 真实的物理机器
    map<std::size_t , string> serverNodes; // hash 值和节点ip映射(真实ip)
    int virtualNodeNum;
    hash<string> hashStr; // 自带的 hash 函数
public:
    ConsistentHash(int vnum):virtualNodeNum(vnum){};
    void addNode(const string& ip){
        physicalServer.insert(ip);
        // 加入物理节点的时候也加入虚拟节点
        for(int i=0;i<virtualNodeNum;++i){
            stringstream key;
            key<<ip<<"#"<<i;
            serverNodes.insert({hashStr(key.str()),ip});
        }
    }
    void delNode(const string &ip){
        physicalServer.erase(ip);
        for(int i=0;i<virtualNodeNum;++i){
            stringstream key;
            key<<ip<<"#"<<i;
            serverNodes.erase(hashStr(key.str()));
        }
    }
    // 模拟插入整数到 hash string
    string virtualInsert(int data){
        stringstream key;
        key<<data;
        size_t hashKey=hashStr(key.str());
        auto iter=serverNodes.lower_bound(hashKey);
        if(iter==serverNodes.end()){
            return serverNodes.begin()->second;
        }
        return iter->second;
    }
};
int main(){
    ConsistentHash hash(10);
    hash.addNode("127.0.0.1");
    hash.addNode("127.0.0.2");
    hash.addNode("127.0.0.3");
    map<string,int> stats;
    for(int i=0;i<1000;++i){
        stats[hash.virtualInsert(i)]++;
    }
    for(auto &s:stats){
        cout<< s.first <<" "<<setprecision(2)<< s.second/(1000*1.0)<<endl;
    }
    return 0;
}

结果如下:

127.0.0.1 0.26
127.0.0.2 0.31
127.0.0.3 0.43

结果看数据落盘还是比价均衡

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容