Memcached是一个免费的开源的、高性能的、具备又分布式内存对象的缓存系统,它经过减轻数据库负载加速动态WEB应用,php
(1)、检查客户端请求的数据是在Memcached中存在,若是存在,直接把请求的数据返回,再也不对数据进行任何操做。git
(2)、若是请求的数据再也不Memcache中,就去查询数据库,把从数据库中获取的数据返回给客户端,同时把数据缓存一份到Memcahe中github
(3)、每次更新数据库(若是更新、删除数据库的数据)的同时更新Memcache中的数据,保证Memcache中的数据数据库中的数据一致。算法
(4)、当分配的Memcache内存空间用完以后,会使用LRU(Least Recetnly Used 最近最少使用数据库
)策略加到期失效策略,失效的数据首先被替换掉,而后再替换掉最近使用的数据.数组
Memcached做为高性能的缓存服务器,具备以下特征:缓存
(1)、协议简单服务器
Memcahed的协议实现比较简单,使用的是基于文本的协议,能直接经过telnet在服务器上存取数据.网络
(2)、基于libevent的处理并发
Libevent使一套利用C开发的程序库,它将BSD系统kqueue Linux系统的epoll等事件处理功能封装成一个接口,确保即便服务端的连接数增长也能发挥很好的性能.Memcached利用这个库进行异步事件处理。
(3)、内置的内存管理方式
当内存但终得数据空间沾满时,使用LRU算法自动删除不使用的缓存,即重用过时数据的内存空间,Memcahed的为缓存系统设计的.没有考虑数据的容灾问题,和机器的内存同样,重启机器数据将会丢失
(4)、互不通讯的Memcached之间有分布特征。
各个Memcahed服务器之间相互不通讯,都是独立的存取数据,不共享任何信息,经过对客户端的设计,让Memcahed具备分布式,能支持海量缓存的大规模一个应用.
memcached尽管是“分布式”缓存服务器,但服务器端并无分布式功能。各个memcached不会互相通讯以共享信息。那么,怎样进行分布式呢?这彻底取决于客户端的实现。本文也将介绍memcached的分布式。
Memcahed 是一种C/S模式,在服务器端启动服务守护进程,此时能够指定监听的IP地址,首先 memcached 是以守护程序方式运行于一个或多个服务器中,随时接受客户端的链接操做,客户端能够由各类语言编写,目前已知的客户端 API 包括 Perl/PHP/Python/Ruby/Java/C#/C 等等。客户端在与 memcached 服务创建链接以后,接下来的事情就是存取对象了,每一个被存取的对象都有一个惟一的标识符 key,存取操做均经过这个 key 进行,保存到memcached 中的对象其实是放置内存中的,并非保存在 cache 文件中的,这也是为何 memcached 可以如此高效快速的缘由。注意,这些对象并非持久的,服务中止以后,里边的数据就会丢失。
与许多 cache 工具相似,Memcached 的原理并不复杂。它采用了C/S的模式,在 server 端启动服务进程,在启动时能够指定监听的 ip,本身的端口号,所使用的内存大小等几个关键参数。一旦启动,服务就一直处于可用状态。Memcached 的目前版本是经过C实现,采用了单进程,单线程,异步I/O,基于事件 (event_based) 的服务方式.使用libevent 做为事件通知实现。多个 Server 能够协同工做,但这些 Server 之间是没有任何通信联系的,每一个 Server 只是对本身的数据进行管理。Client 端经过指定 Server 端的 ip 地址(经过域名应该也能够)。须要缓存的对象或数据是以 key->value对的形式保存在Server端。key 的值经过 hash 进行转换,根据 hash 值把 value 传递到对应的具体的某个 Server 上。当须要获取对象数据时,也根据 key 进行。首先对 key 进行 hash,经过得到的值能够肯定它被保存在了哪台 Server 上,而后再向该 Server 发出请求。Client 端只须要知道保存 hash(key) 的值在哪台服务器上就能够了。
其实说到底,memcache 的工做就是在专门的机器的内存里维护一张巨大的 hash 表,来存储常常被读写的一些数组与文件,从而极大的提升网站的运行效率。
Memcache用到了libevent这个库用于Socket的处理,因此还须要安装libevent。(若是你的系统已经安装了libevent,能够不用安装
#wget http://cloud.github.com/downloads/libevent/libevent/libevent-2.0.21-stable.tar.gz
# ls /usr/lib | grep libevent
# mkdir /opt/tmp && cd /opt/tmp
# mv /libevent-2.0.21-stable.tar.gz /opt/tmp
# tar -xvf libevent-2.0.21-stable.tar.gz
# cd libevent-2.0.21-stable
# ./configure --prefix=/usr && make && make install
# wget http://www.danga.com/memcached/dist/memcached-1.4.0.tar.gz
# tar -xvf memcached-1.4.0.tar.gz && cd memcached-1.4.0
# ./configure --with-libevent=/usr && make && make install
# ls -al /usr/local/bin/memcached 检测是否安装成功
/usr/local/bin/memcached -d -m 10 -u root -l 127.0.0.1 -p 12000 -c 512 -P /tmp/memcached.pid
-d选项是启动一个守护进程,
-m是分配给Memcache使用的内存数量,单位是MB,我这里是10MB,正常来讲都分1024或者根据业务来分
-u是运行Memcache的用户,我这里是root,
-l是监听的服务器IP地址,若是有多个地址的话,我这里指定了服务器的IP地址192.168.0.200,
-p是设置Memcache监听的端口,我这里设置了12000,最好是1024以上的端口,
-c选项是最大运行的并发链接数,默认是1024,我这里设置了256,按照你服务器的负载量来设定,
-P是设置保存Memcache的pid文件,我这里是保存在 /tmp/memcached.pid
这说明没有找到文件:libevent-1.2.so.1解决办法以下:
/usr/local/bin/memcached: error while loading shared libraries: libevent-2.0.so.5: cannot open shared object file: No such file or directory
# ln -s /usr/lib/libevent-2.0.so.5 /usr/lib64/libevent-2.0.so.5
# telete 127.0.0.1 12000
# telnet 127.0.0.1 12000
set test 0 0 3 向test当中存储数据
123 输入的key为test存入数据
STORED 返回set结果
get test 获取数据
VALUE test 0 3
123 取得key为test中的数据
incr test 1 数据 增长1
124
decr test 2 数据减小2
122
quit
>status
pid Process id of this server process (memcache服务器的进程ID)
uptime Number of seconds this server has been running (服务器已经运行的秒数)
time Current UNIX time according to the server (服务器当前的UNIX时间)
version Version string of this server (memcache版本)
pointer_size Current system pointer 当前操做系统的指针大小(32位系统通常是32bit)
rusage_user Accumulated user time for this process (该进程累计的用户时间(秒:微妙))
rusage_system Accumulated system time for this process (该进程累计的系统时间(秒:微妙))
curr_items Current number of items stored by the server (服务器当前存储的内容数量)
total_items Total number of items stored by this server ever since it started (服务器启动以来存储过的内容总数)
bytes Current number of bytes used by this server to store items (服务器当前存储内容所占用的字节数)
curr_connections Number of open connections (当前打开着的链接数量)
total_connections Total number of connections opened since the server started running (服务器运行以来接受的链接总数)
connection_structures Number of connection structures allocated by the server (服务器分配的链接结构的数量)
cmd_get Cumulative number of retrieval requests (get命令(获取)总请求次数)
cmd_set Cumulative number of storage requests (set命令(保存)总请求次数)
get_hits Number of keys that have been requested and found present (请求成功的总次数)
get_misses Number of items that have been requested and not found (请求失败的总次数)
threads Current number of thread (当前线程数)
bytes_read Total number of bytes read by this server from network (服务器从网络读取到的总字节数)
bytes_written Total number of bytes sent by this server to network (服务器向网络发送的总字节数)
limit_maxbytes Number of bytes this server is allowed to use for storage. (服务器在存储时被容许使用的字节总数)
evictions Number of valid items removed from cache to free memory for new items (为获取空闲内存而删除的items数(分配给memcache的空间用满后须要删除旧的items来获得空间分配给新的items))
其中,最关注最多的几个参数:
uptime:是memcached运行的秒数。
cmd_get:是查询缓存的次数。
cmd_get/uptime 结果是平均每秒请求缓存的次数——结果值越大,说明Memcached的利用率越高,站点的访问量大,若是过低,用文件系统缓存就能够了,根本不会体现出使用memcached的强大性能。
cmd_set:是设置key=>value的次数。整个memcached是个大hash,用cmd_get没有找到的内容,就会调用一下cmd_set写进缓存里。
get_hits:是缓存命中的次数。所谓的命中率 = get_hits/cmd_get * 100%。
get_misses:是缓存未命中的次数。get_misses加上get_hits就等于cmd_get。
stats:显示服务器信息、统计数据等
stats reset:清空统计数据
stats slabs:显示各个slab的信息,包括chunk的大小、数目、使用状况等
stats items:显示各个slab中item的数目和存储时长(最后一次访问距离如今的秒数)
quit:退出
# kill `cat /tmp/memcached.pid`
一般较小的应用一台Memcached服务器就能够知足需求,可是大中型项目可能就须要多台Memcached服务器了,这就牵涉到一个分布式部署的问题。
对于多台Memcached服务器,怎么肯定一个数据应该保存到哪台服务器呢?有两种方案,一是普通Hash分布,二是一致性Hash分布。下面详细说明。
跟DB的Amoeba同样这里经过Hash算法后进行取模 % 2
分布到 server1
server2
<?php
/**
* 普通Hash分布
*/
//Hash函数
function mHash($key){
$md5 = substr(md5($key), 0, 8);
$seed = 31;
$hash = 0;
for($i = 0; $i < 8; $i++){
$hash = $hash * $seed + ord($md5{$i});
$i++;
}
return $hash & 0x7FFFFFFF;
}
//假设有2台Memcached服务器
$servers = array(
array('host' => '192.168.1.1', 'port' => 11211),
array('host' => '192.168.1.1', 'port' => 11211)
);
$key = 'MyBlog';
$value = 'http://blog.phpha.com';
$sc = $servers[mHash($key) % 2];
$memcached = new Memcached($sc);
$memcached->set($key, $value);
?>