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 个备注

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

以下是你不想做的事情
<?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),
));
}
?>
clancy hood at gmail dot com
13 年前
如果你想在一个相对较小的项目中开始使用 Memcached,但需要一些可扩展性,那么允许 $persistent_id 也表示你自己定义的键前缀和服务器集是有意义的。这使得在整个项目的生命周期中,键分离和数据集分配到特定服务器变得非常简单,而不会影响你的任何选项。

<?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'));

?>

string(3) "bar"
string(3) "baz"

只需记住将你的 $persistent_ids 保持简短,因为它们会侵占你的最大键长度。快乐编码!:)
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);
}

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

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

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

一个副作用是,任何其他脚本(即使跨不同的网站域)也可以添加到您的服务器“池”(如果它们知道服务器池名称,或者如果它们可以从 memcached 守护进程本身获取它(不确定是否/如何可能),或者如果您或您的团队已经使用相同的服务器池编码了多个站点(例如,new Memcached( 'same-server-pool-name' ))。这可能会造成安全漏洞。
jeroen at 4worx dot com
14 年前
将多个 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 会将所有内容存储为未压缩状态,但事实并非如此。
持久连接选项会因第二个对象的创建而发生更改。
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