架构师训练营 Week 05 作业
发布于: 2020 年 07 月 06 日
1 一致性散列的实现
namespace ConsistenHashing
{
class HashRing
{
public:
void addNode(const std::string &nodeKey, int virtualNums)
{
for (int i = 0; i < virtualNums; i++)
{
nodeMap.emplace(getHash(nodeKey + std::to_string(i)), nodeKey);
}
}
void removeNode(const std::string &nodeKey)
{
auto finder = [&](decltype(nodeMap)::const_reference pair) { return nodeKey == pair.second; };
for (auto it = nodeMap.begin(); (it = std::find_if(it, nodeMap.end(), finder)) != nodeMap.end(); ++it)
{
nodeMap.erase(it);
}
}
std::string getNode(const std::string &nodeKey)
{
if (nodeMap.empty())
return "";
auto greater = nodeMap.upper_bound(getHash(nodeKey));
if (nodeMap.end() != greater)
{
return greater->second;
}
else
{
return nodeMap.begin()->second;
}
}
private:
static uint32_t getHash(const std::string &key)
{
std::size_t hash = std::hash<std::string>{}(key);
return static_cast<uint32_t>(hash % 0xffff'ffff);
}
std::map<uint32_t, std::string> nodeMap;
};
} // namespace ConsistenHashing
复制代码
2 测试用例
100 万 KV 数据,10 个服务器节点的情况下,KV 数据在服务器的分布标准差。所模拟的 KV 数据,使用随机数作为键值。
using namespace std;
using namespace ConsistenHashing;
int main(int argc, char **argv)
{
// Host IPs
vector<string> nodeList{
"192.168.100.101",
"192.168.100.102",
"192.168.100.103",
"192.168.100.104",
"192.168.100.105",
"192.168.100.106",
"192.168.100.107",
"192.168.100.108",
"192.168.100.109",
"192.168.100.110"};
// Create a hash ring
HashRing hashRing;
for (auto &node : nodeList)
{
hashRing.addNode(node, 200);
}
//
map<string, int> counting;
for (auto &node : nodeList)
{
counting.emplace(node, 0);
}
// Hitting test
for (int i = 0; i < 1000'000; i++)
{
string dataKey = to_string(random());
string nodeKey = hashRing.getNode(dataKey);
auto hittedItem = counting.find(nodeKey);
hittedItem->second++;
}
// Calculate standard deviation
double sum = 0;
for_each(counting.begin(), counting.end(), [&](decltype(counting)::const_reference item) { sum += item.second; });
double mean = sum / counting.size();
double variance = 0.;
for_each(counting.begin(), counting.end(), [&](decltype(counting)::const_reference item) { variance += pow(item.second - mean, 2.); });
variance = variance / counting.size();
double standardDeviation = sqrt(variance);
// Output results
for (auto &item : counting)
{
cout << item.first << ", hits: " << item.second << endl;
}
cout << "Standard deviation: " << standardDeviation << endl;
return 0;
}
复制代码
3 运行结果
192.168.100.101, hits: 99253
192.168.100.102, hits: 90910
192.168.100.103, hits: 124879
192.168.100.104, hits: 99950
192.168.100.105, hits: 108481
192.168.100.106, hits: 91469
192.168.100.107, hits: 82288
192.168.100.108, hits: 102209
192.168.100.109, hits: 103421
192.168.100.110, hits: 97140
Standard deviation: 10887.3
复制代码
划线
评论
复制
发布于: 2020 年 07 月 06 日阅读数: 56
Wancho
关注
还未添加个人签名 2020.02.28 加入
还未添加个人简介
评论