原理:分布 场景 调优 | 缓存故障(雪崩 无底洞 数据踢除)
分布:一致性哈希+虚拟节点对缓存命中率的影响 &
memcache lru lazy_delete
应用:memached
确认主从延迟+秒杀
调优:
memcached
在启动时可以通过
f
选项指定
Growth Factor
因子
,
并在某种程度上控制
slab
之 间的差异
.
默认值为
1.25.
但是
,
在该选项出现之前
,
这个因子曾经固定为
2,
称为
”powers of 2”
策略。
缓存雪崩:节点失效
现象:某个节点失效,导致其他节点缓存命中率下降,缺失的数据连接数据库,服务器崩溃,重启后又崩溃,直至缓存重建完毕
方案:把缓存设置为随机
3
到
9
小时的生命周期
,
这样不同时失效
,
把工作分担到各个时间点
上去
.
缓存无底洞:数据分布
现象:节点增多,一个用户的信息被分布到多个节点,连接多个分布式库,导致连接效率下降了
方案:
把某一组
key,
按其共同前缀
,
来分布,使其落在同一个节点上
数据被踢:数据失效
现象:数据设为永久有效,但仍是被踢出了
方案:永久数据和非永久数据分开放,因为lru+lazy会挤占永久数据,
二、Memcached
// append prepend + getDelayed fetch fetchall + setMulti getMulti + addServers getServerByKey setByKey + cas--写锁的set setOptions
//set = add + replace
$m = new Memcached();
$m->addServer('127.0.0.1',11211);
$m->set('foo','bar');
$m->setOption(Memcached::OPT_COMPRESSION,false);
$m->append('foo','def');
$m->prepend('foo','000');
$mess = $m->get('foo');
$m->set('int',11);
$m->set('int',22);
$m->set('string','ok');
$m->set('hash','0xdsfdf');
$m->getDelayed(array('int','string'),true);
// while ($re = $m->fetch()) {
// print_r($re);
// }
$re = $m->fetchAll();
// print_r($re);
$items = array('key1'=>'val1','key2'=>'val2','key3'=>'val3');
$m->setMulti($items,true);
$mess = $m->getMulti(array('key1','key2','key3'),$cas);
//print_r($mess);
$m->addServers(array(
array('127.0.0.1',11211),
array('127.0.0.1',11212)
));
for ($i=0; $i <10 ; $i++) {
$key = 'key_'.$i;
$m->set($key,1);
}
for ($i=0; $i < 10; $i++) {
$key = 'key_'.$i;
$server = $m->getServerByKey($key);
// print_r($server);
}
$list = $m->getServerList();
// var_dump($list);
$m->setByKey('127.0.0.1','orderKey',1);
do {
$ips = $m->get('ip_block',null,$cas);//加上$cas后面才能用
if ($m->getResultCode()==Memcached::RES_NOTFOUND) {
$ips = $_SERVER['REMOTE_ADDR'];
$m->add('ip_block',$ips);
}else{
$m->cas($cas,'ip_block',$ips);//加了写锁的set
}
} while ($m->getResultCode()!=Memcached::RES_SUCCESS);
var_dump($ips);
//list
$r = new Redis;
$r->connect('127.0.0.1',6379);
echo '<pre>';
// $r->lpush('list','key1');
// $r->rpush('list','key2');
// $r->rpush('list','key3');
// $r->rpush('list','key5');
// $r->lpush('list2','2key1');
// $r->rpush('list2','2key2');
// $r->rpush('lis2t','2key3');
// $r->rpush('list2','2key5');
// $r->rp
// $r->linsert('list',Redis::BEFORE,'key1','def');
$range = $r->lrange('list',0,-1);
$range2 = $r->lrange('list2',0,-1);
// $trim = $r->ltrim('list',2,10);
$size = $r->lsize('list');
$lget = $r->lget('list',0);
// echo $size;
// var_dump($range);
$val = $r->rpoplpush('list','list2');
echo $val;
var_dump($range);
var_dump($range2);
//set
$r->sadd('set',123);
$r->sadd('set',456);
$r->sadd('set',789);
$r->srem('set',789);
$r->sadd('set2',123);
$r->sadd('set2',456);
$r->sadd('set2',789);
$r->smove('set2','set','789');
$set = $r->smembers('set');
$set2 = $r->smembers('set2');
$pop = $r->spop('set2');
$set2 = $r->smembers('set2');
echo '<pre>';
// echo $pop;
$num = $r->ssize('set');
$contain = $r->scontains('set','456');
$member = $r->srandMember('set');
// var_dump($member);
// var_dump($contain);
// echo $num;
var_dump($set);
// var_dump($set2);
$r->sadd('int',1);
$r->sadd('int',2);
$r->sadd('int',3);
$r->sadd('int',4);
$r->sadd('int',5);
$r->sadd('int',6);
$desc = $r->sort('int',array('sort'=>'desc'));
var_dump($desc);
$r->sadd('int2',5);
$r->sadd('int2',6);
$r->sadd('int2',7);
$r->sadd('int2',8);
$r->sadd('int2',9);
$r->sadd('int2',10);
$inter = $r->sinter('int','int2');
$uinon = $r->sunion('int','int2');
$diff = $r->sdiff('int2','int');
$diff = $r->sdiffstore('diffstore','int2','int');
// var_dump($inter);
// var_dump($uinon);
// var_dump($diff);
$re = $r->smembers('diffstore');
echo 'diffstore';
var_dump($re);
三、Memcache
set(key,val,compress,timeout) get delete flush flush_all close add replace
new connect
increment decrement
addServer(host,port,persist,weight,timeout,retry_intval,status,failecallback)
./memcached -m 256 -c 1000 -P -l 127.0.0.1 -p 11211 -u root -d /tmp/memcached.pid
getVersion getStats hit/cmd.. getExtendedStats getStatus
<?php
//curd+in/decr+hit+add+start
//./memcached -d -m 256 -u root -l localhost -p 11211 -c 512 -P /tmp/memcached.pid
$memcache = new Memcache();
$memcache->connect('localhost',11211);
// $version = $memcache->getVersion();
$memcache->flush();
//echo $version;
//存取 set get
$arr = array('key1'=>'val1','key2'=>'val2');
$memcache->set('KEY',$arr,true,10); //MEMCACHE_COMPRESSED or 0
$val = $memcache->get('KEY');
//print_r ($val);
//自增 set incr
if($s = $memcache->increment('a',1)){
echo $s;
}else{
$memcache->set('a',1,MEMCACHE_COMPRESSED,30);
}
//命中率
$status = $memcache->getStats();
$hit = ($status['get_hits']/$status['cmd_get'])*100;
$hit = $hit.'%';
// echo $hit;
//缓存图片
$test5= file_get_contents('http://127.0.0.1/linux.jpeg');
$memcache->set('test5',$test5);
$status = $memcache->getStats();
//echo '内存:'.$status['bytes'].'<br>';
//版本
$version = $memcache->getVersion();
// /echo $version;
//增删改 set get delete
$val = $memcache->set('name','susan',false,30);
if(!$memcache->add('name','susan',0,30)){
// echo 'susan will exists';
}
$memcache->replace('name','lion',0,300);
$name = $memcache->get('name');
// echo $name;
$memcache->delete('name',5);
// echo $memcache->get('name');
//连接失败回调
function _callback_memcache_failure($host, $port) {
echo "memcache '$host:$port' failed";
}
$memcache = new Memcache;
// // 增加一台离线服务器
// $memcache->addServer('memcache_host', 11211, false, 1, 1, -1, false);
// //在线
// $memcache->setServerParams('192.168.66.66', 11211, 1, 15, true, 5,1,'_callback_memcache_failure');
//在线 离线状态
$memcache->addServer('127.0.0.1', 11211, 1, 15, 5, 5,-1,'_callback_memcache_failure');
/* status
控制此服务器是否可以被标记为在线状态。设置此参数值为FALSE并且retry_interval参数
设置为-1时允许将失败的服务器保留在一个池中以免影响key的分配算法。对于这个服务器的
请求会进行故障转移或者立即失败, 这受限于memcache.allow_failover参数的设置。
该参数默认TRUE,表明允许进行故障转移。
*/
//获取服务器的在线离线状态
echo $memcache->getServerStatus('127.0.0.1', 11211);
//缓存服务器池中所有服务器统计信息
$stats = $memcache->getExtendedStats();
echo '<pre>';
print_r($stats);
/*
host
要连接的memcached服务端监听的主机位置。这个参数通常指定其他类型的传输比如Unix域套接字使用 unix:///path/to/memcached.sock,这种情况下参数port 必须设置为0。
port
要连接的memcached服务端监听的端口。当使用UNIX域套接字连接时设置为0。
persistent
控制是否使用持久化连接。默认TRUE。
weight
为此服务器创建的桶的数量,用来控制此服务器被选中的权重,单个服务器被选中的概率是相对于所有服务器weight总和而言的。
timeout
连接持续(超时)时间(单位秒),默认值1秒,修改此值之前请三思,过长的连接持续时间可能会导致失去所有的缓存优势。
retry_interval
服务器连接失败时重试的间隔时间,默认值15秒。如果此参数设置为-1表示不重试。此参数和persistent参数在扩展以 dl()函数动态加载的时候无效。
每个失败的连接结构有自己的超时时间,并且在它失效之前选择后端服务请求时该结构会被跳过。一旦一个连接失效, 它将会被成功重新连接或被标记为失败连接以在下一个retry_interval秒重连。 典型的影响是每个web服务子进程在服务于一个页面时将会每retry_interval秒 尝试重新连接一次。
status
控制此服务器是否可以被标记为在线状态。设置此参数值为FALSE并且retry_interval参数 设置为-1时允许将失败的服务器保留在一个池中以免影响key的分配算法。对于这个服务器的请求会进行故障转移或者立即失败, 这受限于memcache.allow_failover参数的设置。该参数默认TRUE,表明允许进行故障转移。
failure_callback
允许用户指定一个运行时发生错误后的回调函数。回调函数会在故障转移之前运行。回调函数会接受到两个参数,分别是失败主机的 主机名和端口号。
timeoutms
*/