缓存更新主要有以下几种方案:
1,检测是否过期,是则加锁去更新缓存(防缓存雪崩锁主要在该场景下出现)
2,主动更新缓存(该方式理论如此,但是具体实现需要依据具体场景,不见得最优)
3,缓存时间加随机数,避免同一时间出现大量缓存过期现象(这里的一个问题是需要去寻找最优的随机范围)
4,欢迎补充。。。
这里的锁方法实现,是对基于 redis 的方案一而言的,不妥之处还请指正!
锁代码如下:
/**
* @author koma<komazhang@foxmail.com>
*
* @param string $key
* @param intger $locktime
*
* @return boolean
**/
function lock($key, $locktime = 1)
{
global $redis;
$curtime = time();
$lockKey = "{$key}.lock";
$locktime = $curtime+$locktime+1;
if ( $redis->setNx($lockKey, $locktime) ) {
return true;
}
if ( ($redis->get($lockKey) < $curtime)
&& ($redis->getSet($lockKey, $locktime) < $curtime) ) {
return true;
}
return false;
}
/**
* @author koma<komazhang@foxmail.com>
*
* @param string $key
*
* @return null
**/
function release($key)
{
global $redis;
$redis->delete("{$key}.lock");
}
调用方式如下:
$redis = new Redis();
$redis->connect('192.168.1.10');
$key = "stream.01";
$data = "this is the content";
$expire = 60;
$curtime = time();
if ( !$redis->hExists($key, 'data') ) {
$redis->hSet($key, 'data', $data);
$redis->hSet($key, 'expire', $curtime+$expire);
}
if ( (intval($redis->hGet($key, 'expire')) < $curtime) && lock($key) ) { //out of time
//update the data
file_put_contents(dirname(__FILE__).'/log.txt', "=========================\n", FILE_APPEND);
file_put_contents(dirname(__FILE__).'/log.txt', "do update\n", FILE_APPEND);
sleep(5);
$redis->hSet($key, 'expire', $curtime+$expire);
//release the lock
release($key);
}
echo $redis->hGet($key, 'data');
本地通过 siege -c 500 -n 10 -bv http://www.localhost.me/redis/test.php 测试通过,欢迎交流!
参考链接:http://redis.io/commands/setnx