在我们日常的系统中,经常有出现查询才能完成的业务,而此业务必不可少,例如排行数据。
我们一般的解决方法是缓存结果方法:定期一次查询,得到结果写到文件。
而这个定期查询是一般采用的是用户访问触发,而这个解决方法在系统的访问量比较低的时候,是能正常运行的。
但当系统的访问量达到一定的量级的时候(如日ip为 20w),就会出现并发的情况,就是非常多个人同时触发了定期更新排行数据,那么对于一个非常消耗资源的sql 同时产生,对数据库(如mysql等)肯定是致命的,非常多时候基本就down掉了的。
为了解决上面的问题,而根本问题就是并发,只要减少或者降低并发的机会,那么就可以解决这个问题了的。
看如下代码(php):
- $lastUpdateFile = ‘lastUpdateFile.time’;
- $updateingFile = ‘updateingFile.lock’;
- $lastUpdate = filectime($lastUpdateFile);
- $frequency = 1800;
- //note 在缓存到期前的3分钟起,就按20%随机几率随机抽取触发者,如果3分钟内都没有人触发缓存,那么当到缓存期的时候,第一个访问者肯定触发
- //note 在触发的生成缓存的时候,就必须确保没有人在触发更新缓存(!file_exists($updateingFile) || time()-filectime($updateingFile) > 300)
- $needUpdate = ((time()-$lastUpdate >$frequency-180) && mt_rand(1, 100) > 80 || time()-$lastUpdate >$frequency) && (!file_exists($updateingFile) || time()-filectime($updateingFile) > 300)? true : false;
- if($needUpdate) {
- touch($updateingFile);
- //do something and make cache
- //just like select data, insert data, makecachefile
- unlink($updateingFile);
- touch($lastUpdateFile);
- }
上面代码使用了在一定时间内随机触发缓存,把并发触发几率极大的降低,那么就解决了我们说的根本问题了。
