这个扩展需要 libmemcached客户端库(版本大于等于 1.0.0)。链接memcached服务器时使用SASL认证,需要libmemcached 必须开启SASL选项。Memcached从0.2.0开始,要求PHP版本大于等于5.2.0。
安装
如果libmemcached被安装在一个非标准路径,使用--with-libmemcached-dir=DIR 来指定路径,DIR就是libmemcached安装时的prefix参数。这个路径需要包含文件include/libmemcached/memcached.h。
如果要支持压缩就需要zlib。对于非标准安装的zlib库,使用--with-zlib-dir=DIR 来指定zlib安装路径,DIR就是zib安装时的prefix参数。
session处理器的支持默认是开启的。如果要关闭它,使用选项--disable-memcached-session。
Do not lose your time to install it on Ubuntu just trying "sudo apt-get install php5-memcached". There is something you need to do that sure installing memcached. Anyway...
Step 1.
$ sudo apt-get install memcached
Step 2.
$ sudo apt-get install php5-memcached
Step 3.
$ sudo /etc/init.d/apache2 restart
Ready!
What about some test?
<?php
error_reporting(E_ALL & ~E_NOTICE);
$mc = new Memcached();
$mc->addServer("localhost", 11211);
$mc->set("foo", "Hello!");
$mc->set("bar", "Memcached...");
$arr = array(
$mc->get("foo"),
$mc->get("bar")
);
var_dump($arr);
?>
Hoping to help someone.
~Kerem运行时配置
这些函数的行为受php.ini中的设置影响。
| 名字 | 默认 | 可修改范围 | 更新日志 |
|---|---|---|---|
| memcached.sess_locking | 1 | PHP_INI_ALL | |
| memcached.sess_consistent_hash | 0 | PHP_INI_ALL | |
| memcached.sess_binary | 0 | PHP_INI_ALL | |
| memcached.sess_lock_wait | 150000 | PHP_INI_ALL | |
| memcached.sess_prefix | memc.sess.key. | PHP_INI_ALL | |
| memcached.sess_number_of_replicas | 0 | PHP_INI_ALL | |
| memcached.sess_randomize_replica_read | 0 | PHP_INI_ALL | |
| memcached.sess_remove_failed | 0 | PHP_INI_ALL | |
| memcached.compression_type | fastlz | PHP_INI_ALL | |
| memcached.compression_factor | 1.3 | PHP_INI_ALL | |
| memcached.compression_threshold | 2000 | PHP_INI_ALL | |
| memcached.serializer | php | PHP_INI_ALL | |
| memcached.use_sasl | 0 | PHP_INI_SYSTEM |
这是配置指令的简短说明。
memcached.sess_lockinginteger开启session支持。有效值: On, Off, 默认值 On.
memcached.sess_consistent_hashintegerMemcached 是否使用一致性哈希保存session。如果为On,session数据保存则使用一致性哈希模式。 使用一致性哈希,可以保证你在增加或删除memcached服务器节点的时候不会导致session大规模的失效。 默认此项是关闭的。
memcached.sess_binaryintegerMemcached session是否使用二进制模式。如果Libmemcached 开启二进制模式。默认值是 Off.
memcached.sess_lock_waitintegerSession 自旋锁等待时间(微秒)。请小心设置此值。值的类型是整数,当此值被设置为0的时候,lock wait的时间将会使用系统默认值,Memcached扩展中默认值是150000。
memcached.sess_prefixstring设置memcached session key的前缀。session前缀最长为219字节长的字符串。默认值是“memc.sess.key.”。
memcached.sess_number_of_replicasinteger使用memcached写session多少个副本。
memcached.sess_randomize_replica_readintegerMemcached session 是否随机复制读。默认值0
memcached.sess_remove_failedinteger是否允许自动剔除出故障的memcached服务器。默认值0
memcached.compression_typestring设置memcached的压缩类型,允许的值为fastlz, zlib。默认值是fastlz(快速无损压缩,性能不错)。
memcached.compression_factorfloat压缩因子. 保存时压缩因子超过设置的极限才会将数据压缩存储。存储压缩条件: plain_len > comp_len * factor。默认是1.3 (节省23%的空间)。
memcached.compression_thresholdinteger压缩阈值。不压缩的序列化值低于此阈值。默认值是2000字节。
memcached.serializerstring设置缓存对象的默认序列化程序。有效值: php, igbinary, json, json_array.
- json
标准的PHP JSON编码。此序列化程序快速而且是压缩后的数据,但是处理UTF-8编码数据时会不完全实现序列化。请查看JSON扩展。
- json_array
json序列化,但是反序列化的时候返回数组。
- php
PHP标准序列化
- igbinary
二进制序列化
如果二进制序列化可用,则优先使用二进制序列化,否则使用php标准序列化。
memcached.use_saslinteger链接memcached服务器时启用SASL认证。有效值On, Off。默认值是Off。
超时时间
一些存储命令在发送时会包含一个失效值(与一个元素或一个客户端操作请求相关)到服务端。所有这类用法,实际发送的值可以是一个Unix时间戳(自1970年1月1日起至失效时间的整型秒数),或者是一个从现在算起的以秒为单位的数字。对于后一种情况,这个秒数不能超过60×60×24×30(30天时间的秒数);如果失效的值大于这个值, 服务端会将其作为一个真实的Unix时间戳来处理而不是自当前时间的偏移。
如果失效值被设置为0(默认),此元素永不过期(但是它可能由于服务端为了给其他新的元素分配空间而被删除)。
The fact that one sets an expiration time does not mean that the keys will expire at that particular time. I'm not sure what is happening in the background, if there is a process like a garbage collector that expire keys, but some function do not activate the expiration check and return the key as valid, for example `getAllKeys` is not atomic and returns even expired keys.
$memcached = new Memcached();
$memcached->set('key','value',10);
//waiting more than 10 sec
sleep(20);
$data = $memcached->getAllKeys();
var_dump($data); // key will still be listed
$key = $memcached->get('key'); // will trigger the expirationA TTL of n seconds will expire between n and n-1 seconds as memcache doesn't use a high-resolution clock internally. This is important to consider if you're working with very short TTLs. See https://github.com/memcached/memcached/issues/307
Note that if you pass the expiration time as an offset of seconds then the cache item will expire in current-second + offset, not in now + offset.
<?php
$Memcached->add('foo', 42, 2);
?>
This item will expire in n seconds where n > 1 and <= 2, not in exactly 2 seconds.结果回调
Result callbacks方式在通过Memcached::getDelayed()或 Memcached::getDelayedBykey()方法获取元素后,为结果集中每个元素调用一次。 回调函数可以接收到一个Memcached对象合一个数组描述的元素信息,此回调函数不需要返回任何信息。
Example #1 结果回调示例
<?php
$m = new Memcached();
$m->addServer('localhost', 11211);
$items = array(
'key1' => 'value1',
'key2' => 'value2',
'key3' => 'value3'
);
$m->setMulti($items);
$m->getDelayed(array('key1', 'key3'), true, 'result_cb');
function result_cb($memc, $item)
{
var_dump($item);
}
?>
以上例程的输出类似于:
array(3) {
["key"]=>
string(4) "key1"
["value"]=>
string(6) "value1"
["cas"]=>
float(49)
}
array(3) {
["key"]=>
string(4) "key3"
["value"]=>
string(6) "value3"
["cas"]=>
float(50)
}
I was having trouble making method calls with the result callbacks in getDelayed, so I emailed the developer.
If you want to use a non-static method as a callback, use the following format: array($obj, 'method'); for example:
<?php
class foo {
private $M = false;
public function __construct() {
$this->M = new Memcached();
$this->M->addServer('localhost', 11211);
$this->M->set('a', 'test');
}
public function test() {
$this->M->getDelayed(array('a'), false, array($this, 'fun'));
}
public function fun() {
echo "Great Success!";
}
}
$f = new foo();
$f->test();
?>
or, alternatively:
<?php
class foo {
public $M = false;
public function __construct() {
$this->M = new Memcached();
$this->M->addServer('localhost', 11211);
$this->M->set('a', 'test');
}
public function fun() {
echo "Great Success!";
}
}
$f = new foo();
$f->M->getDelayed(array('a'), false, array($f, 'fun'));
?>
Works great, thanks Andrei :)通读缓存回调
通读缓存回调在一个元素没有从服务端检索到的时候被调用。这个回调函数会接收到Memcached对象,请求的key以及 一个引用方式传递的值变量等三个参数。此回调函数负责通过返回true或false来决定在key没有值时设置一个默认值。 如果回调返回true,Memcached会存储"传出参数"(引用传递的值变量)存储的值到memcached服务端并将其返回到原来 的调用函数中。仅仅Memcached::get()和Memcached::getByKey() 支持这类回调,因为Memcache协议不支持在请求多个key时提供未检索到key的信息。
Example #1 通读回调示例
<?php
$m = new Memcached();
$m->addServer('localhost', 11211);
$profile_info = $m->get('user:'.$user_id, 'user_info_cb');
function user_info_cb($memc, $key, &$value)
{
$user_id = substr($key, 5);
/* 从数据库读取个人信息 */
/* ... */
$value = $profile_info;
return true;
}
?>
Or just set the value within the callback with your own custom expiration time and return false. I think it's cleaner.
This isn't specified anywhere, so I had a gander at the source... The expiry on read-through cache set values is set to 0, or forever. This means if you want your key to implicitly expire, don't use the callback methods, instead check for boolean false as a return and manually set the value, at least for now.
Sessions支持
memcached提供了一个自定义的session处理器可以被用于存储用户session数据到memcached服务端。一个完全独立的memcached实例将会在内部使用,因此如果需要您可以设置一个不同的服务器池。session的key被存储在前缀memc.sess.key.之下,因此, 如果你对session和通常的缓存使用了同样的服务器池,请注意这一点。译注:另外一个session和通常缓存分离的原因是当通常的缓存占满了memcached服务端后,可能会导致你的session被从缓存中踢除,导致用户莫名的掉线。
session.save_handlerstring设置为memcached开启memcached的session处理器。
session.save_pathstring定义一个逗号分隔的hostname:port样式的session缓存服务器池,例如:"sess1:11211, sess2:11211".
If you want to use 'memcacheD' extention not 'memcache' (there are two diffrent extentions) for session control, you should pay attention to modify php.ini Most web resource from google is based on memcache because It's earlier version than memcacheD. They will say as following session.save_handler = memcache session.save_path = "tcp://localhost:11211" But it's not valid when it comes to memcacheD you should modify php.ini like that session.save_handler = memcached session.save_path = "localhost:11211" Look, there is no protocol indentifier
If you are setting data to the session and it immediately disappears and you aren't getting any warnings in your PHP error log, it's probably because your sessions expired sometime in the 1970s. Somewhere between memcached 1.0.2 and 2.1.0, the memcached session handler became sensitive to the 30-day TTL gotcha (aka "transparent failover"). If your session.gc_maxlifetime is greater than 2592000 (30 days), the value is treated as a unix timestamp instead of a relative seconds count. This issue is likely to impact anyone with long-running sessions who is upgrading from Ubuntu 12.04 to 14.04.
The documentation is not complete, you can also pass the weight of each server and you can use sockets if you want. In your PHP ini:
<?php
// Sockets with weight in the format socket_path:port:weight
session.save_path = "/path/to/socket:0:42"
// Or more than one so that weight makes sense?
session.save_path = "/path/to/socket_x:0:42,/path/to/socket_y:0:666"
?>
And if you should ever want to access these servers in PHP:
<?php
$servers = explode(",", ini_get("session.save_path"));
$c = count($servers);
for ($i = 0; $i < $c; ++$i) {
$servers[$i] = explode(":", $servers[$i]);
}
$memcached = new \Memcached();
call_user_func_array([ $memcached, "addServers" ], $servers);
print_r($memcached->getAllKeys());
?>
If you are using the memcache class for session handling your key is the PHP session ID. This is different than when using the memcached class. Example with memcache: GET nphu2u8eo5niltfgdbc33ajb62 Example with memcached: GET memc.sess.key.nphu2u8eo5niltfgdbc33ajb62 For memcached, the prefix is set in the config: memcached.sess_prefix = "memc.sess.key."
This extension supports Session-locking! by default MEMC_SESS_LOCK_ATTEMPTS 30 MEMC_SESS_LOCK_WAIT 100000 MEMC_SESS_LOCK_EXPIRATION 30
in case of multiples memcached servers, the separator is a semicolon ( ; ) not a comma as written example: session.save_path = "sess1:11211; sess2:11211"
Is important to address that memcached is not concurrent just as regular PHP sessions. If you have two tabs and one of them takes too long to respond and try to log out on the second, the memcached server won't respond.
short mention: Memcached has authentication support.
While the previous poster has a point that Memcached can and will cleanup to make room for it's keys, the likelihood of active sessions (due to the likelihood that they will be written to again within 30 seconds) is fairly low provided you have your memory allocation properly alloted.
It seems a few people think saving sessions in memcache is more secure compared to saving in file-system (/tmp) especially when the discussion is about shared hosting. This is not true. memcache has NO authentication; everybody & anybody can read session.save_path (which will contain the memcached daemon address). FastCGI (PHP-FPM) is much much better when you're considering security and shared hosting. If you want to share sessions across multiple servers transparently without having headaches of adding custom handlers, you can use NFS or something similar.
Memcached类
(PECL memcached >= 0.1.0)
表征到memcached服务集群的连接。
Memcached
{
__construct ([ string $persistent_id ] )
public add ( string $key , mixed $value [, int $expiration ] ) : bool
public addByKey ( string $server_key , string $key , mixed $value [, int $expiration ] ) : bool
public addServer ( string $host , int $port [, int $weight = 0 ] ) : bool
public addServers ( array $servers ) : bool
public append ( string $key , string $value ) : bool
public appendByKey ( string $server_key , string $key , string $value ) : bool
public cas ( float $cas_token , string $key , mixed $value [, int $expiration ] ) : bool
public casByKey ( float $cas_token , string $server_key , string $key , mixed $value [, int $expiration ] ) : bool
public decrement ( string $key [, int $offset = 1 ] ) : int
public decrementByKey ( string $server_key , string $key [, int $offset = 1 [, int $initial_value = 0 [, int $expiry = 0 ]]] ) : int
public delete ( string $key [, int $time = 0 ] ) : bool
public deleteByKey ( string $server_key , string $key [, int $time = 0 ] ) : bool
public deleteMulti ( array $keys [, int $time = 0 ] ) : array
public deleteMultiByKey ( string $server_key , array $keys [, int $time = 0 ] ) : bool
public fetch ( void ) : array
public fetchAll ( void ) : array
public flush ([ int $delay = 0 ] ) : bool
public get ( string $key [, callback $cache_cb [, float &$cas_token ]] ) : mixed
public getAllKeys ( void ) : array
public getByKey ( string $server_key , string $key [, callback $cache_cb [, float &$cas_token ]] ) : mixed
public getDelayed ( array $keys [, bool $with_cas [, callback $value_cb ]] ) : bool
public getDelayedByKey ( string $server_key , array $keys [, bool $with_cas [, callback $value_cb ]] ) : bool
public getMulti ( array $keys [, int $flags ] ) : mixed
public getMultiByKey ( string $server_key , array $keys [, string &$cas_tokens [, int $flags ]] ) : array
public getOption ( int $option ) : mixed
public getResultCode ( void ) : int
public getResultMessage ( void ) : string
public getServerByKey ( string $server_key ) : array
public getServerList ( void ) : array
public getStats ( void ) : array
public getVersion ( void ) : array
public increment ( string $key [, int $offset = 1 ] ) : int
public incrementByKey ( string $server_key , string $key [, int $offset = 1 [, int $initial_value = 0 [, int $expiry = 0 ]]] ) : int
public isPersistent ( void ) : bool
public isPristine ( void ) : bool
public prepend ( string $key , string $value ) : bool
public prependByKey ( string $server_key , string $key , string $value ) : bool
public quit ( void ) : bool
public replace ( string $key , mixed $value [, int $expiration ] ) : bool
public replaceByKey ( string $server_key , string $key , mixed $value [, int $expiration ] ) : bool
public resetServerList ( void ) : bool
public set ( string $key , mixed $value [, int $expiration ] ) : bool
public setByKey ( string $server_key , string $key , mixed $value [, int $expiration ] ) : bool
public setMulti ( array $items [, int $expiration ] ) : bool
public setMultiByKey ( string $server_key , array $items [, int $expiration ] ) : bool
public setOption ( int $option , mixed $value ) : bool
public setOptions ( array $options ) : bool
public setSaslAuthData ( string $username , string $password ) : void
public touch ( string $key , int $expiration ) : bool
public touchByKey ( string $server_key , string $key , int $expiration ) : bool
}
