日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
緩存穿透問題

 一. 緩存穿透 (請求數(shù)據(jù)緩存大量不命中):

公司主營業(yè)務(wù):網(wǎng)站制作、成都網(wǎng)站建設(shè)、移動網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競爭能力。創(chuàng)新互聯(lián)是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊。公司秉承以“開放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對我們的高要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團(tuán)隊有機(jī)會用頭腦與智慧不斷的給客戶帶來驚喜。創(chuàng)新互聯(lián)推出代縣免費做網(wǎng)站回饋大家。

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

    例如:下圖是一個比較典型的cache-storage架構(gòu),cache(例如memcache, redis等等) + storage(例如MySQL, hbase等等)架構(gòu),查一個壓根就不存在的值, 如果不做兼容,永遠(yuǎn)會查詢storage。

緩存穿透問題

二. 危害:

     對底層數(shù)據(jù)源(mysql, hbase, http接口, rpc調(diào)用等等)壓力過大,有些底層數(shù)據(jù)源不具備高并發(fā)性。下載

     例如mysql一般來說單臺能夠扛1000-QPS就已經(jīng)很不錯了(別說你的查詢都是select * from table where id=xx 以及你的機(jī)器多么牛逼,那就有點矯情了)

     例如他人提供的一個抗壓性很差的http接口,可能穿透會擊潰他的服務(wù)。

     緩存穿透問題

三. 如何發(fā)現(xiàn):

   我們可以分別記錄cache命中數(shù), storage命中數(shù),以及總調(diào)用量,如果發(fā)現(xiàn)空命中(cache,storage都沒有命中)較多,可能就會在緩存穿透問題。下載

   注意:緩存本身的命中率(例如redis中的info提供了類似數(shù)字,只代表緩存本身)不代表storage和業(yè)務(wù)的命中率。

   

四. 產(chǎn)生原因以及業(yè)務(wù)是否允許?

    產(chǎn)生原因有很多:可能是代碼本身或者數(shù)據(jù)存在的問題造成的,也很有可能是一些惡意***、爬蟲等等(因為http讀接口都是開放的)

    業(yè)務(wù)是否允許:這個要看做的項目或者業(yè)務(wù)是否允許這種情況發(fā)生,比如做一些非實時的推薦系統(tǒng),假如新用戶來了,確實沒有他的推薦數(shù)據(jù)(推薦數(shù)據(jù)通常是根據(jù)歷史行為算出),這種業(yè)務(wù)是會發(fā)生穿透現(xiàn)象的,至于業(yè)務(wù)允不允許要具體問題具體分析了。下載

 

五. 解決方法:

解決思路大致有兩個,如下表。下面將分別說明

解決緩存穿透適用場景維護(hù)成本
緩存空對象

1. 數(shù)據(jù)命中不高

2. 數(shù)據(jù)頻繁變化實時性高

1.代碼維護(hù)簡單

2.需要過多的緩存空間

3. 數(shù)據(jù)不一致

bloomfilter或者壓縮filter提前攔截

1. 數(shù)據(jù)命中不高

2. 數(shù)據(jù)相對固定實時性低

1.代碼維護(hù)復(fù)雜

