分布式缓存系统Memcache
一、基本概念
1. 缘起:
在数据驱动的web开发中,经常要重复从数据库中取出相同的数据,
这种重复极大的增加了数据库负载。缓存是解决这个问题的好办法。
但是Web中的虽然已经可以实现对页面局部进行缓存,但还是不够灵活。
此时Memcached或许是你想要的。
2. Memcached是什么?
Memcached是由Danga Interactive开发的,高性能的,分布式的内存对象缓存系统,
用于在动态应用中减少数据库负载,提升访问速度。
3. Memcached能缓存什么?
通过在内存里维护一个统一的巨大的hash表,Memcached能够用来存储各种格式的数据,
包括图像、视频、文件以及数据库检索的结果等。
4. Memcached快么?
非常快。Memcached使用了libevent(如果可以的话,在linux下使用epoll)
来均衡任何数量的打开链接,使用非阻塞的网络I/O,对内部对象实现引用计数
(因此,针对多样的客户端,对象可以处在多样的状态),使用自己的页块分配器和哈希表,
因此虚拟内存不会产生碎片并且虚拟内存分配的时间复杂度可以保证为O(1)。
Danga Interactive为提升Danga Interactive的速度研发了Memcached。
目前,LiveJournal.com每天已经在向一百万用户提供多达两千万次的页面访问。
而这些,是由一个由web服务器和数据库服务器组成的集群完成的。
Memcached几乎完全放弃了任何数据都从数据库读取的方式,同时,
它还缩短了用户查看页面的速度、更好的资源分配方式,以及Memcache失效时对数
据库的访问速度。
5. Memcached的特点
Memcached的缓存是一种分布式的,可以让不同主机上的多个用户同时访问,
因此解决了共享内存只能单机应用的局限,更不会出现使用数据库做类似事情的时候,
磁盘开销和阻塞的发生。
二、安装:
1. Windows下操作:
1.1 在网上下载memcached-1.2.1-win32.zip。解压放某个盘下面,比如在c:\memcached
1.2 在终端(cmd)下:
D:\>memcached.exe -d install 安装
D:\>memcached.exe -d uninstall 卸载
D:\>memcached.exe -d start 启动
D:\>memcached.exe -d stop 停止
1.3 在启动之后连接:
D:\> telnet 127.0.0.1 11211 --连接memcache端口11211
使用quit退出。
1.4 其他命令参数:
启动Memcache 常用参数
-p <num> 设置端口号(默认不设置为: 11211)
-U <num> UDP监听端口(默认: 11211, 0 时关闭)
-l <ip_addr> 绑定地址(默认:所有都允许,无论内外网或者本机更换IP,有安全隐患,若设置为127.0.0.1就只能本机访问)
-d 独立进程运行
... -d start 启动memcached服务
... -d restart 重起memcached服务
... -d stop|shutdown 关闭正在运行的memcached服务
... -d install 安装memcached服务
... -d uninstall 卸载memcached服务
-u <username> 绑定使用指定用于运行进程<username>
-m <num> 允许最大内存用量,单位M (默认: 64 MB)
-P <file> 将PID写入文件<file>,这样可以使得后边进行快速进程终止, 需要与-d 一起使用
-M 内存耗尽时返回错误,而不是删除项
-c 最大同时连接数,默认是1024
-f 块大小增长因子,默认是1.25
-n 最小分配空间,key+value+flags默认是48
-h 显示帮助
三、memcached的命令
连接 telnet 127.0.0.1 11211 如果找不到telnet:控制面板/程序与功能/打开或关闭Windows功能/找到Telnet服务器、Telnet客户端两项勾选上。
注意:或者通过xshell连接,端口是11211
1.【错误指令】
Memcache的协议的错误部分主要是三个错误提示之提示指令:
ERROR -- 普通错误信息,比如指令错误之类的
CLIENT_ERROR <错误信息> -- 客户端错误
SERVER_ERROR <错误信息> --服务器端错误
2.【数据操作命令】
格式:<命令> <键> <标记> <有效期> <数据长度>
其中:
<键> -key,是发送过来指令的key内容
<标记> - flags,是调用set指令保存数据时候的flags标记
有效期:是数据在服务器上的有效期限,如果是0,则数据永远有效,单位是秒
数据的长度,block data 块数据的长度,一般在这个个长度结束以后下一行跟着block data数据内容,
发送完数据以后,客户端一般等待服务器端的返回,服务器端的返回:
STORED 数据保存成功
NOT_STORED 数据保存失败,是因为服务器端这个数据key已经存在
2.1 添加数据
格式:add 变量名 标记位 时间 长度
例: add one 1 100000 10
1234567890
3. 获取 get 变量名
get one
get <键>*
<键>* - key
key是是一个不为空的字符串组合,发送这个指令以后,等待服务器的返回。如果服务器端没有任何数据,则是返回:
END
4. 修改 set|replace 变量名 标记位 时间(秒) 长度
5. delete <键> <超时时间>
<键> - key,希望在服务器上删除数据的key键
<超时时间> - timeout
按照秒为单位,这个是个可选项,如果没有指定这个值,那么服务器上key数据将马上被删除,
如果设置了这个值,那么数据将在超时时间后把数据清除,该项缺省值是0,就是马上被删除
删除数据后,服务器端会返回:
DELETED 删除数据成功
NOT_FOUND 这个key没有在服务器上找到.
6. flush_all 这个指令执行后,服务器上所有缓存的数据都被删除,并且返回:OK
7. stats items 看选项号
stats cachedump 选项号 (0|n)
只能看到变量, 值使用 get获取
8. memcache的运行状态可以方便的用stats命令显示。
首先用telnet 127.0.0.1 11211这样的命令连接上memcache,
然后直接输入stats就可以得到当前memcache的状态。
这些状态的说明如下:
Pid memcache服务器的进程ID
uptime 服务器已经运行的秒数
Time 服务器当前的unix时间戳
version memcache版本
pointer_size 当前操作系统的指针大小(32位系统一般是32bit)
rusage_user 进程的累计用户时间
rusage_system 进程的累计系统时间
curr_items 服务器当前存储的items数量
Total_items 从服务器启动以后存储的items总数量
Bytes 当前服务器存储items占用的字节数
curr_connections 当前打开着的连接数
Total_connections 从服务器启动以后曾经打开过的连接数
connection_structures 服务器分配的连接构造数
cmd_get get命令(获取)总请求次数
cmd_set set命令(保存)总请求次数
get_hits 总命中次数
get_misses 总未命中次数
evictions 为获取空闲内存而删除的items数(分配给memcache的空间用满后需要删除旧的items来得到空间分配给新的items)
Bytes_read 总读取字节数(请求字节数)
Bytes_written 总发送字节数(结果字节数)
Limit_maxbytes 分配给memcache的内存大小(字节)
threads 当前线程数
在php里也可以用getStats()来查看。
四、 PHP如何使用
注意:在使用Memcache前需要开启php的支持
1. 将php_memcache.dll模块文件复制到php的ext/目录下
2. 在php.ini中设置支持php_memcache.dll
extension=php_memcache.dll
3. 重启Apache服务
测试访问phpinfo()
$mm=new Memcache(); //创建对象
$mm->addServer("127.0.0.1", 11211);//连接服务器
$mm->add(string $key , mixed $var [, int $flag [, int $expire ]]); //添加数据
其中:
$mem->add("var_1", "this is a test", MEMCACHE_COMPRESSED, 10000);
$mem->add("var_2", array("aaa", "bbb", "ccc"), MEMCACHE_COMPRESSED, 10000);
class Person{
var $name="zhangsan";
var $age=10;
}
$mem->add("var_3", new Person(), MEMCACHE_COMPRESSED, 10000);
print_r($mem->get("var_1"));
echo '<br>';
var_dump($mem->get("var_2"));
echo '<br>';
var_dump($mem->get("var_3"));
echo '<br>';
$mem->close();