欧美亚洲中文,在线国自产视频,欧洲一区在线观看视频,亚洲综合中文字幕在线观看

      1. <dfn id="rfwes"></dfn>
          <object id="rfwes"></object>
        1. 站長(zhǎng)資訊網(wǎng)
          最全最豐富的資訊網(wǎng)站

          redis擊穿怎么解決

          redis擊穿怎么解決

          擊穿:指的是單個(gè)key在緩存中查不到,去數(shù)據(jù)庫(kù)查詢(xún),這樣如果數(shù)據(jù)量不大或者并發(fā)不大的話是沒(méi)有什么問(wèn)題的。

          如果數(shù)據(jù)庫(kù)數(shù)據(jù)量大并且是高并發(fā)的情況下那么就可能會(huì)造成數(shù)據(jù)庫(kù)壓力過(guò)大而崩潰

          注意:這里指的是單個(gè)key發(fā)生高并發(fā)!!! (推薦學(xué)習(xí):Redis視頻教程)

          解決方案:

          1) 通過(guò)synchronized+雙重檢查機(jī)制:某個(gè)key只讓一個(gè)線程查詢(xún),阻塞其它線程

          在同步塊中,繼續(xù)判斷檢查,保證不存在,才去查DB。

          例如:

           private static volaite Object lockHelp=new Object();    public String getValue(String key){      String value=redis.get(key,String.class);      if(value=="null"||value==null||StringUtils.isBlank(value){          synchronized(lockHelp){                 value=redis.get(key,String.class);                  if(value=="null"||value==null||StringUtils.isBlank(value){                       value=db.query(key);                       redis.set(key,value,1000);                   }             }            }             return value;    }

          缺點(diǎn): 會(huì)阻塞其它線程

          2) 設(shè)置value永不過(guò)期

          這種方式可以說(shuō)是最可靠的,最安全的但是占空間,內(nèi)存消耗大,并且不能保持?jǐn)?shù)據(jù)最新 這個(gè)需要根據(jù)具體的業(yè)務(wù)邏輯來(lái)做

          個(gè)人覺(jué)得如果要保持?jǐn)?shù)據(jù)最新不放這么試試,僅供參考:

          起個(gè)定時(shí)任務(wù)或者利用TimerTask 做定時(shí),每個(gè)一段時(shí)間多這些值進(jìn)行數(shù)據(jù)庫(kù)查詢(xún)更新一次緩存,當(dāng)然前提時(shí)不會(huì)給數(shù)據(jù)庫(kù)造成壓力過(guò)大(這個(gè)很重要)

          3) 使用互斥鎖(mutex key)

          業(yè)界比較常用的做法,是使用mutex。簡(jiǎn)單地來(lái)說(shuō),就是在緩存失效的時(shí)候(判斷拿出來(lái)的值為空),不是立即去load db,而是先使用緩存工具的某些帶成功操作返回值的操作(比如Redis的SETNX或者M(jìn)emcache的ADD)去set一個(gè)mutex key,當(dāng)操作返回成功時(shí),再進(jìn)行l(wèi)oad db的操作并回設(shè)緩存;否則,就重試整個(gè)get緩存的方法。

          SETNX,是「SET if Not eXists」的縮寫(xiě),也就是只有不存在的時(shí)候才設(shè)置,可以利用它來(lái)實(shí)現(xiàn)鎖的效果。在redis2.6.1之前版本未實(shí)現(xiàn)setnx的過(guò)期時(shí)間,所以這里給出兩種版本代碼參考:

          public String get(key) {       String value = redis.get(key);       if (value == null) { //代表緩存值過(guò)期           //設(shè)置3min的超時(shí),防止del操作失敗的時(shí)候,下次緩存過(guò)期一直不能load db           if (redis.setnx(key_mutex, 1, 3 * 60) == 1) {  //代表設(shè)置成功                value = db.get(key);                       redis.set(key, value, expire_secs);                       redis.del(key_mutex);                       return value;               } else {  //這個(gè)時(shí)候代表同時(shí)候的其他線程已經(jīng)load db并回設(shè)到緩存了,這時(shí)候重試獲取緩存值即可                       sleep(10);                       get(key);  //重試               }           } else {               return value;                 }  }

          贊(0)
          分享到: 更多 (0)
          網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)