PHP Conference Japan 2024

Memcached::__construct

(PECL memcached >= 0.1.0)

Memcached::__construct创建 Memcached 实例

描述

public Memcached::__construct(?string $persistent_id = null, ?callable $callback = null, ?string $connection_str = null)

创建一个 Memcached 实例,表示与 memcache 服务器的连接。

警告

此函数目前没有文档;仅提供其参数列表。

参数

persistent_id

默认情况下,Memcached 实例在请求结束时会被销毁。要创建在请求之间持续存在的实例,请使用 persistent_id 指定实例的唯一 ID。使用相同 persistent_id 创建的所有实例将共享相同的连接。

callback

connection_str

示例

示例 #1 创建 Memcached 对象

<?php
/* 创建一个常规实例 */
$m = new Memcached();
echo
get_class($m);

/* 创建一个持久实例 */
$m2 = new Memcached('story_pool');
$m3 = new Memcached('story_pool');

/* 现在 $m2 和 $m3 共享相同的连接 */
?>

添加注释

用户贡献的笔记 7 条笔记

23
tschundler at gmail dot com
15 年前
使用持久连接时,务必不要重新添加服务器。

以下是不建议的做法
<?php
$mc
= new Memcached('mc');
$mc->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE, true);
$mc->addServers(array(
array(
'mc1.example.com',11211),
array(
'mc2.example.com',11211),
));
?>
每次加载页面时,这些服务器都会附加到列表中,导致对同一服务器建立许多同时打开的连接。addServer/addServers 函数不会检查对指定服务器的现有引用。

更好的方法是类似于
<?php
$mc
= new Memcached('mc');
$mc->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE, true);
if (!
count($mc->getServerList())) {
$mc->addServers(array(
array(
'mc1.example.com',11211),
array(
'mc2.example.com',11211),
));
}
?>
6
clancy hood at gmail dot com
13 年前
如果您想在一个相对较小的项目中开始使用 Memcached,但需要一定的可扩展性,那么允许 $persistent_id 也表示键前缀和您自己定义的服务器集是有意义的。这使得在整个项目的生命周期中,键分离和数据集到特定服务器(s)的分配都非常简单,而不会影响您的任何选项。



<?php

// 这里是我们将来会添加的数组
$GLOBALS['memcached-sets'] = array (
'_' => array (
array(
'localhost', 11211)
)
);

define('DEFAULT_MEMCACHED_SET', '_');

function
mcache( $persistent_id=DEFAULT_MEMCACHED_SET ) {

// 每个连接每个请求一个实例化
static $memcached_instances = array();

if(
array_key_exists($persistent_id, $memcached_instances)) {
$instance = $memcached_instances[$persistent_id];
}else{
$instance = new Memcached($persistent_id);
$instance->setOption(Memcached::OPT_PREFIX_KEY, $persistent_id);
$instance->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE, true); // 建议选项

// 如果没有列出连接,则添加服务器。获取由 $persistent_id 设置的服务器集或使用默认服务器集。
// 在具有多个服务器集的生产环境中,您可能希望防止错别字静默地将数据
// 添加到默认池中,在这种情况下,如果未匹配则返回错误而不是默认为
if( !count($instance->getServerList()) ) {
$servers = array_key_exists($persistent_id, $GLOBALS['memcached-sets'])
?
$GLOBALS['memcached-sets'][$persistent_id]
:
$GLOBALS['memcached-sets'][DEFAULT_MEMCACHED_SET];
$instance->addServers($servers);
}

$memcached_instances[$persistent_id] = $instance;
}
return
$instance;
}

// 简单示例
mcache()->set('foo', 'bar');
mcache('myset')->set('foo', 'baz');

var_dump(mcache()->get('foo'), mcache('myset')->get('foo'));

?>

字符串(3) "bar"
字符串(3) "baz"

只需记住将您的 $persistent_ids 保持简短,因为它们会影响您的最大键长度。编码愉快! :)
2
enknamel AT gmail DOT com
12 年前
自从我听了这里发布的评论后,这让我抓狂。

