一、memcache概述
1、memcache就是一个数据库、但是数据存在内存中。常用来做缓存服务器、将从数据库查询的数据缓存起来,减少数据库查询、加快查询速度。
2、明确使用场景:缓存服务器
3、适合存储的数据:
①访问比较频繁的数据,安全性差的数据,丢失无所谓的数据。
②数据更新,比较频繁的数据,比如用户的在线状态。
③数据的单个键值不能太大,不要超过1Mb数据。
二、通过putty操作memcached
【memcached手册:http://www.runoob.com/memcached/memcached-tutorial.html】
1、增/改键(set
)
语法:set 键 额外信息 缓存时间 数据长度
键:名称不能超过250字符
额外信息:客户机使用它存储关于键值对的额外信息(注:整型参数)
缓存时间:0-理论永久,其他-单位秒(注:最大存储时间30天)
数据长度:写数字,单位字节(注:①单个键最大存储数据为1M②回车输入具体内容)
说明:键存在则修改,键不存在则创建
2、获取键值(get
)
语法:get 键
3、添加键数据(add
)
语法:add 键 是否压缩 缓存时间/s 数据长度/字节
说明:只能添加不能修改
4、修改键数据(replace
)
语法:replace 键 是否压缩 缓存时间/s 数据长度/字节
说明:只能修改不能添加
5、删除键(delete
)
语法:delete 键
6、删除所有键(flush_all
)
语法:flush_all
7、递增(incr
)和递减(decr
)
语法:incr 键 数字
语法:decr 键 数字
说明:返回增长后的结果,键必须存在
8、查看当前Memcached运行状态(stats
)
pid: memcache服务器进程ID
uptime: 服务器已运行秒数
time: 服务器当前Unix时间戳
version: memcache版本
pointer_size: 操作系统指针大小
rusage_user: 进程累计用户时间
rusage_system: 进程累计系统时间
curr_connections: 当前连接数量
total_connections: Memcached运行以来连接总数
connection_structures: Memcached分配的连接结构数量
cmd_get: get命令请求次数
cmd_set: set命令请求次数
cmd_flush: flush命令请求次数
get_hits: get命令命中次数
get_misses: get命令未命中次数
delete_misses: delete命令未命中次数
delete_hits: delete命令命中次数
incr_misses: incr命令未命中次数
incr_hits: incr命令命中次数
decr_misses: decr命令未命中次数
decr_hits: decr命令命中次数
cas_misses: cas命令未命中次数
cas_hits: cas命令命中次数
cas_badval: 使用擦拭次数
auth_cmds: 认证命令处理的次数
auth_errors: 认证失败数目
bytes_read: 读取总字节数
bytes_written: 发送总字节数
limit_maxbytes: 分配的内存总大小(字节)
accepting_conns:服务器是否达到过最大连接(0/1)
listen_disabled_num: 失效的监听数
threads: 当前线程数
conn_yields: 连接操作主动放弃数目
bytes: 当前存储占用的字节数
curr_items: 当前存储的数据总数
total_items: 启动以来存储的数据总数(包括过期的)
evictions: LRU释放的对象数目
reclaimed: 已过期的数据条目来存储新数据的数目
三、php操作memcached
【官方手册:https://secure.php.net/manual/zh/memcache.set.php】
常用操作
创建mem对象:$mem = new Memcache;
连接服务器: $mem->connect(服务ip地址,端口);
关闭服务器: $mem->close();
设置数据: $mem->set(键,值 [,是否压缩,缓存时间])
【注:缓存时间不设置默认为永久,设置为0也为永久,如果设置其它时间则不能超过30天】
获取数据: $mem->get(键);
递增: $mem->incrment(键,数字);
递减: $mem->decrment(键,数字);
//1、创建mem对象
$mem = new Memcache;
//2、连接mem服务
$mem->connect('localhost',11211);
//3、设置
$rs = $mem->set('hsz',666);
var_dump($rs);
echo "<hr />";
//4、获取
$rs = $mem->get('hsz');
var_dump($rs);
四、memcache能存储的数据类型
使用php可以存储到memcache的数据类型
//1.创建memcache对象
$mem = new memcache;
//2.连接服务
$mem->connect('localhost', 11211);
//3.设置服务
//①整型
$rs = $mem->set('v1', 8);
var_dump($rs);
var_dump($mem->get('v1'));
echo '<br>';
//②浮点型
$rs = $mem->set('v2', 8.88);
var_dump($rs);
var_dump($mem->get('v2'));
echo '<br>';
//③布尔型
$rs = $mem->set('v3', true);
var_dump($rs);
var_dump($mem->get('v3'));
echo '<br>';
//④字符串型
$rs = $mem->set('v4', 'abcdef');
var_dump($rs);
var_dump($mem->get('v4'));
echo '<br>';
//⑤数组型
$rs = $mem->set('v5', ['name'=>'张三', 'age'=>18]);
var_dump($rs);
var_dump($mem->get('v5'));
echo '<br>';
//⑥对象类型
class Cla
{
public $name = '张三';
public $age = 18;
public function show() {
return $this->name.$this->age;
}
}
$obj = new Cla;
$rs = $mem->set('v6', $obj);
var_dump($rs);
var_dump($mem->get('v6'));
echo '<br>';
//⑦空类型
$rs = $mem->set('v7', null);
var_dump($rs);
var_dump($mem->get('v7'));
echo '<br>';
//⑧资源类型
$handler = fopen('./abc.txt', 'rb');
$rs = $mem->set('v8', $handler);
var_dump($rs);
var_dump($mem->get('v8'));
echo '<br>';
结果如下:
使用putty查看memcache数据如下:
五、php代码实现分布式的memcache服务器
//1、创建memcahce对象
$mem = new Memcache;
//2、设置memcache服务器连接池
$mem->addServer('127.0.0.1', 11211);
$mem->addServer('192.168.165.56', 11211);
$mem->addServer('192.168.165.53', 11211);
//3、设置数据
$rs1 = $mem->set('abc_name', '张三');
$rs2 = $mem->set('abc_age', 18);
$rs3 = $mem->set('abc_sex', '男');
var_dump($rs1);
var_dump($rs2);
var_dump($rs3);
echo '<hr />';
var_dump($mem->get('abc_name'));
var_dump($mem->get('abc_age'));
var_dump($mem->get('abc_sex'));
六、memcache的相关算法
1、惰性过期机制(lazy expiration)
说明:memcached内部不会监视记录是否过期,而是在get时查看记录的时间戳,检查记录是否过期。这种技术被称为惰性过期
好处:减少监控过期产生的开销
2、最近最少使用算法(LRU:Least Recently Used)
缓存空间已满,采用LRU策略,
将使用频率最低数据进行删除
图示如下:
七、memcache常见问题
1、缓存雪崩
场景:项目缓存同一时间失效
问题:瞬间几万次,甚至几千万次的同时访问数据库,数据库崩溃
解决:
①不要集中设置缓存有效期
②控制缓存在闲时过期(如:夜间)
③主从复制,读写分离
2、永久数据被踢
原因:因为惰性过期机制和最近最少使用机制导致
解决:永久数据和非永久数据分开存放
八、实现session跨域共享&跨服务器共享
【通过session共享实现单点登录】
1、同一服务器下session跨域共享
2、利用memcache实现session跨服务器共享
使所有服务器设置的session都存储在同一个memcache服务器上,然后各个服务器需要session数据的时候都从这台memcache服务器上读取,从而实现session共享。【通过此种方式共享其它数据也同理】
#one.php代码
//开启session跨域,允许session共享
ini_set('session.cookie_domain','hsz.com');
//通过php的ini_set函数临时更改php配置文件
ini_set('session.save_handler', 'memcache');
ini_set('session.save_path', 'tcp://127.0.0.1:11211'); //ip可以写多个,使用","分隔
session_start();
$_SESSION['name'] = '张三';
echo session_id().'<br>';
print_r($_SESSION);
#two.php代码
//开启session跨域,允许session共享
ini_set('session.cookie_domain','hsz.com');
//通过php的ini_set函数临时更改php配置文件
ini_set('session.save_handler', 'memcache');
ini_set('session.save_path', 'tcp://127.0.0.1:11211');
session_start();
echo session_id().'<br>';
print_r($_SESSION);