緩存更新主要有如下幾種方案:php
1,檢測是否過時,是則加鎖去更新緩存(防緩存雪崩鎖主要在該場景下出現)redis
2,主動更新緩存(該方式理論如此,可是具體實現須要依據具體場景,不見得最優)緩存
3,緩存時間加隨機數,避免同一時間出現大量緩存過時現象(這裏的一個問題是須要去尋找最優的隨機範圍)測試
4,歡迎補充。。。this
這裏的鎖方法實現,是對基於 redis 的方案一而言的,不妥之處還請指正!code
鎖代碼以下:get
/** * @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"); }
調用方式以下:string
$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 測試經過,歡迎交流!io
參考連接:http://redis.io/commands/setnx function