大家都知道,数据库有分布式存储,有没有分布式缓存呢?肯定有!
下面来说一下 分布式缓存memcache 他可以大大的减轻 数据库的读压力,我主要是说在读这方面,当然在写方面也有相同功能,但是大多数情况下,我们的负载压力还是在读方面。
下面来说一下实现原理,数据库的缓存是通过 一个HASH运算来实现的,query的数据放在一个cache中,而query通过HASH 运算得到一个HASH值。存放HASH 值的 链表节点除了存放相应的HASH值外,还要存放相应的query 所对应的结果集的地址,当查询时如过query 的hash值能在链表中找到,那么就直接从缓存中取数据,如果没有则会访问物理文件,同时将该查询缓存到缓存池中,以便第二次访问时,能直接存放,这里需要注意,当数据库中的数据变化时,query就会失效!
同样memcache也运用了相似的原理,不同的是你需要自己手动的添加到缓存中,memcache主要用在两个场景中,1缓解数据库读压力,2用来存放会话数据!
需要注意你的memcache服务器的访问没有任何限制,也就是只要客户知道你的IP,可以直接访问你缓存的数据,但是如果你缓存的session,那么你的客户资料可能会泄露!所以memcache服务器 最好不要设置为和你的apache同一个服务器。设置为单独的服务器同样有风险
那么你可以通过设置memcache服务器的防火墙,只允许apache服务器访问,具体的某个协议来访问等
下面关于一些具体的使用
安装很容易,但是要注意如果你在linux下,先要安装libevent,因为memcache是基于libevent触发的,安装完了后就要启动
windows
Memcached.exe –d -m 50 –l 127.0.0.1 -p 11211 start
linux
memcached -d -m 50 -llocalhost -p11211 -u
具体参数可以参考手册
-p 监听的端口
-l 连接的IP地址, 默认是本机
-d start 启动memcached服务
-d restart 重起memcached服务
-d stop|shutdown 关闭正在运行的memcached服务
-d install 安装memcached服务
-d uninstall 卸载memcached服务
-u 以的身份运行 (仅在以root运行的时候有效)
-m 最大内存使用,单位MB。默认64MB ,最大好像2G
-M 内存耗尽时返回错误,而不是删除项
-c 最大同时连接数,默认是1024
-f 块大小增长因子,默认是1.25
-n 最小分配空间,key+value+flags默认是48
-h 显示帮助
连接后就可以用了
以命令行的形式访问
Command | Description | Example |
get | Reads a value | get mykey |
set | Set a key unconditionally | set mykey 0 60 5 |
add | Add a new key | add newkey 0 60 5 |
replace | Overwrite existing key | replace key 0 60 5 |
append | Append data to existing key | append key 0 60 15 |
prepend | Prepend data to existing key | prepend key 0 60 15 |
incr | Increments numerical key value by given number | incr mykey 2 |
decr | Decrements numerical key value by given number | decr mykey 5 |
delete | Deletes an existing key | delete mykey |
不多讲 大家可以telnet 访问以下,需注意的是windows7 下默认是没有开启telnet的 你需要手动开启此服务
memcache 基于对象的方法
具体可以参考PHP手册 “LXXXIV. Memcache Functions” 这章。
Memcache面向对象的常用接口包括:
Memacache:bool Memcache::add ( string $key , mixed $var [, int $flag [, int $expire ]] )--添加一个值
Memcache::bool Memcache::connect ( string $host [, int $port [, int $timeout ]] )-- 打开一个到Memcache的连接
Memcache::pconnect -- 打开一个到Memcache的长连接参数同上
Memcache::close -- 关闭一个Memcache的连接
Memcache::bool Memcache::set ( string $key , mixed $var [, int $flag [, int $expire ]] ) -- 保存数据到Memcache服务器上
Memcache::get ( string $key [, int &$flags ] )-- 提取一个保存在Memcache服务器上的数据,其中的第一,第二个参数都可以是数组,只要相应的只对应就可以
以下 就不写具体参数了,具体可以差文档
Memcache::replace -- 替换一个已经存在Memcache服务器上的项目(功能类似Memcache::set)
Memcache::delete -- 从Memcache服务器上删除一个保存的项目
Memcache::flush -- 刷新所有Memcache服务器上保存的项目(类似于删除所有的保存的项目),一单刷因就没有了,相当于清空
Memcache::getStats -- 获取当前Memcache服务器运行的状态
Memcache::addServer -- 分布式服务器添加一个服务器
函数的具体参数
下面给一个具体事例
<?php
$mem=new Memcache;
$mem->connect("localhost", 11211);
/*
* 注意:
* 1. 同一个项目安装两次,key要有前缀
*
*
*/
$sql="select * from shops";
$key=substr(md5($sql), 10, 8);
$data=$mem->get($key);
if(!$data){
$mysqli=new mysqli("localhost", "root", "123456", "xsphpdb");
$result=$mysqli->query($sql);
$data=array();
while($row=$result->Fetch_assoc()){
$data[]=$row;
}
$result->free();
$mysqli->close();
$mem->set($key, $data, MEMCACHE_COMPRESSED, 3600);
echo $sql;
}
echo '<pre>';
print_r($data);
echo '</pre>';
$mem->close();
为了区别在一个服务器上有多个实例,防止变量重名,我们一般用query语句作为键值,最好是加密一下,同时在程序中控制,如果在memcacahe缓村服务器中找不到,就从数据库中找,并且当你从服务器中找时,你需要吧相应的数据添加到memcache服务器中,这样就和数据库的缓存基本相同了
另外,memcache可以 和mysql整合为一个整体,这里我不怎么了解,但是整合了后效率应该比在应用程序中会高一些!