我通常将可用服务器列表存储在 APC 中,因此我可以即时修改它。你是对的,系统会在它被列出时尝试继续使用关闭的服务器,幸运的是,使用新的散列方法,将它从轮换中拉出来并不是什么大问题。
我会避免使用全新的 PHP 扩展,或者尝试将新软件添加到您的部署堆栈中。您可能已经在使用某些东西进行监控(nagios?)。让它在每个网络服务器上调用一个简单的 PHP 脚本来调整内存列表似乎是最好的选择。
值得注意的是,在Ketama 散列系统下,将服务器从轮换中移除将导致其密钥在环上的其他位置(连续体)被重新散列,其他服务器将看不到它们在其他地方分配的密钥。将其可视化为一个圆圈,为每个服务器分配圆圈上的多个点(100-200)。密钥被散列到圆圈中并顺时针继续,直到找到服务器。从环中删除服务器只会导致这些值继续更进一步以找到新服务器。运气好的话,值的分布将平等地影响剩余的服务器。
演示哈希系统:
<?php
$m = new Memcached();
$m->setOption(Memcached::OPT_DISTRIBUTION, Memcached::DISTRIBUTION_CONSISTENT);
$m->addServer('localhost', 11211);
$m->addServer('localhost', 11212);
$m->addServer('localhost', 11213);
$m->addServer('localhost', 11214);
$m->addServer('localhost', 11215);
$m->addServer('localhost', 11216);
$m->addServer('localhost', 11217);
$m->addServer('localhost', 11218);
$m->addServer('localhost', 11219);
$m->addServer('localhost', 11210);
$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.
$m->set($key, $key, 5);
var_dump($m->get($key));
unset($m);
$m = new Memcached();
$m->setOption(Memcached::OPT_DISTRIBUTION, Memcached::DISTRIBUTION_CONSISTENT);
//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.
$m->addServer('localhost', 11211);
//$m->addServer('localhost', 11212);
$m->addServer('localhost', 11213);
$m->addServer('localhost', 11214);
$m->addServer('localhost', 11215);
$m->addServer('localhost', 11216);
$m->addServer('localhost', 11217);
$m->addServer('localhost', 11218);
$m->addServer('localhost', 11219);
$m->addServer('localhost', 11210);
var_dump($m->get($key));
unset($m);
$m = new Memcached();
$m->setOption(Memcached::OPT_DISTRIBUTION, Memcached::DISTRIBUTION_CONSISTENT);
//2 servers removed
$m->addServer('localhost', 11211);
$m->addServer('localhost', 11212);
//$m->addServer('localhost', 11213);
//$m->addServer('localhost', 11214);
$m->addServer('localhost', 11215);
$m->addServer('localhost', 11216);
$m->addServer('localhost', 11217);
$m->addServer('localhost', 11218);
$m->addServer('localhost', 11219);
$m->addServer('localhost', 11210);
var_dump($m->get($key));
unset($m);
$m = new Memcached();
$m->setOption(Memcached::OPT_DISTRIBUTION, Memcached::DISTRIBUTION_CONSISTENT);
//Out of order
$m->addServer('localhost', 11210);
$m->addServer('localhost', 11211);
$m->addServer('localhost', 11219);
$m->addServer('localhost', 11212);
$m->addServer('localhost', 11217);
$m->addServer('localhost', 11214);
$m->addServer('localhost', 11215);
$m->addServer('localhost', 11216);
$m->addServer('localhost', 11218);
$m->addServer('localhost', 11219);
$m->addServer('localhost', 11213);
var_dump($m->get($key));
unset($m);
如果散列系统关心顺序,或者我们希望bool(false)
在大多数次要示例上得到省略的服务器,因为早期的服务器已被删除等。但是基于我快速、完全非科学的测试,我只得到一个 bool false 10 次中的任何特定插槽。我显然刚刚在我的测试盒上启动了 10 台服务器。只给他们每个人 4mb 的内存