我的问题与PHP Memcache扩展的addServer函数中的"weight"参数有关.
在过去的几个月里,我一直在为所有服务器使用"weight = 1".我现在正在尝试应用以下配置,最终从旋转中删除"10.10.10.3"并最大限度地减少数据丢失.
使用新的权重值后,我的PHP客户端无法检索以前能够获取的密钥的值.如果我恢复为"weight = 1",则可以毫无问题地获取所有密钥.
是否有配置或我遗漏的任何东西,以便正确使用"重量"选项与"Memcache :: addServer"?
谢谢您的帮助.
$hosts = array(
array('ip' => '10.10.10.1', 'port' => 11211, 'weight' => 100),
array('ip' => '10.10.10.2', 'port' => 11211, 'weight' => 100),
array('ip' => '10.10.10.3', 'port' => 11211, 'weight' => 1),
array('ip' => '10.10.10.4', 'port' => 11211, 'weight' => 100),
);
$memcache = new Memcache();
foreach($hosts as $host) {
$host['port'] = isset($host['port']) ? (int) $host['port'] : 11211;
$host['weight'] = isset($host['weight']) ? (int) $host['weight'] : 1;
$memcache->addserver($host['ip'], $host['port'], false, $host['weight'], 1, 15);
}
Run Code Online (Sandbox Code Playgroud)
PHP版本 = 5.3.10
Memcache PHP变量
- memcache support => enabled
- memcache.allow_failover => 1 => 1
- memcache.chunk_size => 32768 => 32768
- memcache.compress_threshold => 20000 => 20000
- memcache.default_port => 11211 => 11211
- memcache.hash_function => crc32 => crc32
- memcache.hash_strategy => consistent => consistent
- memcache.lock_timeout => 15 => 15
- memcache.max_failover_attempts => 20 => 20
- memcache.protocol => ascii => ascii
- memcache.redundancy => 1 => 1
- memcache.session_redundancy => 2 => 2
Memcached版本
10.10.10.1/10.10.10.2/10.10.10.3正在运行1.4.5
10.10.10.4正在运行1.4.4
dre*_*010 11
weight参数会影响用于确定从哪个服务器读取/写入密钥的一致性散列.更改池中任何1台服务器的权重将导致一些缓存未命中.池中的服务器数量以及您更改权重的数量将考虑您可能遇到的未命中数.
您需要了解的是,memcached是分布式的,这意味着由于您有4台服务器,因此密钥分布在每台服务器中(尽可能接近均匀[权重会影响均匀分布]).如果一台服务器出现故障时,存储在该服务器上的数据不再访问,将不得不从数据库中读取的,因为它是不提供任何其他服务器上.*请注意,PHP扩展memcache和memcached是正义的访问客户memcached群(memcached的是两者的更新,支持更多的功能,但都聊到服务器的分布式缓存集群).
当您想要从缓存中存储或检索值时,会计算一个哈希值,该哈希值确定应在数据集中放置或读取数据的位置.说明这一点的常用方法是使用360度圆圈,如下所示.您计算一个哈希值,并使用它在圆圈中"最接近"的节点.添加或删除服务器,或更改任何一台服务器的权重都会影响散列的结果并导致错过.

资料来源:http://alpha.mixi.co.jp/blog/?p = 158
如果你想逐步的服务器出群集慢慢的,我会逐渐减少推荐它的重量,直到它是0,你可以然后从列表中完全删除服务器.请记住,重量的任何微小变化都可能/将导致缓存未命中,但重量变化多少(以及您拥有多少台服务器)会影响您将遇到的失误次数.
这是Memcached教程故事中的一个片段,可能有助于解释其中的一些内容.
前言是两个系统管理员设置了一个带有3个服务器的memcached集群,并告诉memcached在每个服务器上使用1GB ......
所以,他再次获取程序员使用的密钥,并在他的memcached服务器上查找它们.'get this_key''get that_key'但每次他这样做,他只会在一个memcached中找到每个键!他想,你为什么要这样做呢?他整晚都在困惑.那太傻了!你不希望键存在于所有memcacheds上吗?
"但等等",他认为"我给了每个内存1千兆字节的内存,这意味着,总的来说,我可以缓存3千兆字节的数据库,而不只是一个!哦,伙计,这很棒,"他想."这将为我节省大量现金.布拉德菲茨帕特里克,我爱你的屁股!"
"但是,嗯,下一个问题,这个是一个益智游戏,这个网络服务器就在这里,这个运行memcached它已经老了,它病了,需要升级.但为了做到这一点,我必须让它脱机!会发生什么对我糟糕的memcache集群?呃,让我们发现,"他说,然后他关上了盒子.现在他看着他的图表."哦,不,数据库负载,它大步上升!负载不是一个,它现在是两个.嗯,但仍然可以容忍.所有其他memcached仍然有流量.这不是那么糟糕.只是一个几乎没有缓存未命中,我几乎完成了我的工作.所以他重新启动机器,并将memcached恢复工作.几分钟后,数据库负载再次下降到1,应该始终如此.
"缓存恢复了自己!我现在得到它.如果它不可用,只是意味着我的一些请求被错过.但这还不足以杀死我.这非常可爱."
道德是存储在memcached中的值仅存储在一个服务器上(即密钥分布在所有服务器之间),如果这些服务器中的任何一个变得不可用,则数据不能从缓存中获取并且必须从源中获取.
为了从群集中的正确节点正确存储和检索数据,必须始终对密钥进行哈希处理,以便客户端知道池中该特定密钥的哪个服务器是正确的.
正如您可能猜到的,不同的客户端使用不同的散列技术,因此使用Perl客户端和PHP客户端来存储/检索值将无法正常工作,因为它们的散列方式不同.对此的例外是任何使用libmemcached的客户端,因为它们都将使用相同的散列算法.PHP的memcached扩展使用libmemcached,其中memcache没有,并使用自己的散列算法(据我所知).
进一步阅读:
- memcached wiki和学习memcached的冒险
- Consistent Hashing
- 分布式哈希表