Memcached for PHP和故障转移 - php

我们正在为我们的应用程序部署memcached,我希望使其具有最大的抵抗力。

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

我还没有完全弄清楚的一件事是,如果其中一台服务器死了,会发生什么。至少,似乎memcached客户端只是“放弃”了该服务器,并且没有在其中存储任何内容。

这种行为我很好。我们可以处理大量的缓存缺失。但是,在其中一台服务器被认为“发生故障”之后,随后的组又被重新分配给剩下的服务器,将是一件很不错的事情。

由于这似乎不会自动发生;我猜想解决此问题的唯一方法是让外部系统对Memcached系统进行健康检查,并适当地更新服务器列表。

但是,如果有一个包含10个服务器的列表,并且可以说,第5个就死了。.即使使用Ketama哈希,这似乎也会触发密钥的大量重新分配(这只是基于常识)。

因此,理想情况下,我只是希望PHP扩展能够确定服务器已关闭,在指定的时间段(10分钟)内将其标记为关闭,然后在这10分钟内退回到其他服务器(分布良好)进行设置和获取。

其他人如何解决呢?

编辑:阐明我的libketama点。

假设我们有10台服务器:

1,2,3,4,5,6,7,8,9,10

其中一位死亡。然后,Libketama将提供很高的可能性,使丢失服务器的点击次数平均分配给其余服务器:

1,2,3,4,inactive,6,7,8,9,10

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

1,2,3,4,6,7,8,9,10 // There are now 9 servers!

现在6将获得5的先前键,7将获得6的键。 8将得到7,9将得到8,而10将得到9。第10台服务器过去获得的所有匹配数据将不会在其余的服务器之间平均分配。导致几乎所有密钥的50%被发送到新服务器的可能性很高。

参考方案

我通常将可用服务器列表存储在APC中,因此可以随时对其进行修改。您是正确的,因为系统将尝试在列出的停机服务器上继续使用它,幸运的是,使用新的哈希方法,将其从轮换中拉下来并不是什么大问题。

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

值得注意的是,在Ketama hashing system下,从旋转中删除服务器将导致其密钥在环上的其他任何地方(连续体)重新散列,其他服务器将看不到它们在其他位置分配的密钥。将其可视化为一个圆,每个服务器在圆上分配了多个点(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)。但是基于我的快速,完全非科学的测试,我只能得到一个在10中的任何特定插槽中都bool false 10次。我显然在测试盒上启动了10台服务器。给他们每个人只有4mb的内存

PHP:对数组排序 - php

请如何排序以下数组Array ( 'ben' => 1.0, 'ken' => 2.0, 'sam' => 1.5 ) 至Array ( 'ken' => 2.0, 'sam' => 1.5, 'ben' =&…

PHP PDO组按列名称查询结果 - php

以下PDO查询返回以下结果:$db = new PDO('....'); $sth = $db->prepare('SELECT ...'); 结果如下: name curso ABC stack CDE stack FGH stack IJK stack LMN overflow OPQ overflow RS…

PHP Memcached会话突然失效 - php

session.save_handler = memcached session.save_path = "127.0.0.1:11211" session.gc_maxlifetime = 86400 其余的标准。我希望自上次用户访问该页面以来,该会话至少可以保留86400秒,即,如果我在5分钟后启动了一个会话并访问了该页面,则该会话应…

PHP Array重复数据计数 - php

我在PHP Array中有标题和语言数据。我需要显示重复的标题计数。请检查以下数组格式。Array ( [0] => Array ( [title] => My_title1 [language] => English ) [1] => Array ( [title] => My_title1 [language] => …

PHP-全局变量的性能和内存问题 - php

假设情况:我在php中运行一个复杂的站点,并且我使用了很多全局变量。我可以将变量存储在现有的全局范围内,例如$_REQUEST['userInfo'],$_REQUEST['foo']和$_REQUEST['bar']等,然后将许多不同的内容放入请求范围内(这将是适当的用法,因为这些数据指的是要求自…