基础知识之Memcache的安装和测试
2016-09-21 12:02
501 查看
memcached安装
【memcached 安装使用windows 】
先把php版本从5.2.0升级到5.2.4(覆盖原来的文件就行了)
1. http://jehiah.cz/projects/memcached-win32/ 上下载memcache的windows稳定版,解压放某个盘下面,比如在c:\memcached
2.在终端(也即cmd命令界面)下输入 'c:\memcached\memcached.exe -d install' 安装
3.再输入: 'c:\memcached\memcached.exe -d start' 启动
NOTE: 以后memcached将作为windows的一个服务每次开机时自动启动。默认端口:11211。
4. 在C:\winnt\php.ini 加入一行 'extension=php_memcache.dll'
[Memcache]
memcache.allow_failover = 1
memcache.max_failover_attempts=20
memcache.chunk_size =8192
memcache.default_port = 11211
5. 下载pecl的PECL 5.2.4 Win32 binaries模块包,解压缩后将其中的memcache.dll考到c:\php\ext 中,(也不一定是c盘的PHP文件夹下,主要是看你当初把PHP安装到哪个盘符下面了)
NOTE: php和pecl的版本要一致。
6.重新启动Apache,然后查看一下phpinfo,如果有memcache,那么就说明安装成功!
注:memcache是danga.com的一个项目,最早是为 LiveJournal 服务的,目前全世界不少人使用这个缓存项目来构建自己大负载的网站,来分担数据库的压力。
Memcache官方网站:http://www.danga.com/memcached
扩展下载: http://pecl4win.php.net/download.php/ext/5_1/5.1.2/php_memcache.dll
【安装Memcache服务器端linux】
我目前的平台,服务器是Fedora Core 1(内核:2.4.22),客户端是Windows XP SP2,需要安装的就是服务器的Memcached的守护进程和客户端的PHP扩展php_memcache两个东西。现在我分别来讲。
服务器端主要是安装memcache服务器端,目前的最新版本是 memcached-1.2.0 。
下载:http://www.danga.com/memcached/dist/memcached-1.2.0.tar.gz
另外,Memcache用到了libevent这个库用于Socket的处理,所以还需要安装libevent,libevent的最新版本是libevent-1.2。(如果你的系统已经安装了libevent,可以不用安装)
官网:http://www.monkey.org/~provos/libevent/
下载:http://www.monkey.org/~provos/libevent-1.2.tar.gz
我分别把两个东东下载回来,放到 /tmp 目录下:
# cd /tmp
# wget http://www.danga.com/memcached/dist/memcached-1.2.0.tar.gz
# wget http://www.monkey.org/~provos/libevent-1.2.tar.gz
先安装libevent:
# tar zxvf libevent-1.2.tar.gz
# cd libevent-1.2
# ./configure --prefix=/usr
# make
# make install
然后看看我们的libevent是否安装成功:
# ls -al /usr/lib | grep libevent
lrwxrwxrwx 1 root ??? root ?? ?? 21 11?? 12 17:38 libevent-1.2.so.1 -> libevent-1.2.so.1.0.3
-rwxr-xr-x ?? 1 root ??? root ?? ?? 263546 11?? 12 17:38 libevent-1.2.so.1.0.3
-rw-r--r-- ?? ??? 1 root ??? root ?? ?? 454156 11?? 12 17:38 libevent.a
-rwxr-xr-x ?? 1 root ??? root ?? ?? 811 11?? 12 17:38 libevent.la
lrwxrwxrwx 1 root ??? root ?? ?? 21 11?? 12 17:38 libevent.so -> libevent-1.2.so.1.0.3
还不错,都安装上了,再来安装memcache,同时需要安装中指定libevent的安装位置:
# cd /tmp
# tar zxvf memcached-1.2.0.tar.gz
# cd memcached-1.2.0
# ./configure --with-libevent=/usr
# make
# make install
如果中间出现报错,请仔细检查错误信息,按照错误信息来配置或者增加相应的库或者路径。
安装完成后会把memcached放到 /usr/local/bin/memcached ,我们看以下是否安装了:
# ls -al /usr/local/bin/mem*
-rwxr-xr-x 1 root ??? root ?? 137986 11?? 12 17:39 /usr/local/bin/memcached
-rwxr-xr-x 1 root ??? root ?? 140179 11?? 12 17:39 /usr/local/bin/memcached-debug
恩,安装完成了,现在我们看以下memcache的帮助:
# /usr/local/bin/memecached -h
memcached 1.2.0
-p <num> 是设置Memcache监听的端口,这里设置了12000,最好是1024以上的端口
-s <file> unix socket path to listen on (disables network support)
-l <ip_addr> 连接的IP地址, 默认是本机 是监听的服务器IP地址,如果有多个地址的话,这里指定了服务器的IP地址192.168.0.122
-d 以守护程序(daemon)方式运行 memcached
-r maximize core file limit
-u 以的身份运行 (仅在以root运行的时候有效)<username> assume identity of <username> (only when run as root)
-m <num>最大内存使用,单位MB。默认64MB max memory to use for items in megabytes, default is 64 MB是分配给Memcache使用的内存数量,单位是MB,这里是10MB
-M内存耗尽时返回错误,而不是删除项return error on memory exhausted (rather than removing items)
-c <num> 选项是最大运行的并发连接数,默认是1024,这里设置了256,按照你服务器的负载量来设定
-k lock down all paged memory
-
4000
v verbose (print errors/warnings while in event loop)
-vv very verbose (also print client commands/reponses)
-h 显示帮助<-->print this help and exit
-i print memcached and libevent license
-b run a managed instanced (mnemonic: buckets)
-P <file> save PID in <file>, only used with -d option是设置保存Memcache的pid文件
-f <factor> 块大小增长因子,默认是1.25chunk size growth factor, default 1.25
-n <bytes> ?? ?最小分配空间,key+value+flags默认是48minimum space allocated for key+value+flags, default 48
常用命令:
-d start 启动memcached服务
-d restart 重起memcached服务
-d stop|shutdown 关闭正在运行的memcached服务
-d install 安装memcached服务
-d uninstall 卸载memcached服务
netstat –an
参数不算多,我们来启动一个Memcache的服务器端:
# /usr/local/bin/memcached -d -m 10 -u root -l 192.168.0.200 -p 12000 -c 256 -P tmp/memcached.pid
-d选项是启动一个守护进程,-m是分配给Memcache使用的内存数量,单位是MB,我这里是10MB,-u是运行Memcache的用户,我这里是root,-l是监听的服务器IP地址,如果有多个地址的话,我这里指定了服务器的IP地址192.168.0.200,-p是设置Memcache监听的端口,我这里设置了12000,最好是1024以上的端口,-c选项是最大运行的并发连接数,默认是1024,我这里设置了256,按照你服务器的负载量来设定,-P是设置保存Memcache的pid文件,我这里是保存在/tmp/memcached.pid,如果要结束Memcache进程,执行:
# kill `cat /tmp/memcached.pid`
【Memcache初试】
写一个 example.php 文件(更多使用方法可以参看 PHP 手册里的 Memcache Functions 使用说明),测试代码如下:
<?php
$memcache = new Memcache;
$memcache->connect('localhost', 11211) or die ("Could not connect");
$version = $memcache->getVersion();
echo "Server's version: ".$version."<br/>\n";
$tmp_object = new stdClass;
$tmp_object->str_attr = 'test';
$tmp_object->int_attr = 123;
$memcache->set('key', $tmp_object, false, 10) or die ("Failed to save data at the server");
echo "Store data in the cache (data will expire in 10 seconds)<br/>\n";
$get_result = $memcache->get('key');
echo "Data from the cache:<br/>\n";
var_dump($get_result);
?>
如果输出如下,则测试成功:
Server's version: 1.4.5
Store data in the cache (data will expire in 10 seconds)
Data from the cache:
object(stdClass)#3 (2) { ["str_attr"]=> string(4) "test" ["int_attr"]=> int(123) }
[ 接口介绍 ]
服务器端和客户端都安装配置好了,现在我们就来测试以下我们的成果。Memcache客户端包含两组接口,一组是面向过程的接口,一组是面向对象的接口,具体可以参考PHP手册 “LXXV. Memcache Functions”这章。我们为了简单方便,就使用面向对象的方式,也便于维护和编写代码。Memcache面向对象的常用接口包括:
Memcache::connect -- 打开一个到Memcache的连接
Memcache::pconnect -- 打开一个到Memcache的长连接
Memcache::close -- 关闭一个Memcache的连接
Memcache::set -- 保存数据到Memcache服务器上
Memcache::get -- 提取一个保存在Memcache服务器上的数据
Memcache::replace -- 替换一个已经存在Memcache服务器上的项目(功能类似Memcache::set)
Memcache::delete -- 从Memcache服务器上删除一个保存的项目
Memcache::flush -- 刷新所有Memcache服务器上保存的项目(类似于删除所有的保存的项目)
Memcache::getStats -- 获取当前Memcache服务器运行的状态
[ 测试代码 ]
现在我们开始一段测试代码:
<?php
//连接
$mem=new Memcache;
$mem->connect("192.168.0.200",12000);
//保存数据
$mem->set('key1','This is first value',0,60);
$val=$mem->get('key1');
echo
"Get key1 value: "
.
$val
."<br>";
//替换数据
$mem->replace('key1','This is replace value',0,60);
$val=$mem->get('key1');
echo
"Get key1 value: "
.
$val
.
"<br>";
//保存数组
$arr
=
array('aaa','bbb','ccc','ddd');
$mem->set('key2',$arr,0,60);
$val2=$mem->get('key2');
echo
"Get key2 value: ";
print_r($val2);
echo
"<br>";
//删除数据
$mem->delete('key1');
$val=$mem->get('key1');
echo
"Get key1 value: "
.
$val
.
"<br>";
//清除所有数据
$mem->flush();
$val2=$mem->get('key2');
echo
"Get key2 value: ";
print_r($val2);
echo
"<br>";
//关闭连接
$mem->close();
?>
如果正常的话,浏览器将输出:
Get key1 value: This is first value
Get key1 value: This is replace value
Get key2 value: Array ( [0] => aaa [1] => bbb [2] => ccc [3] => ddd )
Get key1 value:
Get key2 value:
基本说明我们的Memcache安装成功,我们再来分析以下上面的这段程序。
[ 程序分析 ]
初始化一个Memcache的对象:
$mem = new Memcache;
连接到我们的Memcache服务器端,第一个参数是服务器的IP地址,也可以是主机名,第二个参数是Memcache的开放的端口:
$mem->connect("192.168.0.200", 12000);
保存一个数据到Memcache服务器上,第一个参数是数据的key,用来定位一个数据,第二个参数是需要保存的数据内容,这里是一个字符串,第三个参数是一个标记,一般设置为0或者MEMCACHE_COMPRESSED就行了,第四个参数是数据的有效期,就是说数据在这个时间内是有效的,如果过去这个时间,那么会被Memcache服务器端清除掉这个数据,单位是秒,如果设置为0,则是永远有效,我们这里设置了60,就是一分钟有效时间:
$mem->set('key1', 'This is first value', 0, 60);
从Memcache服务器端获取一条数据,它只有一个参数,就是需要获取数据的key,我们这里是上一步设置的key1,现在获取这个数据后输出输出:
$val = $mem->get('key1');
echo "Get key1 value: " . $val;
现在是使用replace方法来替换掉上面key1的值,replace方法的参数跟set是一样的,不过第一个参数key1是必须是要替换数据内容的key,最后输出了:
$mem->replace('key1', 'This is replace value', 0, 60);
$val = $mem->get('key1');
echo "Get key1 value: " . $val;
同样的,Memcache也是可以保存数组的,下面是在Memcache上面保存了一个数组,然后获取回来并输出
$arr = array('aaa', 'bbb', 'ccc', 'ddd');
$mem->set('key2', $arr, 0, 60);
$val2 = $mem->get('key2');
print_r($val2);
现在删除一个数据,使用delte接口,参数就是一个key,然后就能够把Memcache服务器这个key的数据删除,最后输出的时候没有结果
$mem->delete('key1');
$val = $mem->get('key1');
echo "Get key1 value: " . $val . "<br>";
最后我们把所有的保存在Memcache服务器上的数据都清除,会发现数据都没有了,最后输出key2的数据为空,最后关闭连接
$mem->flush();
$val2 = $mem->get('key2');
echo "Get key2 value: ";
print_r($val2);
echo "<br>";
【socket操作memcached】
下面是一段简单的测试代码,代码中对标识符为 'mykey' 的对象数据进行存取操作:
<?php
// 包含 memcached 类文件
require_once('memcached-client.php');
// 选项设置
$options = array(
'servers' => array('192.168.1.1:11211'), //memcached 服务的地址、端口,可用多个数组元素表示多个 memcached 服务
'debug' => true, //是否打开 debug
'compress_threshold' => 10240, //超过多少字节的数据时进行压缩
'persistant' => false //是否使用持久连接
);
// 创建 memcached 对象实例
$mc = new memcached($options);
// 设置此脚本使用的唯一标识符
$key = 'mykey';
// 往 memcached 中写入对象
$mc->add($key, 'some random strings');
$val = $mc->get($key);
echo "n".str_pad('$mc->add() ', 60, '_')."n";
var_dump($val);
// 替换已写入的对象数据值
$mc->replace($key, array('some'=>'haha', 'array'=>'xxx'));
$val = $mc->get($key);
echo "n".str_pad('$mc->replace() ', 60, '_')."n";
var_dump($val);
// 删除 memcached 中的对象
$mc->delete($key);
$val = $mc->get($key);
echo "n".str_pad('$mc->delete() ', 60, '_')."n";
var_dump($val);
?>
[存储数据库查询结果到memcache]
在实际应用中,通常会把数据库查询的结果集保存到 memcached 中,下次访问时直接从 memcached 中获取,而不再做数据库查询操作,这样可以在很大程度上减轻数据库的负担。通常会将 SQL 语句 md5() 之后的值作为唯一标识符 key。下边是一个利用 memcached 来缓存数据库查询结果集的示例(此代码片段紧接上边的示例代码):
复制代码 代码如下:
<?php
$sql = 'SELECT * FROM users';
$key = md5($sql); //memcached 对象标识符
if ( !($datas = $mc->get($key)) ) {
// 在 memcached 中未获取到缓存数据,则使用数据库查询获取记录集。
echo "n".str_pad('Read datas from MySQL.', 60, '_')."n";
$conn = mysql_connect('localhost', 'test', 'test');
mysql_select_db('test');
$result = mysql_query($sql);
while ($row = mysql_fetch_object($result))
$datas[] = $row;
// 将数据库中获取到的结果集数据保存到 memcached 中,以供下次访问时使用。
$mc->add($key, $datas);
} else {
echo "n".str_pad('Read datas from memcached.', 60, '_')."n";
}
var_dump($datas);
?>
可以看出,使用 memcached 之后,可以减少数据库连接、查询操作,数据库负载下来了,脚本的运行速度也提高了。
【Memcache协议分析】
如果你不喜欢 php_memcache.dll 扩展或者服务器器目前不支持这个扩展,那么就可以考虑自己构建,需要构建Memcahe的客户端,要先了解Memcache协议的交互,这样才能开发自己的客户端,我这里就简单的分析以下Memcache的协议。
(更详细的协议内容请在Memcache服务器端的源码的 doc/protocol.txt 文件中,本文基本来源于此)
Memcache既支持TCP协议,也支持UDP协议,不过我们这里是以TCP协议的协议作为主要考虑对象,想了解UDP协议的过程,请参考 doc/protocol.txt 文件。
[ 错误指令]
Memcache的协议的错误部分主要是三个错误提示之提示指令:
普通错误信息,比如指令错误之类的 ERROR\r\n
客户端错误CLIENT_ERROR <错误信息>\r\n
服务器端错误SERVER_ERROR <错误信息>\r\n
[ 数据保存指令]
数据保存是基本的功能,就是客户端通过命令把数据返回过来,服务器端接收后进行处理。
指令格式:
<命令> <键> <标记> <有效期> <数据长度>\r\n
<命令> - command name
主要是三个储存数据的三个命令, set, add, replace
set 命令是保存一个叫做key的数据到服务器上
add 命令是添加一个数据到服务器,但是服务器必须这个key是不存在的,能够保证数据不会被覆盖
replace 命令是替换一个已经存在的数据,如果数据不存在,就是类似set功能
<键> - key
就是保存在服务器上唯一的一个表示符,必须是跟其他的key不冲突,否则会覆盖掉原来的数据,这个key是为了能够准确的存取一个数据项目
<标记> - flag
标记是一个16位的无符号整形数据,用来设置服务器端跟客户端一些交互的操作
<有效期> - expiration time
是数据在服务器上的有效期限,如果是0,则数据永远有效,单位是秒,Memcache服务器端会把一个数据的有效期设置为当前Unix时间+设置的有效时间
<数据长度> - bytes
数据的长度,block data 块数据的长度,一般在这个个长度结束以后下一行跟着block data数据内容,发送完数据以后,客户端一般等待服务器端的返回,服务器端的返回:
数据保存成功 STORED\r\n
数据保存失败,一般是因为服务器端这个数据key已经存在了NOT_STORED\r\n
[ 数据提取命令]
从服务器端提取数据主要是使用get指令,格式是:
get <键>*\r\n
<键>* - key
key是是一个不为空的字符串组合,发送这个指令以后,等待服务器的返回。如果服务器端没有任何数据,则是返回:
END\r\n
证明没有不存在这个key,没有任何数据,如果存在数据,则返回指定格式:
VALUE <键> <标记> <数据长度>\r\n
<数据块>\r\n
返回的数据是以VALUE开始的,后面跟着key和flags,以及数据长度,第二行跟着数据块。
<键> -key
是发送过来指令的key内容
<标记> - flags
是调用set指令保存数据时候的flags标记
<数据长度> - bytes
是保存数据时候定位的长度
<数据块> - data block
数据长度下一行就是提取的数据块内容
[ 数据删除指令]
数据删除指令也是比较简单的,使用get指令,格式是:
delete <键> <超时时间>\r\n
<键> - key
key是你希望在服务器上删除数据的key键
<超时时间> - timeout
按照秒为单位,这个是个可选项,如果你没有指定这个值,那么服务器上key数据将马上被删除,如果设置了这个值,那么数据将在超时时间后把数据清除,该项缺省值是0,就是马上被删除
删除数据后,服务器端会返回:
DELETED\r\n
删除数据成功
NOT_FOUND\r\n
这个key没有在服务器上找到
如果要删除所有服务器上的数据,可以使用flash_all指令,格式:
flush_all\r\n
这个指令执行后,服务器上所有缓存的数据都被删除,并且返回:
OK\r\n
这个指令一般不要轻易使,除非你却是想把所有数据都干掉,删除完以后可以无法恢复的。
[其他指令]
如果想了解当前Memcache服务器的状态和版本等信息,可以使用状态查询指令和版本查询指令。
如果想了解当前所有Memcache服务器运行的状态信息,可以使用stats指令,格式
stats\r\n
服务器将返回每行按照 STAT 开始的状态信息,包括20行,20项左右的信息,包括守护进程的pid、版本、保存的项目数量、内存占用、最大内存限制等等信息。
如果只是想获取部分项目的信息,可以指定参数,格式:
stats <参数>\r\n
这个指令将只返回指定参数的项目状态信息。
如果只是想单独了解当前版本信息,可以使用version指令,格式:
version\r\n
将返回以 VERSION 开头的版本信息
如果想结束当前连接,使用quit指令,格式:
quit\r\n
将断开当前连接
另外还有其他指令,包括incr, decr
c6c1
等,我也不太了解作用,就不做介绍了,如果感兴趣,可以自己去研究。
【MemAdmin】
MemAdmin是一款可视化的Memcached管理与监控工具,使用PHP开发,体积小,操作简单。
主要功能:
服务器参数监控:STATS、SETTINGS、ITEMS、SLABS、SIZES实时刷新
服务器性能监控:GET、DELETE、INCR、DECR、CAS等常用操作命中率实时监控支持数据遍历,方便对存储内容进行监视支持条件查询,筛选出满足条件的KEY或VALUE
数组、JSON等序列化字符反序列显示
兼容memcache协议的其他服务,如Tokyo Tyrant (遍历功能除外)
支持服务器连接池,多服务器管理切换方便简洁
高级 memcached 客户机命令
可以在 memcached 中使用的两个高级命令是 gets 和 cas。gets 和 cas 命令需要结合使用。您将使用这两个命令来确保不会将现有的名称/值对设置为新值(如果该值已经更新过)。我们来分别看看这些命令。
gets
gets 命令的功能类似于基本的 get 命令。两个命令之间的差异在于,gets 返回的信息稍微多一些:64 位的整型值非常像名称/值对的 “版本” 标识符。
下面是使用 gets 命令的客户机服务器交互:
set userId 0 0 5
12345
STORED
get userId
VALUE userId 0 5
12345
END
gets userId
VALUE userId 0 5 4
12345
END
考虑 get 和 gets 命令之间的差异。gets 命令将返回一个额外的值 — 在本例中是整型值 4,用于标识名称/值对。如果对此名称/值对执行另一个 set 命令,则 gets 返回的额外值将会发生更改,以表明名称/值对已经被更新。清单 6 显示了一个例子:
清单 6. set 更新版本指示符
set userId 0 0 5
33333
STORED
gets userId
VALUE userId 0 5 5
33333
END
您看到 gets 返回的值了吗?它已经更新为 5。您每次修改名称/值对时,该值都会发生更改。
cas
cas(check 和 set)是一个非常便捷的 memcached 命令,用于设置名称/值对的值(如果该名称/值对在您上次执行 gets 后没有更新过)。它使用与 set 命令相类似的语法,但包括一个额外的值:gets 返回的额外值。
注意以下使用 cas 命令的交互:
set userId 0 0 5
55555
STORED
gets userId
VALUE userId 0 5 6
55555
END
cas userId 0 0 5 6
33333
STORED
如您所见,我使用额外的整型值 6 来调用 gets 命令,并且操作运行非常顺序。现在,我们来看看清单 7 中的一系列命令:
清单 7. 使用旧版本指示符的 cas 命令
set userId 0 0 5
55555
STORED
gets userId
VALUE userId 0 5 8
55555
END
cas userId 0 0 5 6
33333
EXISTS
注意,我并未使用 gets 最近返回的整型值,并且 cas 命令返回 EXISTS 值以示失败。从本质上说,同时使用 gets 和 cas 命令可以防止您使用自上次读取后经过更新的名称/值对。
缓存管理命令
最后两个 memcached 命令用于监控和清理 memcached 实例。它们是 stats 和 flush_all 命令。
stats
stats 命令的功能正如其名:转储所连接的 memcached 实例的当前统计数据。在下例中,执行 stats 命令显示了关于当前 memcached 实例的信息:
stats
STAT pid 63
STAT uptime 101758
STAT time 1248643186
STAT version 1.4.11
STAT pointer_size 32
STAT rusage_user 1.177192
STAT rusage_system 2.365370
STAT curr_items 2
STAT total_items 8
STAT bytes 119
STAT curr_connections 6
STAT total_connections 7
STAT connection_structures 7
STAT cmd_get 12
STAT cmd_set 12
STAT get_hits 12
STAT get_misses 0
STAT evictions 0
STAT bytes_read 471
STAT bytes_written 535
STAT limit_maxbytes 67108864
STAT threads 4
END
此处的大多数输出都非常容易理解。稍后在讨论缓存性能时,我还将详细解释这些值的含义。至于目前,我们先来看看输出,然后再使用新的键来运行一些 set 命令,并再次运行 stats 命令,注意发生了哪些变化。
flush_all
flush_all 是最后一个要介绍的命令。这个最简单的命令仅用于清理缓存中的所有名称/值对。如果您需要将缓存重置到干净的状态,则 flush_all 能提供很大的用处。下面是一个使用 flush_all 的例子:
set userId 0 0 5
55555
STORED
get userId
VALUE userId 0 5
55555
END
flush_all
OK
get userId
END
缓存性能
在本文的最后,我将讨论如何使用高级 memcached 命令来确定缓存的性能。stats 命令用于调优缓存的使用。需要注意的两个最重要的统计数据是 et_hits 和 get_misses。这两个值分别指示找到名称/值对的次数(get_hits)和未找到名称/值对的次数(get_misses)。
结合这些值,我们可以确定缓存的利用率如何。初次启动缓存时,可以看到 get_misses 会自然地增加,但在经过一定的使用量之后,这些 get_misses 值应该会逐渐趋于平稳 — 这表示缓存主要用于常见的读取操作。如果您看到 get_misses 继续快速增加,而 get_hits 逐渐趋于平稳,则需要确定一下所缓存的内容是什么。您可能缓存了错误的内容。
确定缓存效率的另一种方法是查看缓存的命中率(hit ratio)。缓存命中率表示执行 get 的次数与错过 get 的次数的百分比。要确定这个百分比,需要再次运行 stats 命令,如清单 8 所示:
清单 8. 计算缓存命中率
stats
STAT pid 6825
STAT uptime 540692
STAT time 1249252262
STAT version 1.2.6
STAT pointer_size 32
STAT rusage_user 0.056003
STAT rusage_system 0.180011
STAT curr_items 595
STAT total_items 961
STAT bytes 4587415
STAT curr_connections 3
STAT total_connections 22
STAT connection_structures 4
STAT cmd_get 2688
STAT cmd_set 961
STAT get_hits 1908
STAT get_misses 780
STAT evictions 0
STAT bytes_read 5770762
STAT bytes_written 7421373
STAT limit_maxbytes 536870912
STAT threads 1
END
现在,用 get_hits 的数值除以 cmd_gets。在本例中,您的命中率大约是 71%。在理想情况下,您可能希望得到更高的百分比 — 比率越高越好。查看统计数据并不时测量它们可以很好地判定缓存策略的效率。
[常有命令如下:]
启动/结束
memcached -d -m 10 -u root -l 192.168.0.122 -p 11200 -c 256 -P /tmp/memcached.pid
-d 选项是启动一个守护进程,
-m 是分配给Memcache使用的内存数量,单位是MB,这里是10MB
-u 是运行Memcache的用户,这里是root
-l 是监听的服务器IP地址,如果有多个地址的话,这里指定了服务器的IP地址192.168.0.122
-p 是设置Memcache监听的端口,这里设置了12000,最好是1024以上的端口
-c 选项是最大运行的并发连接数,默认是1024,这里设置了256,按照你服务器的负载量来设定
-P 是设置保存Memcache的pid文件
kill `cat /tmp/memcached.pid`
获取运行状态
echo stats | nc 192.168.1.123 11200
watch "echo stats | nc 192.168.1.123 11200" (实时状态)
1。memcached的连接函数(connect, pconnect)
2。memcahced的操作函数(set, get, delete, replace, flush)
3。多服务器配置函数(addServer)
4。状态监控函数(getStats.....)
[安装多个memcached]
sc create "Memcached Server1" start= auto binPath= "C:\memcached\memcached.exe -d runservice -m 32 -p 11220 -l 127.0.0.1" DisplayName= "Memcached Server1"
下面是启动、停止、卸载该服务的命令:
sc start "Memcached Server1" //启动
sc stop "Memcached Server1" //停止
sc delete "Memcached Server1" //卸载该服务
分布式memcached测试:
<?php
//我的电脑上有两个memcahced服务.
$mem=new Memcache;
$mem->addServer('127.0.0.1',11211);
$mem->addServer('127.0.0.1',11221);
$mem->addServer('127.0.0.1',11220);
//这里注意,把key1,放入到 11211端口的mem还是
//9999 端口的mem就不要我们操心,有$mem对象本身维护.
if($mem->set('key1','hello',MEMCACHE_COMPRESSED,300)){
echo 'add ok!';
}
if($mem->set('key2','hello2',MEMCACHE_COMPRESSED,300)){
echo 'add ok!';
}
if($mem->set('key3','hello3',MEMCACHE_COMPRESSED,300)){
echo 'add ok!';
}
?>
总结:
1. mem服务的数据不是同步的, 数据是分布的
2. 把什么数据放入到哪个memcached是由客户端的mem对象决定
3. 当执行addServer的时候,并不是立即去连接mem服务,而是通过计算,hash后才去决定连接哪个mem服务,因此当你大量加入服务器到连接池,没有多余开销
【memcached 安装使用windows 】
先把php版本从5.2.0升级到5.2.4(覆盖原来的文件就行了)
1. http://jehiah.cz/projects/memcached-win32/ 上下载memcache的windows稳定版,解压放某个盘下面,比如在c:\memcached
2.在终端(也即cmd命令界面)下输入 'c:\memcached\memcached.exe -d install' 安装
3.再输入: 'c:\memcached\memcached.exe -d start' 启动
NOTE: 以后memcached将作为windows的一个服务每次开机时自动启动。默认端口:11211。
4. 在C:\winnt\php.ini 加入一行 'extension=php_memcache.dll'
[Memcache]
memcache.allow_failover = 1
memcache.max_failover_attempts=20
memcache.chunk_size =8192
memcache.default_port = 11211
5. 下载pecl的PECL 5.2.4 Win32 binaries模块包,解压缩后将其中的memcache.dll考到c:\php\ext 中,(也不一定是c盘的PHP文件夹下,主要是看你当初把PHP安装到哪个盘符下面了)
NOTE: php和pecl的版本要一致。
6.重新启动Apache,然后查看一下phpinfo,如果有memcache,那么就说明安装成功!
注:memcache是danga.com的一个项目,最早是为 LiveJournal 服务的,目前全世界不少人使用这个缓存项目来构建自己大负载的网站,来分担数据库的压力。
Memcache官方网站:http://www.danga.com/memcached
扩展下载: http://pecl4win.php.net/download.php/ext/5_1/5.1.2/php_memcache.dll
【安装Memcache服务器端linux】
我目前的平台,服务器是Fedora Core 1(内核:2.4.22),客户端是Windows XP SP2,需要安装的就是服务器的Memcached的守护进程和客户端的PHP扩展php_memcache两个东西。现在我分别来讲。
服务器端主要是安装memcache服务器端,目前的最新版本是 memcached-1.2.0 。
下载:http://www.danga.com/memcached/dist/memcached-1.2.0.tar.gz
另外,Memcache用到了libevent这个库用于Socket的处理,所以还需要安装libevent,libevent的最新版本是libevent-1.2。(如果你的系统已经安装了libevent,可以不用安装)
官网:http://www.monkey.org/~provos/libevent/
下载:http://www.monkey.org/~provos/libevent-1.2.tar.gz
我分别把两个东东下载回来,放到 /tmp 目录下:
# cd /tmp
# wget http://www.danga.com/memcached/dist/memcached-1.2.0.tar.gz
# wget http://www.monkey.org/~provos/libevent-1.2.tar.gz
先安装libevent:
# tar zxvf libevent-1.2.tar.gz
# cd libevent-1.2
# ./configure --prefix=/usr
# make
# make install
然后看看我们的libevent是否安装成功:
# ls -al /usr/lib | grep libevent
lrwxrwxrwx 1 root ??? root ?? ?? 21 11?? 12 17:38 libevent-1.2.so.1 -> libevent-1.2.so.1.0.3
-rwxr-xr-x ?? 1 root ??? root ?? ?? 263546 11?? 12 17:38 libevent-1.2.so.1.0.3
-rw-r--r-- ?? ??? 1 root ??? root ?? ?? 454156 11?? 12 17:38 libevent.a
-rwxr-xr-x ?? 1 root ??? root ?? ?? 811 11?? 12 17:38 libevent.la
lrwxrwxrwx 1 root ??? root ?? ?? 21 11?? 12 17:38 libevent.so -> libevent-1.2.so.1.0.3
还不错,都安装上了,再来安装memcache,同时需要安装中指定libevent的安装位置:
# cd /tmp
# tar zxvf memcached-1.2.0.tar.gz
# cd memcached-1.2.0
# ./configure --with-libevent=/usr
# make
# make install
如果中间出现报错,请仔细检查错误信息,按照错误信息来配置或者增加相应的库或者路径。
安装完成后会把memcached放到 /usr/local/bin/memcached ,我们看以下是否安装了:
# ls -al /usr/local/bin/mem*
-rwxr-xr-x 1 root ??? root ?? 137986 11?? 12 17:39 /usr/local/bin/memcached
-rwxr-xr-x 1 root ??? root ?? 140179 11?? 12 17:39 /usr/local/bin/memcached-debug
恩,安装完成了,现在我们看以下memcache的帮助:
# /usr/local/bin/memecached -h
memcached 1.2.0
-p <num> 是设置Memcache监听的端口,这里设置了12000,最好是1024以上的端口
-s <file> unix socket path to listen on (disables network support)
-l <ip_addr> 连接的IP地址, 默认是本机 是监听的服务器IP地址,如果有多个地址的话,这里指定了服务器的IP地址192.168.0.122
-d 以守护程序(daemon)方式运行 memcached
-r maximize core file limit
-u 以的身份运行 (仅在以root运行的时候有效)<username> assume identity of <username> (only when run as root)
-m <num>最大内存使用,单位MB。默认64MB max memory to use for items in megabytes, default is 64 MB是分配给Memcache使用的内存数量,单位是MB,这里是10MB
-M内存耗尽时返回错误,而不是删除项return error on memory exhausted (rather than removing items)
-c <num> 选项是最大运行的并发连接数,默认是1024,这里设置了256,按照你服务器的负载量来设定
-k lock down all paged memory
-
4000
v verbose (print errors/warnings while in event loop)
-vv very verbose (also print client commands/reponses)
-h 显示帮助<-->print this help and exit
-i print memcached and libevent license
-b run a managed instanced (mnemonic: buckets)
-P <file> save PID in <file>, only used with -d option是设置保存Memcache的pid文件
-f <factor> 块大小增长因子,默认是1.25chunk size growth factor, default 1.25
-n <bytes> ?? ?最小分配空间,key+value+flags默认是48minimum space allocated for key+value+flags, default 48
常用命令:
-d start 启动memcached服务
-d restart 重起memcached服务
-d stop|shutdown 关闭正在运行的memcached服务
-d install 安装memcached服务
-d uninstall 卸载memcached服务
netstat –an
参数不算多,我们来启动一个Memcache的服务器端:
# /usr/local/bin/memcached -d -m 10 -u root -l 192.168.0.200 -p 12000 -c 256 -P tmp/memcached.pid
-d选项是启动一个守护进程,-m是分配给Memcache使用的内存数量,单位是MB,我这里是10MB,-u是运行Memcache的用户,我这里是root,-l是监听的服务器IP地址,如果有多个地址的话,我这里指定了服务器的IP地址192.168.0.200,-p是设置Memcache监听的端口,我这里设置了12000,最好是1024以上的端口,-c选项是最大运行的并发连接数,默认是1024,我这里设置了256,按照你服务器的负载量来设定,-P是设置保存Memcache的pid文件,我这里是保存在/tmp/memcached.pid,如果要结束Memcache进程,执行:
# kill `cat /tmp/memcached.pid`
【Memcache初试】
写一个 example.php 文件(更多使用方法可以参看 PHP 手册里的 Memcache Functions 使用说明),测试代码如下:
<?php
$memcache = new Memcache;
$memcache->connect('localhost', 11211) or die ("Could not connect");
$version = $memcache->getVersion();
echo "Server's version: ".$version."<br/>\n";
$tmp_object = new stdClass;
$tmp_object->str_attr = 'test';
$tmp_object->int_attr = 123;
$memcache->set('key', $tmp_object, false, 10) or die ("Failed to save data at the server");
echo "Store data in the cache (data will expire in 10 seconds)<br/>\n";
$get_result = $memcache->get('key');
echo "Data from the cache:<br/>\n";
var_dump($get_result);
?>
如果输出如下,则测试成功:
Server's version: 1.4.5
Store data in the cache (data will expire in 10 seconds)
Data from the cache:
object(stdClass)#3 (2) { ["str_attr"]=> string(4) "test" ["int_attr"]=> int(123) }
[ 接口介绍 ]
服务器端和客户端都安装配置好了,现在我们就来测试以下我们的成果。Memcache客户端包含两组接口,一组是面向过程的接口,一组是面向对象的接口,具体可以参考PHP手册 “LXXV. Memcache Functions”这章。我们为了简单方便,就使用面向对象的方式,也便于维护和编写代码。Memcache面向对象的常用接口包括:
Memcache::connect -- 打开一个到Memcache的连接
Memcache::pconnect -- 打开一个到Memcache的长连接
Memcache::close -- 关闭一个Memcache的连接
Memcache::set -- 保存数据到Memcache服务器上
Memcache::get -- 提取一个保存在Memcache服务器上的数据
Memcache::replace -- 替换一个已经存在Memcache服务器上的项目(功能类似Memcache::set)
Memcache::delete -- 从Memcache服务器上删除一个保存的项目
Memcache::flush -- 刷新所有Memcache服务器上保存的项目(类似于删除所有的保存的项目)
Memcache::getStats -- 获取当前Memcache服务器运行的状态
[ 测试代码 ]
现在我们开始一段测试代码:
<?php
//连接
$mem=new Memcache;
$mem->connect("192.168.0.200",12000);
//保存数据
$mem->set('key1','This is first value',0,60);
$val=$mem->get('key1');
echo
"Get key1 value: "
.
$val
."<br>";
//替换数据
$mem->replace('key1','This is replace value',0,60);
$val=$mem->get('key1');
echo
"Get key1 value: "
.
$val
.
"<br>";
//保存数组
$arr
=
array('aaa','bbb','ccc','ddd');
$mem->set('key2',$arr,0,60);
$val2=$mem->get('key2');
echo
"Get key2 value: ";
print_r($val2);
echo
"<br>";
//删除数据
$mem->delete('key1');
$val=$mem->get('key1');
echo
"Get key1 value: "
.
$val
.
"<br>";
//清除所有数据
$mem->flush();
$val2=$mem->get('key2');
echo
"Get key2 value: ";
print_r($val2);
echo
"<br>";
//关闭连接
$mem->close();
?>
如果正常的话,浏览器将输出:
Get key1 value: This is first value
Get key1 value: This is replace value
Get key2 value: Array ( [0] => aaa [1] => bbb [2] => ccc [3] => ddd )
Get key1 value:
Get key2 value:
基本说明我们的Memcache安装成功,我们再来分析以下上面的这段程序。
[ 程序分析 ]
初始化一个Memcache的对象:
$mem = new Memcache;
连接到我们的Memcache服务器端,第一个参数是服务器的IP地址,也可以是主机名,第二个参数是Memcache的开放的端口:
$mem->connect("192.168.0.200", 12000);
保存一个数据到Memcache服务器上,第一个参数是数据的key,用来定位一个数据,第二个参数是需要保存的数据内容,这里是一个字符串,第三个参数是一个标记,一般设置为0或者MEMCACHE_COMPRESSED就行了,第四个参数是数据的有效期,就是说数据在这个时间内是有效的,如果过去这个时间,那么会被Memcache服务器端清除掉这个数据,单位是秒,如果设置为0,则是永远有效,我们这里设置了60,就是一分钟有效时间:
$mem->set('key1', 'This is first value', 0, 60);
从Memcache服务器端获取一条数据,它只有一个参数,就是需要获取数据的key,我们这里是上一步设置的key1,现在获取这个数据后输出输出:
$val = $mem->get('key1');
echo "Get key1 value: " . $val;
现在是使用replace方法来替换掉上面key1的值,replace方法的参数跟set是一样的,不过第一个参数key1是必须是要替换数据内容的key,最后输出了:
$mem->replace('key1', 'This is replace value', 0, 60);
$val = $mem->get('key1');
echo "Get key1 value: " . $val;
同样的,Memcache也是可以保存数组的,下面是在Memcache上面保存了一个数组,然后获取回来并输出
$arr = array('aaa', 'bbb', 'ccc', 'ddd');
$mem->set('key2', $arr, 0, 60);
$val2 = $mem->get('key2');
print_r($val2);
现在删除一个数据,使用delte接口,参数就是一个key,然后就能够把Memcache服务器这个key的数据删除,最后输出的时候没有结果
$mem->delete('key1');
$val = $mem->get('key1');
echo "Get key1 value: " . $val . "<br>";
最后我们把所有的保存在Memcache服务器上的数据都清除,会发现数据都没有了,最后输出key2的数据为空,最后关闭连接
$mem->flush();
$val2 = $mem->get('key2');
echo "Get key2 value: ";
print_r($val2);
echo "<br>";
【socket操作memcached】
下面是一段简单的测试代码,代码中对标识符为 'mykey' 的对象数据进行存取操作:
<?php
// 包含 memcached 类文件
require_once('memcached-client.php');
// 选项设置
$options = array(
'servers' => array('192.168.1.1:11211'), //memcached 服务的地址、端口,可用多个数组元素表示多个 memcached 服务
'debug' => true, //是否打开 debug
'compress_threshold' => 10240, //超过多少字节的数据时进行压缩
'persistant' => false //是否使用持久连接
);
// 创建 memcached 对象实例
$mc = new memcached($options);
// 设置此脚本使用的唯一标识符
$key = 'mykey';
// 往 memcached 中写入对象
$mc->add($key, 'some random strings');
$val = $mc->get($key);
echo "n".str_pad('$mc->add() ', 60, '_')."n";
var_dump($val);
// 替换已写入的对象数据值
$mc->replace($key, array('some'=>'haha', 'array'=>'xxx'));
$val = $mc->get($key);
echo "n".str_pad('$mc->replace() ', 60, '_')."n";
var_dump($val);
// 删除 memcached 中的对象
$mc->delete($key);
$val = $mc->get($key);
echo "n".str_pad('$mc->delete() ', 60, '_')."n";
var_dump($val);
?>
[存储数据库查询结果到memcache]
在实际应用中,通常会把数据库查询的结果集保存到 memcached 中,下次访问时直接从 memcached 中获取,而不再做数据库查询操作,这样可以在很大程度上减轻数据库的负担。通常会将 SQL 语句 md5() 之后的值作为唯一标识符 key。下边是一个利用 memcached 来缓存数据库查询结果集的示例(此代码片段紧接上边的示例代码):
复制代码 代码如下:
<?php
$sql = 'SELECT * FROM users';
$key = md5($sql); //memcached 对象标识符
if ( !($datas = $mc->get($key)) ) {
// 在 memcached 中未获取到缓存数据,则使用数据库查询获取记录集。
echo "n".str_pad('Read datas from MySQL.', 60, '_')."n";
$conn = mysql_connect('localhost', 'test', 'test');
mysql_select_db('test');
$result = mysql_query($sql);
while ($row = mysql_fetch_object($result))
$datas[] = $row;
// 将数据库中获取到的结果集数据保存到 memcached 中,以供下次访问时使用。
$mc->add($key, $datas);
} else {
echo "n".str_pad('Read datas from memcached.', 60, '_')."n";
}
var_dump($datas);
?>
可以看出,使用 memcached 之后,可以减少数据库连接、查询操作,数据库负载下来了,脚本的运行速度也提高了。
【Memcache协议分析】
如果你不喜欢 php_memcache.dll 扩展或者服务器器目前不支持这个扩展,那么就可以考虑自己构建,需要构建Memcahe的客户端,要先了解Memcache协议的交互,这样才能开发自己的客户端,我这里就简单的分析以下Memcache的协议。
(更详细的协议内容请在Memcache服务器端的源码的 doc/protocol.txt 文件中,本文基本来源于此)
Memcache既支持TCP协议,也支持UDP协议,不过我们这里是以TCP协议的协议作为主要考虑对象,想了解UDP协议的过程,请参考 doc/protocol.txt 文件。
[ 错误指令]
Memcache的协议的错误部分主要是三个错误提示之提示指令:
普通错误信息,比如指令错误之类的 ERROR\r\n
客户端错误CLIENT_ERROR <错误信息>\r\n
服务器端错误SERVER_ERROR <错误信息>\r\n
[ 数据保存指令]
数据保存是基本的功能,就是客户端通过命令把数据返回过来,服务器端接收后进行处理。
指令格式:
<命令> <键> <标记> <有效期> <数据长度>\r\n
<命令> - command name
主要是三个储存数据的三个命令, set, add, replace
set 命令是保存一个叫做key的数据到服务器上
add 命令是添加一个数据到服务器,但是服务器必须这个key是不存在的,能够保证数据不会被覆盖
replace 命令是替换一个已经存在的数据,如果数据不存在,就是类似set功能
<键> - key
就是保存在服务器上唯一的一个表示符,必须是跟其他的key不冲突,否则会覆盖掉原来的数据,这个key是为了能够准确的存取一个数据项目
<标记> - flag
标记是一个16位的无符号整形数据,用来设置服务器端跟客户端一些交互的操作
<有效期> - expiration time
是数据在服务器上的有效期限,如果是0,则数据永远有效,单位是秒,Memcache服务器端会把一个数据的有效期设置为当前Unix时间+设置的有效时间
<数据长度> - bytes
数据的长度,block data 块数据的长度,一般在这个个长度结束以后下一行跟着block data数据内容,发送完数据以后,客户端一般等待服务器端的返回,服务器端的返回:
数据保存成功 STORED\r\n
数据保存失败,一般是因为服务器端这个数据key已经存在了NOT_STORED\r\n
[ 数据提取命令]
从服务器端提取数据主要是使用get指令,格式是:
get <键>*\r\n
<键>* - key
key是是一个不为空的字符串组合,发送这个指令以后,等待服务器的返回。如果服务器端没有任何数据,则是返回:
END\r\n
证明没有不存在这个key,没有任何数据,如果存在数据,则返回指定格式:
VALUE <键> <标记> <数据长度>\r\n
<数据块>\r\n
返回的数据是以VALUE开始的,后面跟着key和flags,以及数据长度,第二行跟着数据块。
<键> -key
是发送过来指令的key内容
<标记> - flags
是调用set指令保存数据时候的flags标记
<数据长度> - bytes
是保存数据时候定位的长度
<数据块> - data block
数据长度下一行就是提取的数据块内容
[ 数据删除指令]
数据删除指令也是比较简单的,使用get指令,格式是:
delete <键> <超时时间>\r\n
<键> - key
key是你希望在服务器上删除数据的key键
<超时时间> - timeout
按照秒为单位,这个是个可选项,如果你没有指定这个值,那么服务器上key数据将马上被删除,如果设置了这个值,那么数据将在超时时间后把数据清除,该项缺省值是0,就是马上被删除
删除数据后,服务器端会返回:
DELETED\r\n
删除数据成功
NOT_FOUND\r\n
这个key没有在服务器上找到
如果要删除所有服务器上的数据,可以使用flash_all指令,格式:
flush_all\r\n
这个指令执行后,服务器上所有缓存的数据都被删除,并且返回:
OK\r\n
这个指令一般不要轻易使,除非你却是想把所有数据都干掉,删除完以后可以无法恢复的。
[其他指令]
如果想了解当前Memcache服务器的状态和版本等信息,可以使用状态查询指令和版本查询指令。
如果想了解当前所有Memcache服务器运行的状态信息,可以使用stats指令,格式
stats\r\n
服务器将返回每行按照 STAT 开始的状态信息,包括20行,20项左右的信息,包括守护进程的pid、版本、保存的项目数量、内存占用、最大内存限制等等信息。
如果只是想获取部分项目的信息,可以指定参数,格式:
stats <参数>\r\n
这个指令将只返回指定参数的项目状态信息。
如果只是想单独了解当前版本信息,可以使用version指令,格式:
version\r\n
将返回以 VERSION 开头的版本信息
如果想结束当前连接,使用quit指令,格式:
quit\r\n
将断开当前连接
另外还有其他指令,包括incr, decr
c6c1
等,我也不太了解作用,就不做介绍了,如果感兴趣,可以自己去研究。
【MemAdmin】
MemAdmin是一款可视化的Memcached管理与监控工具,使用PHP开发,体积小,操作简单。
主要功能:
服务器参数监控:STATS、SETTINGS、ITEMS、SLABS、SIZES实时刷新
服务器性能监控:GET、DELETE、INCR、DECR、CAS等常用操作命中率实时监控支持数据遍历,方便对存储内容进行监视支持条件查询,筛选出满足条件的KEY或VALUE
数组、JSON等序列化字符反序列显示
兼容memcache协议的其他服务,如Tokyo Tyrant (遍历功能除外)
支持服务器连接池,多服务器管理切换方便简洁
高级 memcached 客户机命令
可以在 memcached 中使用的两个高级命令是 gets 和 cas。gets 和 cas 命令需要结合使用。您将使用这两个命令来确保不会将现有的名称/值对设置为新值(如果该值已经更新过)。我们来分别看看这些命令。
gets
gets 命令的功能类似于基本的 get 命令。两个命令之间的差异在于,gets 返回的信息稍微多一些:64 位的整型值非常像名称/值对的 “版本” 标识符。
下面是使用 gets 命令的客户机服务器交互:
set userId 0 0 5
12345
STORED
get userId
VALUE userId 0 5
12345
END
gets userId
VALUE userId 0 5 4
12345
END
考虑 get 和 gets 命令之间的差异。gets 命令将返回一个额外的值 — 在本例中是整型值 4,用于标识名称/值对。如果对此名称/值对执行另一个 set 命令,则 gets 返回的额外值将会发生更改,以表明名称/值对已经被更新。清单 6 显示了一个例子:
清单 6. set 更新版本指示符
set userId 0 0 5
33333
STORED
gets userId
VALUE userId 0 5 5
33333
END
您看到 gets 返回的值了吗?它已经更新为 5。您每次修改名称/值对时,该值都会发生更改。
cas
cas(check 和 set)是一个非常便捷的 memcached 命令,用于设置名称/值对的值(如果该名称/值对在您上次执行 gets 后没有更新过)。它使用与 set 命令相类似的语法,但包括一个额外的值:gets 返回的额外值。
注意以下使用 cas 命令的交互:
set userId 0 0 5
55555
STORED
gets userId
VALUE userId 0 5 6
55555
END
cas userId 0 0 5 6
33333
STORED
如您所见,我使用额外的整型值 6 来调用 gets 命令,并且操作运行非常顺序。现在,我们来看看清单 7 中的一系列命令:
清单 7. 使用旧版本指示符的 cas 命令
set userId 0 0 5
55555
STORED
gets userId
VALUE userId 0 5 8
55555
END
cas userId 0 0 5 6
33333
EXISTS
注意,我并未使用 gets 最近返回的整型值,并且 cas 命令返回 EXISTS 值以示失败。从本质上说,同时使用 gets 和 cas 命令可以防止您使用自上次读取后经过更新的名称/值对。
缓存管理命令
最后两个 memcached 命令用于监控和清理 memcached 实例。它们是 stats 和 flush_all 命令。
stats
stats 命令的功能正如其名:转储所连接的 memcached 实例的当前统计数据。在下例中,执行 stats 命令显示了关于当前 memcached 实例的信息:
stats
STAT pid 63
STAT uptime 101758
STAT time 1248643186
STAT version 1.4.11
STAT pointer_size 32
STAT rusage_user 1.177192
STAT rusage_system 2.365370
STAT curr_items 2
STAT total_items 8
STAT bytes 119
STAT curr_connections 6
STAT total_connections 7
STAT connection_structures 7
STAT cmd_get 12
STAT cmd_set 12
STAT get_hits 12
STAT get_misses 0
STAT evictions 0
STAT bytes_read 471
STAT bytes_written 535
STAT limit_maxbytes 67108864
STAT threads 4
END
此处的大多数输出都非常容易理解。稍后在讨论缓存性能时,我还将详细解释这些值的含义。至于目前,我们先来看看输出,然后再使用新的键来运行一些 set 命令,并再次运行 stats 命令,注意发生了哪些变化。
flush_all
flush_all 是最后一个要介绍的命令。这个最简单的命令仅用于清理缓存中的所有名称/值对。如果您需要将缓存重置到干净的状态,则 flush_all 能提供很大的用处。下面是一个使用 flush_all 的例子:
set userId 0 0 5
55555
STORED
get userId
VALUE userId 0 5
55555
END
flush_all
OK
get userId
END
缓存性能
在本文的最后,我将讨论如何使用高级 memcached 命令来确定缓存的性能。stats 命令用于调优缓存的使用。需要注意的两个最重要的统计数据是 et_hits 和 get_misses。这两个值分别指示找到名称/值对的次数(get_hits)和未找到名称/值对的次数(get_misses)。
结合这些值,我们可以确定缓存的利用率如何。初次启动缓存时,可以看到 get_misses 会自然地增加,但在经过一定的使用量之后,这些 get_misses 值应该会逐渐趋于平稳 — 这表示缓存主要用于常见的读取操作。如果您看到 get_misses 继续快速增加,而 get_hits 逐渐趋于平稳,则需要确定一下所缓存的内容是什么。您可能缓存了错误的内容。
确定缓存效率的另一种方法是查看缓存的命中率(hit ratio)。缓存命中率表示执行 get 的次数与错过 get 的次数的百分比。要确定这个百分比,需要再次运行 stats 命令,如清单 8 所示:
清单 8. 计算缓存命中率
stats
STAT pid 6825
STAT uptime 540692
STAT time 1249252262
STAT version 1.2.6
STAT pointer_size 32
STAT rusage_user 0.056003
STAT rusage_system 0.180011
STAT curr_items 595
STAT total_items 961
STAT bytes 4587415
STAT curr_connections 3
STAT total_connections 22
STAT connection_structures 4
STAT cmd_get 2688
STAT cmd_set 961
STAT get_hits 1908
STAT get_misses 780
STAT evictions 0
STAT bytes_read 5770762
STAT bytes_written 7421373
STAT limit_maxbytes 536870912
STAT threads 1
END
现在,用 get_hits 的数值除以 cmd_gets。在本例中,您的命中率大约是 71%。在理想情况下,您可能希望得到更高的百分比 — 比率越高越好。查看统计数据并不时测量它们可以很好地判定缓存策略的效率。
[常有命令如下:]
启动/结束
memcached -d -m 10 -u root -l 192.168.0.122 -p 11200 -c 256 -P /tmp/memcached.pid
-d 选项是启动一个守护进程,
-m 是分配给Memcache使用的内存数量,单位是MB,这里是10MB
-u 是运行Memcache的用户,这里是root
-l 是监听的服务器IP地址,如果有多个地址的话,这里指定了服务器的IP地址192.168.0.122
-p 是设置Memcache监听的端口,这里设置了12000,最好是1024以上的端口
-c 选项是最大运行的并发连接数,默认是1024,这里设置了256,按照你服务器的负载量来设定
-P 是设置保存Memcache的pid文件
kill `cat /tmp/memcached.pid`
获取运行状态
echo stats | nc 192.168.1.123 11200
watch "echo stats | nc 192.168.1.123 11200" (实时状态)
1。memcached的连接函数(connect, pconnect)
2。memcahced的操作函数(set, get, delete, replace, flush)
3。多服务器配置函数(addServer)
4。状态监控函数(getStats.....)
[安装多个memcached]
sc create "Memcached Server1" start= auto binPath= "C:\memcached\memcached.exe -d runservice -m 32 -p 11220 -l 127.0.0.1" DisplayName= "Memcached Server1"
下面是启动、停止、卸载该服务的命令:
sc start "Memcached Server1" //启动
sc stop "Memcached Server1" //停止
sc delete "Memcached Server1" //卸载该服务
分布式memcached测试:
<?php
//我的电脑上有两个memcahced服务.
$mem=new Memcache;
$mem->addServer('127.0.0.1',11211);
$mem->addServer('127.0.0.1',11221);
$mem->addServer('127.0.0.1',11220);
//这里注意,把key1,放入到 11211端口的mem还是
//9999 端口的mem就不要我们操心,有$mem对象本身维护.
if($mem->set('key1','hello',MEMCACHE_COMPRESSED,300)){
echo 'add ok!';
}
if($mem->set('key2','hello2',MEMCACHE_COMPRESSED,300)){
echo 'add ok!';
}
if($mem->set('key3','hello3',MEMCACHE_COMPRESSED,300)){
echo 'add ok!';
}
?>
总结:
1. mem服务的数据不是同步的, 数据是分布的
2. 把什么数据放入到哪个memcached是由客户端的mem对象决定
3. 当执行addServer的时候,并不是立即去连接mem服务,而是通过计算,hash后才去决定连接哪个mem服务,因此当你大量加入服务器到连接池,没有多余开销
相关文章推荐
- 深度学习FPGA实现基础知识9(Deep Learning(深度学习)Matlab工具箱下载、安装、测试)
- 【推荐】Nginx基础知识之————多模块(非覆盖安装、RTMP在线人数实例安装测试)
- 软件测试的基础知识概要介绍
- 软件测试的基础知识概要介绍
- 教你安装所有类型的游戏(新手必读)(游戏不能玩怎么办) 基础知识大放送 - 手机游戏-Nokia.索爱.小中屏176*220版 - 手机游戏 |手机游戏下载|3GP下载|电子书下载|蚂蚁爬爬手机论坛 - Powered by Discuz!
- 《软件测试管理》第14章 软件测试常见问题——(一)基础知识部分
- 《软件测试管理》第14章 软件测试常见问题——(一)基础知识部分
- YY指针堆栈,测试你的基础知识。(csdn)
- 《软件测试管理》第14章 软件测试常见问题——(一)基础知识部分
- 《软件测试管理》第14章 软件测试常见问题——(一)基础知识部分
- 《软件测试管理》第14章 软件测试常见问题——(一)基础知识部分
- 软件测试常见问题——(一)基础知识部分(转贴)
- [Ref]软件测试基础知识
- cfengine的基础安装和测试 推荐
- SQL Server 索引基础知识(3)----测试中一些常看的指标和清除缓存的方法
- 软件测试基础知识复习
- 新手软件测试基础知识汇总
- 带你走入Debian--第一部分.基础知识和安装
- 软件测试基础知识复习
- 软件测试:软件测试的基础知识概要介绍