首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Memcached for PHP和故障转移

Memcached for PHP和故障转移
EN

Stack Overflow用户
提问于 2012-09-11 14:28:28
回答 4查看 5.8K关注 0票数 13

我们正在为我们的应用程序部署memcached,我想尽可能地抵抗它。

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

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

我不介意这种行为。我们可以处理一堆缓存失误。然而,在其中一台服务器被认为“失败”之后,接下来的设置会被重新分发到剩下的服务器上,这将是一件好事。

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

但是如果有10台服务器的列表,让我们说,第5台就死了。即使使用Ketama散列,这似乎也会引发大量的密钥重新分配(这只是基于常识)。

因此,理想情况下,我只想让PHP扩展知道服务器已关闭,将其标记为指定的时间(10分钟),并在这10分钟内返回到其他服务器(很好地分布)进行sets和gets。

其他人怎么解决这个问题呢?

编辑:澄清我的libketama观点。

假设我们有10台服务器:

代码语言:javascript
复制
1,2,3,4,5,6,7,8,9,10

其中一个死了。然后,Libketama将提供一个非常高的可能性,即对丢失的服务器的点击将平等地分布到其余的服务器上:

代码语言:javascript
复制
1,2,3,4,inactive,6,7,8,9,10

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

代码语言:javascript
复制
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%的密钥被发送到新服务器。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-09-11 14:48:54

我通常将可用服务器的列表存储在APC中,这样我就可以动态地修改它。您是正确的,因为系统将尝试继续使用下行服务器,幸运的是,使用新的散列方法将其从旋转中提取出来并不是什么大不了的事情。

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

值得注意的是,在Ketama散列系统下,从旋转中删除服务器将导致它的密钥在环(连续体)的其他地方被重新散列,其他服务器将不会看到它们在其他地方分配的密钥。将其可视化为一个圆,每个服务器在圆圈上被分配多个点(100-200)。键被散列到圆圈,并按顺时针方向继续,直到找到服务器。从环中移除服务器只会导致这些值继续更远一些,以找到新服务器。幸运的话,值的分配将同样地影响其余的服务器。

演示哈希系统:

代码语言:javascript
复制
<?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毫巴公羊

票数 3
EN

Stack Overflow用户

发布于 2012-09-11 14:49:29

您可能需要尝试Memcached::OPT_AUTO_EJECT_HOSTS选项常量用于PHP。它并没有被直接记录下来,但是有一条评论是这里命名它的。

(我还没试过,所以我不能告诉你它是否有效)

票数 2
EN

Stack Overflow用户

发布于 2012-09-11 14:52:57

根据对这些评论的答复,我建议如下:

您需要构建一个缓存类。

该类将包含以下信息:

  • 缓存服务器列表
代码语言:javascript
复制
- Status for online or offline
- Count of requests to this server

  • 当前存储的密钥列表以及它在哪个服务器上

接下来,您需要您的标准函数来添加、更新和删除键。

每次执行其中一个函数时,您都希望检查密钥是否已经在缓存中,以及它在哪个服务器上。

如果它不在服务器中,那么在检索实际DB值之后,选择请求最少的服务器来保存它。

如果这些函数中的任何一个从缓存服务器返回错误,我将将该服务器标记为脱机,重置计数,并从该服务器上的列表中删除任何键。

此时,您可以轻松地将它们自动移动到新服务器上,或者只需删除它们,以便再次查询它们。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12372031

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档