处理缓存失效时DB负载突然过高的问题

缓存的一个常见使用方式:先查缓存--未命中--查DB--写缓存。

   

if(!cacheUtil.getDataFromCache()){ //(1)
 	Object data = cacheUtil.getDataFromDB();//(2)
	cacheUtil.setDataToCache(data);
 }

 这种方式使用起来简单,但也存在比较大的问题。我们都知道缓存会设置一定的过期时间,一旦缓存过期,如果此时正好有大量的请求进来,会在代码(1)处出现大量并发,代码(2)处会使DB的压力瞬间增大。为了避免这样的情况出现,我们采取了以下措施:

      1.定期主动刷新缓存。使用定时任务来定时更新缓存,定时任务时间比缓存时间短,保证缓存永不过期;这种方案对于key值比较少且固定的数据来说比较适用。

      2.对缓存失效时的请求进行限流;1W个请求只处理先进来的100,后面的直接失败;

AtomicInteger cacheLock = new AtomicInteger(0);
 		if(!cacheUtil.getDataFromCache()){
 			if(cacheLock.incrementAndGet()<=100){
 				try{
 					Object data = cacheUtil.getDataFromDB();
 					cacheUtil.setDataToCache(data);
 				}finally{
 					cacheLock.decrementAndGet();
 				}
 			}else{
 				return;
 			}
 		}

 
  

       这个方案虽然控制了穿透到DB的请求数量,但是会导致大量请求失败,所以方案可以改成让一定数量的请求去走DB,而让其他请求等待。

        

猜你喜欢

转载自chenqunhui.iteye.com/blog/2286457