Redis緩存的幾大問題

1.緩存粒度控制

通俗來講,緩存粒度問題就是我們在使用緩存時,是將所有數據緩存還是緩存部分數據?

緩存粒度問題是一個容易被忽視的問題,如果使用不當,可能會造成很多無用空間的浪費,可能會造成網絡帶寬的浪費,可能會造成代碼通用性較差等情況,必須學會綜合數據通用性、空間佔用比、代碼維護性 三點評估取捨因素權衡使用。

2.緩存穿透問題

緩存穿透是指查詢一個一定不存在的數據,由於緩存不命中,並且出於容錯考慮, 如果從存儲層查不到數據則不寫入緩存,這將導致這個不存在的數據每次請求都要到存儲層去查詢,失去了緩存的意義。

可能造成原因:

1.業務代碼自身問題 2.惡意攻擊。爬蟲等等

危害

 對底層數據源壓力過大,有些底層數據源不具備高併發性。  例如mysql一般來說單臺能夠扛1000-QPS就已經很不錯了

解決方案

1.緩存空對象

```java
public class NullValueResultDO implements Serializable{
     private static final long serialVersionUID = -6550539547145486005L;
}
 
public class UserManager {
     UserDAO userDAO;
     LocalCache localCache;
 
     public UserDO getUser(String userNick) {
          Object object = localCache.get(userNick);
          if(object != null) {
               if(object instanceof NullValueResultDO) {
                    return null;
               }
               return (UserDO)object;
          } else {
               User user = userDAO.getUser(userNick);
               if(user != null) {
                    localCache.put(userNick,user);
               } else {
                    localCache.put(userNick, new NullValueResultDO());
               }
               return user;
          }
     }          
}
```

2.布隆過濾器

3.緩存擊穿.熱點key重建緩存問題

緩存擊穿是指緩存中沒有但數據庫中有的數據(一般是緩存時間到期),這時由於併發用戶特別多,同時讀緩存沒讀到數據,又同時去數據庫去取數據,引起數據庫壓力瞬間增大,造成過大壓力

我們知道,使用緩存,如果獲取不到,纔會去數據庫裏獲取。但是如果是熱點 key,訪問量非常的大,數據庫在重建緩存的時候,會出現很多線程同時重建的情況。因爲高併發導致的大量熱點的 key 在重建還沒完成的時候,不斷被重建緩存的過程,由於大量線程都去做重建緩存工作,導致服務器拖慢的情況。

解決方案

1.互斥鎖

第一次獲取緩存的時候,加一個鎖,然後查詢數據庫,接着是重建緩存。這個時候,另外一個請求又過來獲取緩存,發現有個鎖,這個時候就去等待,之後都是一次等待的過程,直到重建完成以後,鎖解除後再次獲取緩存命中。

```java
public String getKey(String key){
    String value = redis.get(key);
    if(value == null){
        String mutexKey = "mutex:key:"+key; //設置互斥鎖的key
        if(redis.set(mutexKey,"1","ex 180","nx")){ //給這個key上一把鎖,ex表示只有一個線程能執行,過期時間爲180秒
          value = db.get(key);
          redis.set(key,value);
          redis.delete(mutexKety);
  }else{
        // 其他的線程休息100毫秒後重試
        Thread.sleep(100);
        getKey(key);
  }
 }
 return value;
}
```

互斥鎖的優點是思路非常簡單,具有一致性,但是互斥鎖也有一定的問題,就是大量線程在等待的問題。存在死鎖的可能性。

4.緩存雪崩問題

緩存雪崩是指機器宕機或在我們設置緩存時採用了相同的過期時間,導致緩存在某一時刻同時失效,請求全部轉發到DB,DB瞬時壓力過重雪崩。

1:在緩存失效後,通過加鎖或者隊列來控制讀數據庫寫緩存的線程數量。比如對某個key只允許一個線程查詢數據和寫緩存,其他線程等待。

2:做二級緩存,A1爲原始緩存,A2爲拷貝緩存,A1失效時,可以訪問A2,A1緩存失效時間設置爲短期,A2設置爲長期

3:不同的key,設置不同的過期時間,讓緩存失效的時間點儘量均勻。

4:如果緩存數據庫是分佈式部署,將熱點數據均勻分佈在不同的緩存數據庫中。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章