如果启用持久性,您设置的选项也将保留,并且如果您在启用持久性的情况下设置某些选项,则将关闭所有持久连接。这是 libmemcached 的一部分,memcached 扩展程序是针对其构建的。您可以通过运行 strace 来验证这一点。

所以您应该这样做

<?php

$mem
= new Memcached($myPoolId);

if(empty(
$mem->getServerList())) {
//此代码块仅在设置新的 EG(persistent_list) 条目时执行
$mem->setOption(Memcached::OPT_RECV_TIMEOUT, 1000);
$mem->setOption(Memcached::OPT_SEND_TIMEOUT, 3000);
$mem->setOption(Memcached::OPT_TCP_NODELAY, true);
$mem->setOption(Memcached::OPT_PREFIX_KEY, "md_");
$mem->addServer($myMemcahceIp, $myMemcachePort);
}

?>
2
Tobias
13 年前
请注意,使用此 Memcached 接口,如果一个或多个底层 memcached 守护进程关闭、遭受高网络延迟(默认情况下超过 1 秒)或已崩溃,则仍然不会有任何警告、错误或通知。一切似乎都正常工作,您只是不会获得正确的结果。
3
Tobias
13 年前
不确定,但似乎 __construct() 创建了一个 Memcache() 类的实例,该实例至少存在于子 Apache 进程中,如果不是在主 Apache 进程中。

这(似乎)意味着添加到服务器“池”(通过 ->addServers())的 Memcache 守护进程会一直被记住。

这就是为什么您不希望每次脚本运行时都调用 ->addServers(),因为 ->addServers() 不会检查重复项,并且会将数百或数千个连接添加到来自 Apache 进程的 memcached 守护进程中。

一个副作用是,任何其他脚本(即使跨不同的网站域名)也可以添加到您的服务器“池”(如果他们知道服务器池名称,或者如果他们可以从 memcached 守护进程本身获取它(不确定是否/如何这可能),或者如果您或您的团队已使用相同的服务器池编写了多个站点(即,新的 Memcached('same-server-pool-name'))。这可能会造成安全漏洞。
0
jeroen at 4worx dot com
15 年前
将多个 memcached 实例与选项结合使用以及持久连接可能会令人困惑

<?php

$a
= new Memcached('memcached_pool');
$a->setOption(Memcached::OPT_COMPRESSION, false);

$b = new Memcached('memcached_pool');
$b->setOption(Memcached::OPT_COMPRESSION, true);

$a->add('key', 'some data');

?>

您可能认为连接 $a 将存储所有未压缩的数据,但事实并非如此。
第二个对象创建更改了持久连接选项。
-2
kangzjnet at gmail dot com
11 年前
要启用自动故障转移,您必须设置 OPT_REMOVE_FAILED_SERVERS 选项,该选项受 php-memcached 2.0.0b2 或更高版本支持。

以下是一个示例,


<?php
$memcache
= new Memcached ( 'a_mem_pool' );
$ss = $memcache->getServerList ();
if (empty (
$ss )) {
$memcache->setOption(Memcached::OPT_RECV_TIMEOUT, 1000);
$memcache->setOption(Memcached::OPT_SEND_TIMEOUT, 1000);
$memcache->setOption(Memcached::OPT_TCP_NODELAY, true);
$memcache->setOption(Memcached::OPT_SERVER_FAILURE_LIMIT, 50);
$memcache->setOption(Memcached::OPT_CONNECT_TIMEOUT, 500);
$memcache->setOption(Memcached::OPT_RETRY_TIMEOUT, 300);
$memcache->setOption(Memcached::OPT_DISTRIBUTION, Memcached::DISTRIBUTION_CONSISTENT);
$memcache->setOption(Memcached::OPT_REMOVE_FAILED_SERVERS, true);
$memcache->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE, true);
$memcache->addServer ( '10.10.1.75', 11211, 1 );
$memcache->addServer ( '10.10.1.76', 11211, 1 );
$memcache->addServer ( '10.10.1.77', 11211, 1 );
}
?>
To Top