Memcached for PHP和故障转移

Eve*_*ert 13 php memcached

我们正在为我们的应用程序部署memcached,我想尽可能地让它变得耐用.

我们计划使用更新的memcacheD扩展.

我还没有想到的一件事是,如果其中一台服务器死机会发生什么.至少看起来memcached客户端只是'放弃'在该服务器上,并且不存储任何内容.

这个行为我很好.我们可以处理一堆缓存未命中.然而,在其中一个服务器被视为"失败"后,后续集合并被重新分配给剩余的服务器将是很好的.

因为这似乎不会自动发生; 我想解决这个问题的唯一方法是让外部系统对memcached系统进行健康检查,并适当更新服务器列表.

但是如果有一个包含10个服务器的列表,并且让我们说,第5个死了......即使使用Ketama-hashing,这似乎会触发重新分配密钥(这只是基于常识).

所以理想情况下,我只想简单地看一下服务器关闭的PHP扩展,将其标记为指定的时间(10分钟),并在这10分钟内回退到其他服务器(很好地分布)的集合和获取.

别人怎么解决这个问题?

编辑:澄清我的libketama点.

假设我们有10台服务器:

1,2,3,4,5,6,7,8,9,10
Run Code Online (Sandbox Code Playgroud)

其中一人死亡.然后,Libketama将提供一个非常高的可能性,即丢失的服务器的命中率平均分配给剩余的服务器:

1,2,3,4,inactive,6,7,8,9,10
Run Code Online (Sandbox Code Playgroud)

但是:如果我们手动提供和管理此列表,则情况并非如此:

1,2,3,4,6,7,8,9,10 // There are now 9 servers!
Run Code Online (Sandbox Code Playgroud)

6现在将获得5个以前的密钥,7个将获得6个.8将获得7,9将获得8,10将获得9.第10台服务器过去获得的所有命中都不会均匀分布在其余服务器中.导致几乎50%的密钥被发送到新服务器的可能性很高.

pre*_*mer 3

我通常将可用服务器列表存储在 APC 中,这样我就可以即时修改它。您是对的,系统将尝试在列出的同时继续使用已关闭的服务器,幸运的是,使用新的哈希方法将其从轮换中拉出并不是什么大问题。

\n\n

我会避免使用全新的 PHP 扩展,或尝试向部署堆栈添加新软件。您可能已经在使用某些东西进行监控(nagios?)。让它在每个网络服务器上调用一个简单的 PHP 脚本来调整内存列表似乎是最好的选择。

\n\n

值得注意的是,在Ketama 哈希系统下,从轮换中删除服务器将导致其密钥在环上的其他位置(连续体)重新进行哈希处理,其他服务器将看不到在其他位置分配的密钥。将其可视化为一个圆圈,每个服务器在圆圈上分配了多个点(100-200)。密钥被散列到圆圈中并继续顺时针方向,直到找到服务器。从环中删除服务器只会导致这些值继续进一步寻找新服务器。幸运的是,价值的分配将平等地到达其余服务器。

\n\n

演示哈希系统:

\n\n
<?php\n\n\n$m = new Memcached();\n$m->setOption(Memcached::OPT_DISTRIBUTION, Memcached::DISTRIBUTION_CONSISTENT);\n\n\n$m->addServer(\'localhost\', 11211);\n$m->addServer(\'localhost\', 11212);\n$m->addServer(\'localhost\', 11213);\n$m->addServer(\'localhost\', 11214);\n$m->addServer(\'localhost\', 11215);\n$m->addServer(\'localhost\', 11216);\n$m->addServer(\'localhost\', 11217);\n$m->addServer(\'localhost\', 11218);\n$m->addServer(\'localhost\', 11219);\n$m->addServer(\'localhost\', 11210);\n\n$key = uniqid(); //You may change this to md5(uniqid()); if you\'d like to see a greater variation in keys. I don\'t think it necessary.\n$m->set($key, $key, 5);\n\n\nvar_dump($m->get($key));\n\nunset($m);\n\n\n$m = new Memcached();\n$m->setOption(Memcached::OPT_DISTRIBUTION, Memcached::DISTRIBUTION_CONSISTENT);\n//one server removed. If assignment to the continuum is dependent based on add order, we would expect the get call here to fail 90% of the time, as there will only be a success if the value was stored on the first server. If the assignment is based on some hash of the server details we\'d expect success 90% of the time. \n$m->addServer(\'localhost\', 11211);\n//$m->addServer(\'localhost\', 11212);\n$m->addServer(\'localhost\', 11213);\n$m->addServer(\'localhost\', 11214);\n$m->addServer(\'localhost\', 11215);\n$m->addServer(\'localhost\', 11216);\n$m->addServer(\'localhost\', 11217);\n$m->addServer(\'localhost\', 11218);\n$m->addServer(\'localhost\', 11219);\n$m->addServer(\'localhost\', 11210);\n\nvar_dump($m->get($key));\n\nunset($m);\n\n$m = new Memcached();\n$m->setOption(Memcached::OPT_DISTRIBUTION, Memcached::DISTRIBUTION_CONSISTENT);\n//2 servers removed\n$m->addServer(\'localhost\', 11211);\n$m->addServer(\'localhost\', 11212);\n//$m->addServer(\'localhost\', 11213);\n//$m->addServer(\'localhost\', 11214);\n$m->addServer(\'localhost\', 11215);\n$m->addServer(\'localhost\', 11216);\n$m->addServer(\'localhost\', 11217);\n$m->addServer(\'localhost\', 11218);\n$m->addServer(\'localhost\', 11219);\n$m->addServer(\'localhost\', 11210);\n\nvar_dump($m->get($key));\n\nunset($m);\n\n$m = new Memcached();\n$m->setOption(Memcached::OPT_DISTRIBUTION, Memcached::DISTRIBUTION_CONSISTENT);\n//Out of order\n$m->addServer(\'localhost\', 11210);\n$m->addServer(\'localhost\', 11211);\n$m->addServer(\'localhost\', 11219);\n$m->addServer(\'localhost\', 11212);\n$m->addServer(\'localhost\', 11217);\n$m->addServer(\'localhost\', 11214);\n$m->addServer(\'localhost\', 11215);\n$m->addServer(\'localhost\', 11216);\n$m->addServer(\'localhost\', 11218);\n$m->addServer(\'localhost\', 11219);\n$m->addServer(\'localhost\', 11213);\n\nvar_dump($m->get($key));\n\nunset($m);\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果哈希系统关心顺序,\xc2\xa0 或省略我们期望得到的服务器bool(false)大多数次要示例的服务器,因为早期的服务器被删除等。但是,根据我的快速、完全非科学的测试,我只得到一个bool false 在任何特定槽位中十分之一。显然我刚刚在我的测试盒上启动了 10 个服务器。只给他们每个人 4mb 的内存

\n