一个很好的重新分区算法

时间:2010-06-21 09:03:39

标签: c++ algorithm memcached

我正在实施一个memcached客户端库。我希望它支持多个服务器,所以我希望添加一些负载平衡系统。

基本上,您可以在服务器上执行两项操作:

  • 存储value给定key
  • 获取value给予key

我们说我有N台服务器(从0N - 1),我想要一个重新分区功能 key和服务器号N会在index范围内给我[0, N[

unsigned int getServerIndex(const std::string& key, unsigned int serverCount);

该功能应尽可能快速和简单,并且必须遵守以下约束:

getServerIndex(key, N) == getServerIndex(key, N); //aka. No random return.

我希望我可以使用外部库(例如OpenSSL及其散列函数) 。我有什么选择?


旁注:

显然,基本实现:

unsigned int getServerIndex(const std::string& key, unsigned int serverCount)
{
  return 0;
}

不是一个有效的答案,因为这不是一个好的重新分区功能:D


其他信息:

Keys通常是ANSI charset中的任何可能的字符串(主要是[a-zA-Z0-9_-])。大小可以是从一个字符键到任何你想要的大小。

良好重新分区算法是一种算法,对于两种不同,返回a的概率与返回b的概率相等(或不太远)键。服务器的数量可能会发生变化(很少),如果确实如此,那么给定key的返回索引也会发生变化。

3 个答案:

答案 0 :(得分:3)

你可能正在寻找实现consistent hashing的东西。最简单的方法是为每个内存缓存服务器分配一个随机ID,并按照某个指标将每个项目分配给与项目哈希值最接近的ID的内存缓存服务器。

这个的常见选择 - 以及Kademlia等分布式系统采用的方法 - 将使用SHA1哈希函数(尽管哈希不重要),并通过对哈希值进行异或来比较距离item与服务器的哈希值并将结果解释为一个量级。因此,您只需要让每个客户端都知道内存缓存服务器及其ID的列表。

当一个memcache服务器加入或离开时,它只需要生成自己的随机ID,然后让它的新邻居向它发送任何更接近其哈希的项目而不是它们自己的项目。

答案 1 :(得分:1)

我认为哈希方法是正确的想法。那里有许多简单的哈希算法。

随着即将推出的C ++ 0x和新标准unordered_maphash字符串正在成为标准操作。许多编译器已经提供了STL版本,其版本为hash_map,因此已经预先实现了hash功能。

我会从那些开始...但是如果我们有更多关于你的字符串的信息会更好:它们是否被限制在一个有限的字符集中,或者它们可能是很多相似的字符串?

问题是如果输入不是均匀分布的话,“标准”哈希可能不会产生统一分布......

修改

鉴于这些信息,我认为大多数STL已经附带的哈希函数应该可以工作,因为你似乎没有高度集中的区域。然而,我现在已经成为概率方面的专家,所以请耐心等待(和实验)。

答案 2 :(得分:0)

这样非常简单的事情
hash(key) % serverCount