2

我对 PHP 中的 Memcached 持久性有疑问。Memcached lib 返回空getServerList(),直到有 10 个并发连接。找不到对此的合理解释,但找到了有同样问题的人(没有解决方案)。

我的例子:

class Cache {

    protected $memcached;

    public function __construct($cache_name) {
        $instance_name = 'persistent-' . $cache_name;
        $this->memcached = new Memcached($instance_name);
        $server_count = count($this->memcached->getServerList());
        echo '[MC] Server count of ', $instance_name, ': ', $server_count, PHP_EOL;

        if (0 == $server_count) {
            $servers = array(array("localhost","16586"),array("localhost","16587"));
            echo '[MC] Adding servers: ', json_encode($servers), PHP_EOL;
            // options don't change anything in my case
            $this->memcached->setOptions(array(
                Memcached::OPT_DISTRIBUTION => Memcached::DISTRIBUTION_CONSISTENT,
                Memcached::OPT_LIBKETAMA_COMPATIBLE => true
            ));
            $this->memcached->addServers($servers);
        }

        $stats = $this->memcached->getStats();
        foreach($stats as $server => $data){
            echo '[MC] Stats of ', $server, ' curr_connections: ', $data['curr_connections'], ' total_connections: ', $data['total_connections'], PHP_EOL;
        }
    }

    public function get($key) {
        echo '[MC] Server for key: ', $key, ' is ', json_encode($this->memcached->getServerByKey($key)), PHP_EOL;
        $ret = $this->memcached->get($key);
        echo '[MC] Getting ', $key, ' with result: ', $ret, PHP_EOL;
        return $ret;
    }

    public function set($key, $data, $timeout = 0) {
        echo '[MC] Set of ', $key, ' with data: ', $data, PHP_EOL;
        return $this->memcached->set($key, $data, $timeout);
    }
}

$cache = new Cache('instance');

$ret = $cache->get('something');

if(empty($ret)) {
    $cache->set('something', true);
}

我对这段代码的期望是addServers在建立连接后单次运行。

新运行(memcached/apache 重启后)显示:

// first run
[MC] Server count of persistent-instance: 0
[MC] Adding servers: [["localhost","16586"],["localhost","16587"]]
[MC] Stats of localhost:16586 curr_connections: 5 total_connections: 6
[MC] Stats of localhost:16587 curr_connections: 5 total_connections: 6
[MC] Server for key: something is {"host":"localhost","port":16587,"weight":1}
[MC] Getting something with result: 
[MC] Set of something with data: 1

// second
[MC] Server count of persistent-instance: 0
[MC] Adding servers: [["localhost","16586"],["localhost","16587"]]
[MC] Stats of localhost:16586 curr_connections: 6 total_connections: 7
[MC] Stats of localhost:16587 curr_connections: 6 total_connections: 7
[MC] Server for key: something is {"host":"localhost","port":16587,"weight":1}
[MC] Getting something with result: 1

// up to 6th call curr_connections are growing and still adding servers to pool
[MC] Server count of persistent-instance: 0
[MC] Adding servers: [["localhost","16586"],["localhost","16587"]]
[MC] Stats of localhost:16586 curr_connections: 10 total_connections: 11
[MC] Stats of localhost:16587 curr_connections: 10 total_connections: 11
[MC] Server for key: something is {"host":"localhost","port":16587,"weight":1}
[MC] Getting something with result: 1

// 7th+ call finally with expected result
[MC] Server count of persistent-instance: 2
[MC] Stats of localhost:16586 curr_connections: 10 total_connections: 11
[MC] Stats of localhost:16587 curr_connections: 10 total_connections: 11
[MC] Server for key: something is {"host":"localhost","port":16587,"weight":1}
[MC] Getting something with result: 1

我错过了什么吗?发生了什么?

我的配置:

  • Ubuntu 13.04
  • 阿帕奇 2.2.22
  • Memcached 服务器 1.4.14(4 个实例)
  • libmemcached 1.0.8
  • PHP 5.4.9-4ubuntu2.3
  • 用于 PHP最新的 Memcached 库。

更新 2014.04.22

我的最新配置仍然存在问题:

  • Xubuntu 13.10(内核 3.11.0-19)
  • 阿帕奇 2.4.6
  • 内存缓存 1.4.14
  • libmemcached 1.0.8
  • PHP 5.5.3-1ubuntu2.3
  • 用于 PHP 2.1.0 的 Memcached 库
4

2 回答 2

1

我不确定我明白你的“问题”是什么。您的每个 Apache PHP“服务器”(即子工作人员)在启动时还没有连接到 memcache - 所以每个都需要初始化一个连接 - 他们每个都做......一次。

现在每个工人都有一个服务器列表。

如果您要第二次查询它-您将“看到”服务器列表..但是您有一个缓存对象,我假设您只实例化一次。所以你永远不会第二次调用它,所以它永远不会尝试第二次调用 getServers ......所以你永远不会看到“这里是服务器列表”。

我有正确的吗?

如果是这样,这是关于“单身人士”的常见问题/误解之一。关于单身人士,你总是需要问的最重要的问题是“他们有多少人”——因为他们只是在他们控制的上下文中“单身”……但在这种情况下——其他外部因素可能会使他们。在这种情况下,每个 PHP 实例有一个....但是您的 apache 会创建多个PHP 实例 - 所以每个实例都会有一个 - 并且这些实例不共享任何内容,因此每个实例都需要自己的全局变量、与数据库的持久连接、与数据库的持久连接内存缓存等

很高兴得到纠正。

于 2020-11-02T09:13:52.253 回答
0

如果您使用 php-fpm(或与 Apache 类似的配置),每个 php 子节点将创建自己的与 memcache 的持久连接。因此,如果 php-fpm 配置为创建 10 个子节点,那么您的日志输出就完全有意义了 :-)

于 2016-12-21T17:39:36.270 回答