原理不解释了,网上都有。
实现要点:
- 保持虚拟节点和物理节点的映射关系
- 数据 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
结果看数据落盘还是比价均衡
网友评论