2.緩存空間占用少

       1. 緩存空對象下載

         緩存穿透問題

        (1). 定義:如上圖所示,當(dāng)?shù)冖诓組ISS后,仍然將空對象保留到Cache中(可能是保留幾分鐘或者一段時間,具體問題具體分析),下次新的Request(同一個key)將會從Cache中獲取到數(shù)據(jù),保護(hù)了后端的Storage。

        (2) 適用場景:數(shù)據(jù)命中不高,數(shù)據(jù)頻繁變化實時性高(一些亂轉(zhuǎn)業(yè)務(wù))

        (3) 維護(hù)成本:代碼比較簡單,但是有兩個問題:

             第一是空值做了緩存,意味著緩存系統(tǒng)中存了更多的key-value,也就是需要更多空間(有人說空值沒多少,但是架不住多?。?,解決方法是我們可以設(shè)置一個較短的過期時間。

             第二是數(shù)據(jù)會有一段時間窗口的不一致,假如,Cache設(shè)置了5分鐘過期,此時Storage確實有了這個數(shù)據(jù)的值,那此段時間就會出現(xiàn)數(shù)據(jù)不一致,解決方法是我們可以利用消息或者其他方式,清除掉Cache中的數(shù)據(jù)。

        (4) 偽代碼:

Java代碼  下載

  1. package com.carlosfu.service;  

  2.   

  3. import org.apache.commons.lang.StringUtils;  

  4.   

  5. import com.carlosfu.cache.Cache;  

  6. import com.carlosfu.storage.Storage;  

  7.   

  8. /** 

  9.  * 某服務(wù) 

  10.  *  

  11.  * @author carlosfu 

  12.  * @Date 2015-10-11 

  13.  * @Time 下午6:28:46 

  14.  */  

  15. public class XXXService {  

  16.   

  17.     /** 

  18.      * 緩存 

  19.      */  

  20.     private Cache cache = new Cache();  

  21.   

  22.     /** 

  23.      * 存儲 

  24.      */  

  25.     private Storage storage = new Storage();  

  26.   

  27.     /** 

  28.      * 模擬正常模式 

  29.      * @param key 

  30.      * @return 

  31.      */  

  32.     public String getNormal(String key) {  

  33.         // 從緩存中獲取數(shù)據(jù)  

  34.         String cacheValue = cache.get(key);  

  35.         // 緩存為空  

  36.         if (StringUtils.isBlank(cacheValue)) {  

  37.             // 從存儲中獲取  

  38.             String storageValue = storage.get(key);  

  39.             // 如果存儲數(shù)據(jù)不為空,將存儲的值設(shè)置到緩存  

  40.             if (StringUtils.isNotBlank(storageValue)) {  

  41.                 cache.set(key, storageValue);  

  42.             }  

  43.             return storageValue;  

  44.         } else {  

  45.             // 緩存非空  

  46.             return cacheValue;  

  47.         }  

  48.     }  

  49.   

  50.   

  51.     /** 

  52.      * 模擬防穿透模式 

  53.      * @param key 

  54.      * @return 

  55.      */  

  56.     public String getPassThrough(String key) {  

  57.         // 從緩存中獲取數(shù)據(jù)  

  58.         String cacheValue = cache.get(key);  

  59.         // 緩存為空  

  60.         if (StringUtils.isBlank(cacheValue)) {  

  61.             // 從存儲中獲取  

  62.             String storageValue = storage.get(key);  

  63.             cache.set(key, storageValue);  

  64.             // 如果存儲數(shù)據(jù)為空,需要設(shè)置一個過期時間(300秒)  

  65.             if (StringUtils.isBlank(storageValue)) {  

  66.                 cache.expire(key, 60 * 5);  

  67.             }  

  68.             return storageValue;  

  69.         } else {  

  70.             // 緩存非空  

  71.             return cacheValue;  

  72.         }  

  73.     }  

  74.   

  75. }  

 

2. bloomfilter或者壓縮filter(bitmap等等)提前攔截下載

緩存穿透問題

        (1). 定義:如上圖所示,在訪問所有資源(cache, storage)之前,將存在的key用布隆過濾器提前保存起來,做第一層攔截, 例如: 我們的推薦服務(wù)有4億個用戶uid, 我們會根據(jù)用戶的歷史行為進(jìn)行推薦(非實時),所有的用戶推薦數(shù)據(jù)放到hbase中,但是每天有許多新用戶來到網(wǎng)站,這些用戶在當(dāng)天的訪問就會穿透到hbase。為此我們每天4點對所有uid做一份布隆過濾器。如果布隆過濾器認(rèn)為uid不存在,那么就不會訪問hbase,在一定程度保護(hù)了hbase(減少30%左右)。下載

            

        (2) 適用場景:數(shù)據(jù)命中不高,數(shù)據(jù)相對固定實時性低(通常是數(shù)據(jù)集較大)

        (3) 維護(hù)成本:代碼維護(hù)復(fù)雜, 緩存空間占用少

              第一是空值做了緩存,意味著緩存系統(tǒng)中存了更多的key-value,也就是需要更多空間(有人說空值沒多少,但是架不住多?。鉀Q方法是我們可以設(shè)置一個較短的過期時間。

              第二是數(shù)據(jù)會有一段時間窗口的不一致,假如,Cache設(shè)置了5分鐘過期,此時Storage確實有了這個數(shù)據(jù)的值,那此段時間就會出現(xiàn)數(shù)據(jù)不一致,解決方法是我們可以利用消息或者其他方式,清除掉Cache中的數(shù)據(jù)。


分享名稱:緩存穿透問題
本文地址:http://www.dlmjj.cn/article/ghijis.html