Memcached一致性哈希无法与4个服务器中的3个一起运行 [英] Memcached consistent hashing not working with 3 of 4 servers down

查看:139
本文介绍了Memcached一致性哈希无法与4个服务器中的3个一起运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有3个Memcached服务器在运行,我在其中一个或另一个关闭了服务器,以研究PHP-memcached在服务器无法访问时的行为.

I have 3 memcached servers running where I shutdown the one or the other to investigate how PHP-memcached behaves upon a server not beeing reachable.

我在PHP中定义了4台服务器,其中1台用于模拟大部分脱机的服务器(备用服务器).当我关闭1台服务器(=> 2仍在线)时,第三个->get()给我结果.

I have defined 4 servers in PHP, 1 to simulate a server that is mostly offline (spare server). When I shutdown 1 server (=> 2 are still online), the third ->get() gives me a result.

当我关闭另一台服务器(=> 1仍处于联机状态)时,它将找不到推送到最后一台服务器的对象.

When I shutdown one more server (=> 1 is still online), it won't find objects pushed to that last server.

首次运行,共4台服务器中的3台:

Entity not found in cache on 1st try: NOT FOUND
Entity not found in cache on 2nd try: NOT FOUND
Entity not found in cache on 3rd try: NOT FOUND
Entity not found in cache on 4th try: NOT FOUND

第二次运行,最多4台服务器中的3台:

Entity found in Cache: SUCCESS

第三次运行,共有4台服务器中的2台:

Entity not found in cache on 1st try: CONNECTION FAILURE
Entity not found in cache on 2nd try: SERVER IS MARKED DEAD
Entity not found in cache on 3rd try: NOT FOUND
Entity not found in cache on 4th try: NOT FOUND

第四次运行,共4台服务器中的1台:

Entity not found in cache on 1st try: CONNECTION FAILURE
Entity not found in cache on 2nd try: SERVER IS MARKED DEAD
Entity not found in cache on 3rd try: CONNECTION FAILURE
Entity not found in cache on 4th try: SERVER IS MARKED DEAD

尽管有一台服务器处于联机状态,并且每次在缓存中找不到任何对象时,我都会将其推送到内存缓存中,但是它不再能够找到密钥.

Although there is one server left online and I do push my object to memcached everytime it does not find any in cache, it is not able to find the key anymore.

我认为它也应该只支持一台服务器.

I think it should also work with only a single server left.

您能向我解释这种行为吗?

即使关闭20台服务器中的19台,似乎也无法实现安全的操作.

It looks like it is not possible to implement something that is safe even when I shutdown 19 of 20 servers.

侧面问题:libketama不再真正维护了,使用它仍然很好吗? lib背后的逻辑相当不错,并且还用于清漆缓存服务器中.

Sidequestion: libketama is not really maintained anymore, is it still good to use it? The logic behind the lib was rather good and is also used in the varnish caching server.

我的脚本:

<?php
require_once 'CachableEntity.php';
require_once 'TestEntity.php';

echo PHP_EOL;

$cache = new Memcached();
$cache->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE, true);
$cache->setOption(Memcached::OPT_DISTRIBUTION, Memcached::DISTRIBUTION_CONSISTENT);
$cache->setOption(Memcached::OPT_SERVER_FAILURE_LIMIT, 1);
$cache->setOption(Memcached::OPT_REMOVE_FAILED_SERVERS, true);
$cache->setOption(Memcached::OPT_AUTO_EJECT_HOSTS, true);

$cache->setOption(Memcached::OPT_TCP_NODELAY, true);
//$cache->setOption(Memcached::OPT_RETRY_TIMEOUT, 10);

$cache->addServers([
    ['localhost', '11212'],
    ['localhost', '11213'],
    ['localhost', '11214'],
    ['localhost', '11215'], // always offline
]);


$entityId = '/test/test/article_123456789.test';

$entity = new TestEntity($entityId);

$found = false;

$cacheKey = $entity->getCacheKey();

$cacheResult = $cache->get($cacheKey);
if (empty($cacheResult)) {
    echo 'Entity not found in cache on 1st try: ' . $cache->getResultMessage(), PHP_EOL;

    $cacheResult = $cache->get($cacheKey);
    if (empty($cacheResult)) {
        echo 'Entity not found in cache on 2nd try: ' . $cache->getResultMessage(), PHP_EOL;

        $cacheResult = $cache->get($cacheKey);
        if (empty($cacheResult)) {
            echo 'Entity not found in cache on 3rd try: ' . $cache->getResultMessage(), PHP_EOL;

            $cacheResult = $cache->get($cacheKey);
            if (empty($cacheResult)) {
                echo 'Entity not found in cache on 4th try: ' . $cache->getResultMessage(), PHP_EOL;

                $entity
                    ->setTitle('TEST')
                    ->setText('Hellow w0rld. Lorem Orem Rem Em M IpsuM')
                    ->setUrl('http://www.google.com/content-123456789.html');

                $cache->set($cacheKey, $entity->serialize(), 120);
            }
        }
        else { $found = true; }
    }
    else { $found = true; }
}
else { $found = true; }


if ($found === true) {
    echo 'Entity found in Cache: ' . $cache->getResultMessage(), PHP_EOL;
    $entity->unserialize($cacheResult);
    echo 'Title: ' . $entity->getTitle(), PHP_EOL;
}

echo PHP_EOL;

推荐答案

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