15

我一整天都在尝试用 PHP 理解 Memcache 并编写代码,但我在某些方面感到困惑。我浏览了很多文章,几乎所有与此相关的 SO 问题,但找不到确切的答案

1) 在 PHP 中创建一致散列密钥的代码是什么?我必须安装哪些库以及我真正需要做什么?有什么好文章可以看吗?

2)假设,我已经成功存储了一个一致的散列密钥,现在如果我的任何服务器关闭或添加了一个新服务器,即使我使用的是一致的散列密钥等也会有什么不同吗?

3)如果在http://ru.php.net/manual/en/memcached.addserver.php中所述的一致哈希的情况下,使用 Memcached::addServers() 而不是 Memcached::addServer() 会产生任何影响不是那是什么意思?

$m = new Memcached();
$m->setOption(Memcached::OPT_DISTRIBUTION, Memcached::DISTRIBUTION_CONSISTENT);
$m->addServers($servers);

4) 使用上述代码是否足以进行一致哈希,然后添加/删除服务器不会对密钥产生任何影响?

5) 什么是 Ketama 图书馆?如果 Memcached::DISTRIBUTION_CONSISTENT 可以更好地工作,为什么要使用它?以下http://www.last.fm/user/RJ/journal/2007/04/10/rz_libketama_-_a_consistent_hashing_algo_for_memcache_clients

6) 我是否必须以某种方式对我的密钥进行哈希处理,或者只提供我的密钥并让 Memcached 处理其余的?

请各位,我需要你们的真正支持,以便尽快了解并实施我的生产环境。你的回答会让我明白我应该更好地编码什么。

4

2 回答 2

18

好吧,这些问题很多,一次让我尽力一一回答。

1) 在 PHP 中创建一致散列密钥的代码是什么?我必须安装哪些库以及我真正需要做什么?有什么好文章可以看吗?

好吧,当您对代码提出质疑时,此代码足以用于 PHP 中的一致性哈希。您只需要使用您的 LibMemcached 客户端库即可将一致散列与 Memcached 结合使用。只需在您的代码下方添加以下行

$m->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE, true);

如果您想使用一致的散列,强烈建议启用此选项,并且可能会在未来的版本中默认启用。请按照此获取一堆常量及其定义,以便更好地理解http://www.php.net/manual/en/memcached.constants.php

虽然更好的方法可以通过在 php.ini 中全局设置来获得更好的性能(我还没有测试过。)

memcache.hash_strategy = consistent;

正如http://blog.fedecarg.com/2008/12/24/memcached-consistent-hashing-mechanism/中所建议的那样,您无需在每个 memcached 调用中单独指定。默认值为标准,使用模数计算,如果您添加或删除服务器,这将无济于事。

2)假设,我已经成功存储了一个一致的散列密钥,现在如果我的任何服务器关闭或添加了一个新服务器,即使我使用的是一致的散列密钥等也会有什么不同吗?

尽管正如 lsmooth 所说,删除或添加服务器时总会产生影响,但假设将 1 台服务器添加到 3 台服务器中,这将是大约 1/4 = 25% 的密钥丢失,因此服务器数量越多,丢失密钥的机会就越少.

3)如果在http://ru.php.net/manual/en/memcached.addserver.php中所述的一致哈希的情况下,使用 Memcached::addServers() 而不是 Memcached::addServer() 会产生任何影响不是那是什么意思?

正如伊斯穆斯所说。他是对的。最好使用 addServers。请注意,必须在使用 setOption 设置所有选项后调用 «addServers()»,否则这些选项将不适用于这些服务器。

4) 使用上述代码是否足以进行一致哈希,然后添加/删除服务器不会对密钥产生任何影响?

已在问题 1 中回答。

5) 什么是 Ketama 图书馆?如果 Memcached::DISTRIBUTION_CONSISTENT 可以更好地工作,为什么要使用它?http://www.last.fm/user/RJ/journal/2007/04/10/rz_libketama_-_a_consistent_hashing_algo_for_memcache_clients

LibKetama 是 Consistent Hashing 密钥分发算法所基于的库。因此,在 Memcached 中使用一致哈希意味着使用 LibKetama,这就是它的本质。

6) 我是否必须以某种方式对我的密钥进行哈希处理,或者只提供我的密钥并让 Memcached 处理其余的?

Yvan 说“Memcached 客户端会自动对您的密钥进行哈希处理。假设您有 3 个服务器,A、B 和 C 以及 3 个密钥 «K1» 到 «K9»。例如,客户端哈希算法将存储如下:K1/K2 /K3 存储在 A 上,K4/K5/K6 存储在 B 上,K7/K8/K9 存储在 C 上。如果您的服务器 B 出现故障,其密钥 (K4/K5/K6) 将均匀存储在剩余的 2 台服务器上( A 和 C). 例如,K4 会去 A,K5/K6 会去服务器 C。

这只是一个例子,不是真正的算法。您可以使用函数 $memcached->getServerByKey('K4') 找出哪个密钥在哪个服务器上。然后让一台服务器宕机,看看 getServerByKey() 在此失败后向您发送什么”。在http://www.dugwood.com/895442.html#dwCmtForm

于 2014-01-01T10:49:30.180 回答
8

PHP 的 memcached 扩展支持一致性哈希。除了在您的代码中使用它,您无需执行任何操作,如下所示:

<?php
  $servers = array(
    array('memcache1.example.com', 11211),
    array('memcache2.example.com', 11211)
    );
  $m = new Memcached();
  $m->setOption(Memcached::OPT_DISTRIBUTION, Memcached::DISTRIBUTION_CONSISTENT);
  $m->addServers($servers);
?>

然后,当您开始将项目添加到缓存时,扩展程序会自动将它们分发到服务器,以便在您添加服务器时最大限度地减少缓存损失。如果它无法从它应该在的服务器中检索项目 - 例如因为服务器已关闭 - 你将不得不自己在你的 php 代码中处理它。

使用 addServers 而不是 addServer 对一致性哈希没有任何影响。如文档中所述,您应该在添加多个服务器时使用 addServers,以便内部数据结构只更新一次。

PHP 的 Consistent Hashing 实现基于libketama,它根本不需要 libketama。该扩展负责为您将项目分发到不同的服务器,以便最大限度地减少缓存损失。删除或添加服务器时总会产生影响。

于 2014-01-01T02:06:33.650 回答