我在 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
- Apache 2.2.22
- Memcached 服务器 1.4.14(4 个实例)
- libmemcached 1.0.8
- PHP 5.4.9-4ubuntu2.3
- PHP 的 Memcached 库 latest .
更新 2014.04.22
问题在我的最新配置上仍然存在:
- Xubuntu 13.10(内核 3.11.0-19)
- Apache 2.4.6
- 内存缓存 1.4.14
- libmemcached 1.0.8
- PHP 5.5.3-1ubuntu2.3
- PHP 2.1.0 的 Memcached 库
最佳答案
我不确定我是否明白您的“问题”是什么。 您的每个 Apache PHP“服务器”(即子 worker )在启动时尚未连接到内存缓存 - 因此每个都需要初始化一个连接 - 他们每个都......一次。
现在每个 worker 都有一个服务器列表。
如果你第二次查询它——你会“看到”服务器列表.. 但是你有一个缓存对象,我假设你只实例化一次。所以你永远不会第二次调用它,所以它永远不会尝试第二次调用 getServers ......所以你永远不会看到“这里是服务器列表”。
我说的对吗?
如果是这样,这是关于“单例”的常见问题/误解之一。关于单例,您总是需要问的最重要的问题是“他们中有多少人”——因为他们只是在他们控制的上下文中是“单例”的……但在这种情况下——其他外部因素可能会更多他们。 在这种情况下,每个 PHP 实例都有一个....但是您的 apache 生成多个 PHP 实例 - 所以每个实例都会有一个 - 而那些共享没有,所以每个都需要它自己的全局变量,它自己与数据库的持久连接,与内存缓存的持久连接等。
很高兴被纠正。
关于php - PHP 中的持久内存缓存 - 服务器池不断增长,直到 curr_connections 10,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19451582/