我们正在为我们的应用程序部署memcached,我想尽可能地抵抗它。
我们计划使用更新的memcacheD扩展。
有一件事我还没有完全弄清楚,如果其中一个服务器死了会发生什么。至少,memcached客户机似乎只是在服务器上“放弃”,并且没有在其中存储任何东西。
我不介意这种行为。我们可以处理一堆缓存失误。然而,在其中一台服务器被认为“失败”之后,接下来的设置会被重新分发到剩下的服务器上,这将是一件好事。
因为这似乎不是自动发生的;我想解决这个问题的唯一方法是让外部系统对memcached系统进行健康检查,并适当地更新服务器列表。
但是如果有10台服务器的列表,让我们说,第5台就死了。即使使用Ketama散列,这似乎也会引发大量的密钥重新分配(这只是基于常识)。
因此,理想情况下,我只想让PHP扩展知道服务器已关闭,将其标记为指定的时间(10分钟),并在这10分钟内返回到其他服务器(很好地分布)进行sets和gets。
其他人怎么解决这个问题呢?
编辑:澄清我的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 s,8将得到7 s,9将得到8 s,10将得到9 s。第10台服务器所使用的所有点击量都不会在其余服务器中平均分配。导致几乎50%的密钥被发送到新服务器。
发布于 2012-09-11 14:48:54
我通常将可用服务器的列表存储在APC中,这样我就可以动态地修改它。您是正确的,因为系统将尝试继续使用下行服务器,幸运的是,使用新的散列方法将其从旋转中提取出来并不是什么大不了的事情。
我将避免使用全新的PHP扩展,也不会尝试向部署堆栈中添加新软件。您可能已经使用了一些监视工具(nagios?)。让它在每个bet服务器上调用一个简单的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),因为早期的服务器被删除等等。然而,基于我的快速、完全不科学的测试,我只在每10次中的任何一个特定插槽中得到一个bool。显然,我只是在我的测试框上启动了10台服务器。每人只给他们4毫巴公羊
发布于 2012-09-11 14:49:29
您可能需要尝试Memcached::OPT_AUTO_EJECT_HOSTS选项常量用于PHP。它并没有被直接记录下来,但是有一条评论是这里命名它的。
(我还没试过,所以我不能告诉你它是否有效)
发布于 2012-09-11 14:52:57
根据对这些评论的答复,我建议如下:
您需要构建一个缓存类。
该类将包含以下信息:
- Status for online or offline
- Count of requests to this server
接下来,您需要您的标准函数来添加、更新和删除键。
每次执行其中一个函数时,您都希望检查密钥是否已经在缓存中,以及它在哪个服务器上。
如果它不在服务器中,那么在检索实际DB值之后,选择请求最少的服务器来保存它。
如果这些函数中的任何一个从缓存服务器返回错误,我将将该服务器标记为脱机,重置计数,并从该服务器上的列表中删除任何键。
此时,您可以轻松地将它们自动移动到新服务器上,或者只需删除它们,以便再次查询它们。
https://stackoverflow.com/questions/12372031
复制相似问题