Redis緩存、雪崩颂郎、穿透吼渡,數(shù)據(jù)一致性

  1. 緩存雪崩概念

故障原因:redis掛了 事前:redis高可用,主從+哨兵乓序,redis cluster诞吱,避免全盤崩潰 事中:本地cache緩存 + hystrix限流&降級,避免MySQL被打死 事后:redis持久化竭缝,快速恢復(fù)緩存數(shù)據(jù)

故障原因2:緩存時采用了相同的過期時間房维,導(dǎo)致緩存在某一時刻同時失效 將緩存失效時間分散開,比如我們可以在原有的失效時間基礎(chǔ)上增加一個隨機(jī)值抬纸,比如1-5分鐘隨機(jī)咙俩,這樣每一個緩存的過期時間的重復(fù)率就會降低,就很難引發(fā)集體失效的事件湿故。(和緩存擊穿不同的是阿趁,緩存擊穿指并發(fā)查同一條數(shù)據(jù),緩存雪崩是不同數(shù)據(jù)都過期了坛猪,很多數(shù)據(jù)都查不到從而查數(shù)據(jù)庫脖阵。)

2、緩存穿透

緩存穿透是指緩存和數(shù)據(jù)庫中都沒有的數(shù)據(jù)墅茉,而用戶不斷發(fā)起請求命黔,如發(fā)起為id為“-1”的數(shù)據(jù)或id為特別大不存在的數(shù)據(jù)。這時的用戶很可能是攻擊者就斤,攻擊會導(dǎo)致數(shù)據(jù)庫壓力過大悍募。解決辦法有兩個:

查詢數(shù)據(jù)庫不存在,則在redis中存一份Null值洋机,避免訪問Mysql

采用布隆過濾器坠宴,將List數(shù)據(jù)裝載入布隆過濾器中,訪問經(jīng)過布隆過濾器绷旗,存在才可以往db中查詢喜鼓。于是在內(nèi)存中就可以攔截惡意請求。

解決方案:布隆過濾器
布隆過濾器的使用方法衔肢,類似java的SET集合庄岖,用來判斷某個元素(key)是否在某個集合中。和一般的hash set不同的是膀懈,這個算法無需存儲key的值顿锰,對于每個key,只需要k個比特位启搂,每個存儲一個標(biāo)志硼控,用來判斷key是否在集合中。

使用步驟:1胳赌、將List數(shù)據(jù)裝載入布隆過濾器中

private BloomFilter<String> bf =null;

//PostConstruct注解對象創(chuàng)建后牢撼,自動調(diào)用本方法
@PostConstruct
public void init(){
    //在bean初始化完成后,實(shí)例化bloomFilter疑苫,并加載數(shù)據(jù)
    List<Entity> entities= initList();
    //初始化布隆過濾器
    bf = BloomFilter.create(Funnels.stringFunnel(Charsets.UTF_8), entities.size());
    for (Entity entity : entities) {
        bf.put(entity.getId());
    }
}

2熏版、訪問經(jīng)過布隆過濾器,存在才可以往db中查詢

 public Provinces query(String id) {
        //先判斷布隆過濾器中是否存在該值捍掺,值存在才允許訪問緩存和數(shù)據(jù)庫
        if(!bf.mightContain(id)){
            Log.info("非法訪問"+System.currentTimeMillis());
            return null;
        }
        Log.info("數(shù)據(jù)庫中得到數(shù)據(jù)"+System.currentTimeMillis());
        Entity entity= super.query(id);
        return entity;
    }

這樣當(dāng)外界有惡意攻擊時撼短,不存在的數(shù)據(jù)請求就可以直接攔截在過濾器層,而不會影響到底層數(shù)據(jù)庫系統(tǒng)挺勿。

  1. 緩存擊穿概念
    一個存在的key曲横,在緩存過期的一刻,同時有大量的請求不瓶,這些請求都會擊穿到DB禾嫉,造成瞬時DB請求量大、壓力驟增蚊丐。

