<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>

          高并發(fā):緩存模式以及緩存的數(shù)據(jù)一致性

          共 2343字,需瀏覽 5分鐘

           ·

          2020-09-01 05:46

          作者 |?stephanie Tang

          來(lái)源 |?stephanietang.github.io/2020/04/13/cache-pattern/


          緩存由于其高性能,支持高并發(fā)的特性,在高并發(fā)的項(xiàng)目中不可或缺。被大家廣泛使用的有Redis,Memcached等。本文主要探討幾種常見(jiàn)的緩存的讀寫(xiě)模式,以及如何來(lái)保證緩存和數(shù)據(jù)庫(kù)的數(shù)據(jù)一致性。


          Cache-Aside


          Cache-Aside可能是項(xiàng)目中最常見(jiàn)的一種模式。它是一種控制邏輯都實(shí)現(xiàn)在應(yīng)用程序中的模式。緩存不和數(shù)據(jù)庫(kù)直接進(jìn)行交互,而是由應(yīng)用程序來(lái)同時(shí)和緩存以及數(shù)據(jù)庫(kù)打交道。Cache-Aside的名字正體現(xiàn)了這個(gè)模式,Cache在應(yīng)用的一旁(aside)。

          讀數(shù)據(jù)時(shí)

          1. 程序需要判斷緩存中是否已經(jīng)存在數(shù)據(jù)。


          2. 當(dāng)緩存中已經(jīng)存在數(shù)據(jù)(也就是緩存命中,cache hit),則直接從緩存中返回?cái)?shù)據(jù)


          3. 當(dāng)緩存中不存在數(shù)據(jù)(也就是緩存未命中,cache miss),則先從數(shù)據(jù)庫(kù)里讀取數(shù)據(jù),并且存入緩存,然后返回?cái)?shù)據(jù)

          寫(xiě)數(shù)據(jù)時(shí),我們可以有以下兩種策略:

          第一種策略:

          1. 更新數(shù)據(jù)庫(kù)


          2. 更新緩存

          但這種策略有線程安全的問(wèn)題,可能出現(xiàn)緩存和數(shù)據(jù)庫(kù)不一致。試想有兩個(gè)寫(xiě)的線程,線程A和線程B

          1. A寫(xiě)數(shù)據(jù)庫(kù)


          2. B后于A寫(xiě)數(shù)據(jù)庫(kù)


          3. B寫(xiě)緩存


          4. A寫(xiě)緩存


          5. 緩存和數(shù)據(jù)庫(kù)中的數(shù)據(jù)不一致,緩存中的是臟數(shù)據(jù)

          要解決線程安全的問(wèn)題,我們可以加鎖,不過(guò)實(shí)現(xiàn)起來(lái)比較麻煩,因此我們不考慮這種寫(xiě)策略,而使用第二種策略。

          第二種策略:

          1. 更新數(shù)據(jù)庫(kù)


          2. 刪除緩存中對(duì)應(yīng)的數(shù)據(jù)


          那么這種寫(xiě)策略會(huì)有線程安全的問(wèn)題嗎?有,試想一下有兩個(gè)線程,線程A讀,線程B寫(xiě)


          1. A讀數(shù)據(jù),由于未命中那么從數(shù)據(jù)庫(kù)中取數(shù)據(jù)


          2. B寫(xiě)數(shù)據(jù)庫(kù)


          3. B刪除緩存


          4. A由于網(wǎng)絡(luò)延遲比較慢,將臟數(shù)據(jù)寫(xiě)入緩存

          但是這種情況可能性非常的小,需要同時(shí)滿足很多條件,近乎不太可能發(fā)生,所以我們一般都采用這種寫(xiě)策略。另外可以對(duì)緩存中的數(shù)據(jù)設(shè)置合適的過(guò)期時(shí)間,即使發(fā)生的臟數(shù)據(jù)的情況,也不會(huì)發(fā)生很長(zhǎng)時(shí)間。

          應(yīng)用場(chǎng)景


          應(yīng)用于緩存不支持Read-Through/Write-Through的系統(tǒng)。

          優(yōu)點(diǎn)


          • 緩存僅僅保存被請(qǐng)求的數(shù)據(jù),屬于懶加載模式(Lazy Loading),和下文的Write-Through模式相比,避免了任何數(shù)據(jù)都被寫(xiě)入緩存造成緩存頻繁的更新。

          缺點(diǎn)


          • 當(dāng)發(fā)生緩存未命中的情況時(shí),則會(huì)比較慢,因?yàn)橐?jīng)過(guò)三個(gè)步驟:查詢緩存,從數(shù)據(jù)庫(kù)讀取,寫(xiě)入緩存。


          • 復(fù)雜的邏輯都在應(yīng)用程序中,如果實(shí)現(xiàn)微服務(wù),多個(gè)微服務(wù)中會(huì)有重復(fù)的邏輯代碼

          Read-Through/Write-Through


          這種模式中,應(yīng)用程序?qū)⒕彺孀鳛橹饕臄?shù)據(jù)源,而數(shù)據(jù)庫(kù)對(duì)于應(yīng)用程序是透明的,更新數(shù)據(jù)庫(kù)和從數(shù)據(jù)庫(kù)的讀取的任務(wù)都交給緩存來(lái)代理了,所以對(duì)于應(yīng)用程序來(lái)說(shuō),簡(jiǎn)單很多。


          Read-Through


          由緩存配置一個(gè)讀模塊,它知道如何將數(shù)據(jù)庫(kù)中的數(shù)據(jù)寫(xiě)入緩存。在數(shù)據(jù)被請(qǐng)求的時(shí)候,如果未命中,則將數(shù)據(jù)從數(shù)據(jù)庫(kù)載入緩存。


          Write-Through


          緩存配置一個(gè)寫(xiě)模塊,它知道如何將數(shù)據(jù)寫(xiě)入數(shù)據(jù)庫(kù)。當(dāng)應(yīng)用要寫(xiě)入數(shù)據(jù)時(shí),緩存會(huì)先存儲(chǔ)數(shù)據(jù),并調(diào)用寫(xiě)模塊將數(shù)據(jù)寫(xiě)入數(shù)據(jù)庫(kù)。



          應(yīng)用場(chǎng)景

          Read Through/Write Through適用于寫(xiě)入之后經(jīng)常被讀取的應(yīng)用。


          優(yōu)點(diǎn)


          • 緩存不存在臟數(shù)據(jù)


          • 相比較Cache-Aside懶加載模式,讀取速度更高,因?yàn)檩^少因?yàn)榫彺嫖疵卸鴱臄?shù)據(jù)庫(kù)中查找


          • 應(yīng)用程序的邏輯相對(duì)簡(jiǎn)單


          缺點(diǎn)


          • 對(duì)于總是寫(xiě)入?yún)s很少被讀取的應(yīng)用,那么Write-Through會(huì)非常浪費(fèi)性能,因?yàn)閿?shù)據(jù)可能更改了很多次,卻沒(méi)有被讀取,白白的每次都寫(xiě)入緩存造成寫(xiě)入延遲。

          除了Write-Through以外,我們還有另外的兩種寫(xiě)模式可以和Read-Through一起來(lái)配合使用,分別是Write-Back和Write-Around。


          Write-Back


          又叫做Write-Behind。和Write-Through寫(xiě)入的時(shí)機(jī)不同,Write-Back將緩存作為可靠的數(shù)據(jù)源,每次都只寫(xiě)入緩存,而寫(xiě)入數(shù)據(jù)庫(kù)則采用異步的方式,比如當(dāng)數(shù)據(jù)要被移除出緩存的時(shí)候再存儲(chǔ)到數(shù)據(jù)庫(kù)或者一段時(shí)間之后批量更新數(shù)據(jù)庫(kù)。



          應(yīng)用場(chǎng)景


          讀寫(xiě)效率都非常好,寫(xiě)的時(shí)候因?yàn)楫惒酱鎯?chǔ)到數(shù)據(jù)庫(kù),提升了寫(xiě)的效率,適用于讀寫(xiě)密集的應(yīng)用。


          優(yōu)點(diǎn)


          • 寫(xiě)入和讀取數(shù)據(jù)都非常的快,因?yàn)槎际菑木彺嬷兄苯幼x取和寫(xiě)入。


          • 對(duì)于數(shù)據(jù)庫(kù)不可用的情況有一定的容忍度,即使數(shù)據(jù)庫(kù)暫時(shí)不可用,系統(tǒng)也整體可用,當(dāng)數(shù)據(jù)庫(kù)之后恢復(fù)的時(shí)候,再將數(shù)據(jù)寫(xiě)入數(shù)據(jù)庫(kù)。


          缺點(diǎn)


          • 有數(shù)據(jù)丟失的風(fēng)險(xiǎn),如果緩存掛掉而數(shù)據(jù)沒(méi)有及時(shí)寫(xiě)到數(shù)據(jù)庫(kù)中,那么緩存中的有些數(shù)據(jù)將永久的丟失了


          Write-Around


          和Write-Through不同,更新的時(shí)候只寫(xiě)入數(shù)據(jù)庫(kù),不寫(xiě)入緩存,結(jié)合Read-Through或者Cache-Aside使用,只在緩存未命中的情況下寫(xiě)緩存。


          應(yīng)用場(chǎng)景


          適合于只寫(xiě)入一次而很少被讀取的應(yīng)用。

          優(yōu)點(diǎn)


          • 相比較Write-Through寫(xiě)入的時(shí)候的效率較高,如果數(shù)據(jù)寫(xiě)入后很少被讀取,緩存也不會(huì)被沒(méi)用到的數(shù)據(jù)占滿。

          缺點(diǎn)


          • 如果數(shù)據(jù)會(huì)寫(xiě)入多次,那么可能存在緩存和數(shù)據(jù)庫(kù)不一致

          - 推薦閱讀 -


          架構(gòu)師離職后,成為自由開(kāi)發(fā)者的第 100 天


          往期推薦



          常用的 IDEA插件推薦,不用就out啦

          秒殺系統(tǒng)設(shè)計(jì)原理

          Java 泛型背后的原理

          Spring Boot + Dataway 配配就能配出來(lái)?

          傳說(shuō)中最經(jīng)典的外包案例


          下方二維碼關(guān)注我

          互聯(lián)網(wǎng)草根,堅(jiān)持分享技術(shù)創(chuàng)業(yè)產(chǎn)品心得和總結(jié)~



          點(diǎn)擊“閱讀原文”,領(lǐng)取 2020 年最新免費(fèi)技術(shù)資料大全

          ↓↓↓?
          瀏覽 52
          點(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>
                  亚洲成人超碰在线观看 | 亚洲无码高清黄色视频网站 | 中国在线黄色一级学生妹 | 亚洲日本色情视频在线 | 亚洲天堂久久 |