<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Redis 緩存異常、應(yīng)對(duì)策略

          共 2431字,需瀏覽 5分鐘

           ·

          2024-07-12 08:00

          1、緩存和數(shù)據(jù)庫(kù)不一致#

          只要我們使用 Redis 緩存,就必然會(huì)面對(duì)緩存和數(shù)據(jù)庫(kù)間的一致性保證問(wèn)題,這里的“一致性”包含了兩種情況:緩存中有數(shù)據(jù)且與數(shù)據(jù)庫(kù)中的值相同、緩存中沒(méi)有數(shù)據(jù),最新值在數(shù)據(jù)庫(kù)中。

          對(duì)于讀寫(xiě)緩存來(lái)說(shuō),要想保證緩存和數(shù)據(jù)庫(kù)中的數(shù)據(jù)一致,就要采用同步直寫(xiě)策略,在業(yè)務(wù)應(yīng)用中使用事務(wù)機(jī)制,來(lái)保證緩存和數(shù)據(jù)庫(kù)的更新具有原子性。對(duì)數(shù)據(jù)一致性的要求不高的場(chǎng)景,可以使用異步寫(xiě)回策略。

          只讀緩存在新增數(shù)據(jù)時(shí)是符合數(shù)據(jù)一致性第二種情況的,但是在刪改數(shù)據(jù)時(shí),無(wú)論是操作緩存還是操作數(shù)據(jù)庫(kù),有一項(xiàng)失敗,就會(huì)產(chǎn)生數(shù)據(jù)不一致的問(wèn)題。具體情況如圖:
          針對(duì)這種情況可以引用重試機(jī)制來(lái)解決,具體來(lái)說(shuō),可以把要數(shù)據(jù)暫存到消息隊(duì)列中。無(wú)論哪項(xiàng)操作失敗,都可以從消息隊(duì)列中重新讀取這些值,然后再次進(jìn)行刪除或更新。如果刪改成功,就把數(shù)據(jù)從消息隊(duì)列中去除,以免重復(fù)操作,以此來(lái)保證數(shù)據(jù)一致性。多次重試仍然失敗的話就需要業(yè)務(wù)層面預(yù)警來(lái)排查解決了。

          除了操作失敗的原因,實(shí)際當(dāng)有大量并發(fā)請(qǐng)求時(shí),應(yīng)用還是有可能讀到不一致的數(shù)據(jù)。根據(jù)刪改緩存、數(shù)據(jù)庫(kù)的先后順序分為兩種情況:先操作緩存和先操作數(shù)據(jù)庫(kù)。通過(guò)引用“延遲雙刪”的操作,來(lái)保證先操作緩存后操作數(shù)據(jù)庫(kù)的數(shù)據(jù)一致性問(wèn)題,代碼示意如下:

          redis.delKey(X)
          db.update(X)
          Thread.sleep(N)
          redis.delKey(X)

          具體情況與應(yīng)對(duì)措施總結(jié)如圖:

          2、雪崩#

          指大量的應(yīng)用請(qǐng)求無(wú)法在 Redis 緩存中進(jìn)行處理,到達(dá)數(shù)據(jù)庫(kù)層面,導(dǎo)致數(shù)據(jù)庫(kù)的壓力激增。原因有二:
          其一,緩存中有大量數(shù)據(jù)同時(shí)過(guò)期。
          其二,Redis 緩存實(shí)例掛了。

          原因一可以通過(guò)以下兩個(gè)方法解決:
          (1)微調(diào)過(guò)期時(shí)間:對(duì)于同一批數(shù)據(jù)設(shè)置不同的過(guò)期時(shí)間,如通過(guò)隨機(jī)數(shù)延遲過(guò)期等。
          (2)降級(jí)處理:非核心數(shù)據(jù)請(qǐng)求直接返回 空 或 錯(cuò)誤 等預(yù)置信息,核心數(shù)據(jù)運(yùn)行未命中緩存訪問(wèn)數(shù)據(jù)庫(kù)。

          原因二可以通過(guò)以下兩個(gè)方法解決:
          (1)熔斷:拒絕緩存客戶端的請(qǐng)求,保護(hù)數(shù)據(jù)庫(kù),防止整個(gè)系統(tǒng)崩潰,直到 Redis 緩存實(shí)例恢復(fù)正常,但是對(duì)業(yè)務(wù)應(yīng)用的影響范圍大。
          (2)限流:允許部分請(qǐng)求到達(dá) Redis 緩存,無(wú)法命中再訪問(wèn)數(shù)據(jù)庫(kù),減輕數(shù)據(jù)庫(kù)壓力,相對(duì)于熔斷來(lái)說(shuō)影響范圍稍微縮小。
          無(wú)論采取何種措施,雪崩都已經(jīng)發(fā)生了,必定會(huì)影響到業(yè)務(wù)系統(tǒng),所以要做好預(yù)防工作,構(gòu)建 Redis 緩存高可靠集群,盡量避免事故。

          3、擊穿#

          指針對(duì)某個(gè)熱點(diǎn)數(shù)據(jù)的請(qǐng)求,無(wú)法在緩存中處理,大量訪問(wèn)該數(shù)據(jù)的請(qǐng)求發(fā)送到了后端數(shù)據(jù)庫(kù),壓力激增影響到其他請(qǐng)求,如下圖:
          為了避免緩存擊穿給數(shù)據(jù)庫(kù)帶來(lái)的激增壓力,對(duì)于訪問(wèn)特別頻繁的熱點(diǎn)數(shù)據(jù),可以不設(shè)置過(guò)期時(shí)間了,全部在緩存中進(jìn)行處理。

          4、穿透#

          指要訪問(wèn)的數(shù)據(jù)既不在 Redis 緩存中,也不在數(shù)據(jù)庫(kù)中,導(dǎo)致請(qǐng)求壓力還是落到數(shù)據(jù)庫(kù),緩存也就成了“擺設(shè)”。如下圖:
          通常情況是由于業(yè)務(wù)數(shù)據(jù)被誤刪除,或者惡意攻擊訪問(wèn),有三種方案解決緩存穿透的影響:
          (1)緩存空值或缺省值:針對(duì)穿透的數(shù)據(jù),在 Redis 中緩存一個(gè)空值或是和業(yè)務(wù)層協(xié)商確定的缺省值,避免把大量請(qǐng)求發(fā)送給數(shù)據(jù)庫(kù)。
          (2)布隆過(guò)濾器
          布隆過(guò)濾器由一個(gè)初值都為 0 的 bit 數(shù)組和 N 個(gè)哈希函數(shù)組成,數(shù)據(jù)入庫(kù)則進(jìn)行標(biāo)記,過(guò)程如下:

          • 使用 N 個(gè)哈希函數(shù),分別計(jì)算這個(gè)數(shù)據(jù)的哈希值,得到 N 個(gè)哈希值。

          • 我們把這 N 個(gè)哈希值對(duì) bit 數(shù)組的長(zhǎng)度取模,得到每個(gè)哈希值在數(shù)組中的對(duì)應(yīng)位置。

          • 我們把對(duì)應(yīng)位置的 bit 位設(shè)置為 1,這就完成了在布隆過(guò)濾器中標(biāo)記數(shù)據(jù)的操作。

          當(dāng)查詢某個(gè)數(shù)據(jù)時(shí),按照哈希函數(shù)的計(jì)算結(jié)果,查看 bit 數(shù)組中這 N 個(gè)位置上的 bit 值,只要有一個(gè)不為 1,這就表明布隆過(guò)濾器沒(méi)有對(duì)該數(shù)據(jù)做過(guò)標(biāo)記。當(dāng)緩存穿透發(fā)生,布隆過(guò)濾器的快速檢測(cè)特性可以幫數(shù)據(jù)庫(kù)阻擋大部分的壓力。例子如下圖:
          (3)前端請(qǐng)求過(guò)濾:在請(qǐng)求入口前端進(jìn)行合法性檢測(cè),把惡意的請(qǐng)求(如請(qǐng)求參數(shù)不合理、非法值或請(qǐng)求字段不存在)直接過(guò)濾掉。

          小結(jié)#

          雪崩、擊穿、穿透,這三類(lèi)異常問(wèn)題從成因來(lái)看,前兩個(gè)主要是因?yàn)閿?shù)據(jù)不在緩存中了,而穿透則是因?yàn)閿?shù)據(jù)既不在緩存中,也不在數(shù)據(jù)庫(kù)中。當(dāng)雪崩或擊穿發(fā)生時(shí),一旦數(shù)據(jù)庫(kù)中的數(shù)據(jù)被再次寫(xiě)入到緩存后,應(yīng)用又可以在緩存中快速訪問(wèn)數(shù)據(jù)了,數(shù)據(jù)庫(kù)的壓力也會(huì)相應(yīng)地降低,而穿透發(fā)生時(shí),Redis 緩存和數(shù)據(jù)庫(kù)會(huì)同時(shí)持續(xù)承受請(qǐng)求壓力。

          對(duì)應(yīng)的熔斷、降級(jí)、限流這些方法都是屬于“有損”方案,在保證數(shù)據(jù)庫(kù)和整體系統(tǒng)穩(wěn)定的同時(shí),會(huì)對(duì)業(yè)務(wù)應(yīng)用帶來(lái)負(fù)面影響。降級(jí)時(shí),有部分?jǐn)?shù)據(jù)的請(qǐng)求就只能得到錯(cuò)誤返回信息,無(wú)法正常處理。熔斷時(shí),整個(gè)緩存系統(tǒng)暫停,影響的業(yè)務(wù)范圍更大。流機(jī)時(shí),整個(gè)業(yè)務(wù)系統(tǒng)的吞吐率會(huì)降低,并發(fā)處理能力減弱,影響到用戶體驗(yàn)。

          所以,應(yīng)當(dāng)盡量使用預(yù)防式方案,總結(jié)如下:

          • 雪崩,合理地設(shè)置數(shù)據(jù)過(guò)期時(shí)間,以及搭建高可靠緩存集群。

          • 擊穿,在緩存訪問(wèn)非常頻繁的熱點(diǎn)數(shù)據(jù)時(shí),不要設(shè)置過(guò)期時(shí)間。

          • 穿透,提前在入口前端實(shí)現(xiàn)惡意請(qǐng)求檢測(cè),或者規(guī)范數(shù)據(jù)庫(kù)的數(shù)據(jù)刪除操作,避免誤刪除。

          鏈接:https://www.cnblogs.com/WinterSir/p/17973038

                                                                        (版權(quán)歸原作者所有,侵刪)

          瀏覽 66
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  操女人在线 | 俺也色色 | 色拍拍视频 | 波多野结衣红桃视频 | 欧美大鸡巴操逼 |