解決方案
在訪問key之前熙参,采用SETNX(set if not exists)來設(shè)置另一個短期key來鎖住當(dāng)前key的訪問,訪問結(jié)束再刪除該短期key麦备。
上面的現(xiàn)象是多個線程同時去查詢數(shù)據(jù)庫的這條數(shù)據(jù)孽椰,那么我們可以在第一個查詢數(shù)據(jù)的請求上使用一個 互斥鎖來鎖住它。

其他的線程走到這一步拿不到鎖就等著凛篙,等第一個線程查詢到了數(shù)據(jù)弄屡,然后做緩存。后面的線程進(jìn)來發(fā)現(xiàn)已經(jīng)有緩存了鞋诗,就直接走緩存膀捷。

    static Lock reenLock = new ReentrantLock();
    public List<String> getData04() throws InterruptedException {
        List<String> result = new ArrayList<String>();
        // 從緩存讀取數(shù)據(jù)
        result = getDataFromCache();
        if (result.isEmpty()) {
            if (reenLock.tryLock()) {
                try {
                    System.out.println("我拿到鎖了,從DB獲取數(shù)據(jù)庫后寫入緩存");
                    // 從數(shù)據(jù)庫查詢數(shù)據(jù)
                    result = getDataFromDB();
                    // 將查詢到的數(shù)據(jù)寫入緩存
                    setDataToCache(result);
                } finally {
                    reenLock.unlock();// 釋放鎖
                }

            } else {
                result = getDataFromCache();// 先查一下緩存
                if (result.isEmpty()) {
                    System.out.println("我沒拿到鎖,緩存也沒數(shù)據(jù),先小憩一下");
                    Thread.sleep(100);// 小憩一會兒
                    return getData04();// 重試
                }
            }
        }
        return result;
    }

鏈接:http://www.reibang.com/p/87896241343c

4、數(shù)據(jù)庫與緩存一致性

Cache Aside Pattern削彬,基本都采用如下的緩存模式:

讀的時候全庸,先讀緩存,緩存沒有的話融痛,那么就讀數(shù)據(jù)庫壶笼,然后取出數(shù)據(jù)后放入緩存,同時返回響應(yīng)

更新的時候雁刷,先更新數(shù)據(jù)庫,再刪除緩存(先刪除緩存在更新數(shù)據(jù)庫會存在臟數(shù)據(jù))

參考:
http://www.reibang.com/p/dc09f86ca4ba
http://www.reibang.com/p/cbc39abb6b94

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末覆劈,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌责语,老刑警劉巖炮障,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異坤候,居然都是意外死亡胁赢,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進(jìn)店門白筹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來智末,“玉大人,你說我怎么就攤上這事徒河∠倒荩” “怎么了?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵顽照,是天一觀的道長由蘑。 經(jīng)常有香客問我,道長棒厘,這世上最難降的妖魔是什么纵穿? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮奢人,結(jié)果婚禮上谓媒,老公的妹妹穿的比我還像新娘。我一直安慰自己何乎,他們只是感情好句惯,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著支救,像睡著了一般抢野。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上各墨,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天指孤,我揣著相機(jī)與錄音,去河邊找鬼贬堵。 笑死恃轩,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的黎做。 我是一名探鬼主播叉跛,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼蒸殿!你這毒婦竟也來了筷厘?” 一聲冷哼從身側(cè)響起鸣峭,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎酥艳,沒想到半個月后摊溶,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡玖雁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年更扁,在試婚紗的時候發(fā)現(xiàn)自己被綠了盖腕。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片赫冬。...
    茶點(diǎn)故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖溃列,靈堂內(nèi)的尸體忽然破棺而出劲厌,到底是詐尸還是另有隱情,我是刑警寧澤听隐,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布补鼻,位于F島的核電站,受9級特大地震影響雅任,放射性物質(zhì)發(fā)生泄漏风范。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一沪么、第九天 我趴在偏房一處隱蔽的房頂上張望硼婿。 院中可真熱鬧,春花似錦禽车、人聲如沸寇漫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽州胳。三九已至,卻和暖如春逸月,著一層夾襖步出監(jiān)牢的瞬間栓撞,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工碗硬, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留瓤湘,地道東北人。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓肛响,卻偏偏與公主長得像岭粤,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子特笋,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評論 2 348