當前位置:首頁 » 硬碟大全 » 數據緩存層設計
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

數據緩存層設計

發布時間: 2023-03-22 19:18:50

『壹』 一級緩存二級緩存三級緩存都幹嘛用的

緩存就是你提取所需要的數據時 暫時存放的地方 緩存的大小與速度決定了你的電腦運行速度的快慢 名字只是取決於性能的高低 一般情況大多數都是用的二級高速緩存

『貳』 L1緩存的數據緩存設計

根據工作原理的不同,目前主流處理器所採用的一級數據緩存又可以分為實數據讀寫緩存和數據代碼指令追蹤緩存2種,它們分別被AMD和Intel所採用。不同的一級數據緩存設計對於二級緩存容量的需求也各不相同,下面讓我們簡單了解一下這兩種一級數據緩存設計的不同之處。 AMD採用的一級緩存設計屬於傳統的「實數據讀寫緩存」設計。基於該架構的一級數據緩存主要用於存儲CPU最先讀取的數據;而更多的讀取數據則分別存儲在二級緩存和系統內存當中。做個簡單的假設,假如處理器需要讀取「AMD ATHLON 64 3000+ IS GOOD」這一串數據(不記空格),那麼首先要被讀取的「AMDATHL」將被存儲在一級數據緩存中,而餘下的「ON643000+ISGOOD」則被分別存儲在二級緩存和系統內存當中(如下圖所示)。
需要注意的是,以上假設只是對AMD處理器一級數據緩存的一個抽象描述,一級數據緩存和二級緩存所能存儲的數據長度完全由緩存容量的大小決定,而絕非以上假設中的幾個位元組。「實數據讀寫緩存」的優點是數據讀取直接快速,但這也需要一級數據緩存具有一定的容量,增加了處理器的製造難度(一級數據緩存的單位製造成本較二級緩存高)。 自P4時代開始,Intel開始採用全新的「數據代碼指令追蹤緩存」設計。基於這種架構的一級數據緩存不再存儲實際的數據,而是存儲這些數據在二級緩存中的指令代碼(即數據在二級緩存中存儲的起始地址)。假設處理器需要讀取「INTEL P4 IS GOOD」這一串數據(不記空格),那麼所有數據將被存儲在二級緩存中,而一級數據代碼指令追蹤緩存需要存儲的僅僅是上述數據的起始地址(如下圖所示)。
由於一級數據緩存不再存儲實際數據,因此「數據代碼指令追蹤緩存」設計能夠極大地降CPU對一級數據緩存容量的要求,降低處理器的生產難度。但這種設計的弊端在於數據讀取效率較「實數據讀寫緩存設計」低,而且對二級緩存容量的依賴性非常大。

『叄』 redis怎麼實現資料庫的緩存

大致為兩種措施:

一、腳本同步:
1、自己寫腳本將資料庫數據寫入到redis/memcached。
2、這就涉及到實時數據變更的問題(mysql row binlog的實時分析),binlog增量訂閱Alibaba 的canal ,以及緩存層數據 丟失/失效 後的數據同步恢復問題。

二、業務層實現:
1、先讀取nosql緩存層,沒有數據再讀取mysql層,並寫入數據到nosql。
2、nosql層做好多節點分布式(一致性hash),以及節點失效後替代方案(多層hash尋找相鄰替代節點),和數據震盪恢復了。

redis實現資料庫緩存的分析:

  • 對於變化頻率非常快的數據來說,如果還選擇傳統的靜態緩存方式(Memocached、File System等)展示數據,可能在緩存的存取上會有很大的開銷,並不能很好的滿足需要,而Redis這樣基於內存的NoSQL資料庫,就非常適合擔任實時數據的容器。

  • 但是往往又有數據可靠性的需求,採用MySQL作為數據存儲,不會因為內存問題而引起數據丟失,同時也可以利用關系資料庫的特性實現很多功能。所以就會很自然的想到是否可以採用MySQL作為數據存儲引擎,Redis則作為Cache。

  • MySQL到Redis數據復制方案,無論MySQL還是Redis,自身都帶有數據同步的機制,比較常用的MySQL的Master/Slave模式,就是由Slave端分析Master的binlog來實現的,這樣的數據復制其實還是一個非同步過程,只不過當伺服器都在同一內網時,非同步的延遲幾乎可以忽略。那麼理論上也可用同樣方式,分析MySQL的binlog文件並將數據插入Redis。

  • 因此這里選擇了一種開發成本更加低廉的方式,借用已經比較成熟的MySQL UDF,將MySQL數據首先放入Gearman中,然後通過一個自己編寫的PHP Gearman Worker,將數據同步到Redis。比分析binlog的方式增加了不少流程,但是實現成本更低,更容易操作。

『肆』 為什麼CPU要分一級緩存、二級緩存和三級緩存

CPU緩存就是CPU內部的緩存運行頻率,緩存的大小與結構對CPU速度的影響較大,因此緩存大小也是CPU重要的性能指標之一。

CPU緩存的作用主要是為了解決CPU運算速度與內存讀寫速度不匹配的矛盾,而緩存的容量要比內存要小的太多,但是其速度要比內存快的多,因此這樣會讓CPU使用很長的時間等待數據到來或把數據寫入內存中。

搜索在緩存中的數據是內存中的一小部分,但這一小部分是短時間內CPU即將訪問的,當CPU調用大量數據時,就能夠避開內存直接從緩存中調用,從而加快讀取速度。

當CPU需要讀取數據並進行計算時,首先需要將CPU緩存中查到所需的數據,並在最短的時間下交付給CPU。

如果沒有查到所需的數據,CPU就會提出「要求」經過緩存從內存中讀取,再原路返回至CPU進行計算。而同時,把這個數據所在的數據也調入緩存,可以使得以後對整塊數據的讀取都從緩存中進行,不必再調用內存。

一級緩存(L1 Cache)

CPU一級緩存,就是指CPU的第一層級的高速緩存,主要當擔的工作是緩存指令和緩存數據。一級緩存的容量與結構對CPU性能影響十分大,但是由於它的結構比較復雜,又考慮到成本等因素,一般來說,CPU的一級緩存較小,通常CPU的一級緩存也就能做到256KB左右的水平。

二級緩存(L2 Cache66)

CPU二級緩存,就是指CPU的第二層級的高速緩存,而二級緩存的容量會直接影響到CPU的性能,二級緩存的容量越大越好。例如intel的第八代i7-8700處理器,共有六個核心數量,而每個核心都擁有256KB的二級緩存,屬於各核心獨享,這樣二級緩存總數就達到了1.5MB。

三級緩存(L3 Cache)

CPU三級緩存,就是指CPU的第三層級的高速緩存,其作用是進一步降低內存的延遲,同時提升海量數據量計算時的性能。和一級緩存、二級緩存不同的是,三級緩存是核心共享的,能夠將容量做的很大。

CPU的核心數量、高頻高低都會影響性能,但如果讓CPU更聰明、更有效率的執行計算任務,那麼緩存的作用就至關重要了。

(4)數據緩存層設計擴展閱讀:

CPU主要性能參數:

1、主頻

主頻也叫時鍾頻率,單位是兆赫(MHz)或千兆赫(GHz),用來表示CPU的運算、處理數據的速度。

2、外頻

外頻是CPU的基準頻率,單位是MHz。CPU的外頻決定著整塊主板的運行速度。

3、匯流排頻率

前端匯流排(FSB)是將CPU連接到北橋晶元的匯流排。前端匯流排(FSB)頻率(即匯流排頻率)是直接影響CPU與內存直接數據交換速度。

4、倍頻系數

倍頻系數是指CPU主頻與外頻之間的相對比例關系。

5、緩存

緩存大小也是CPU的重要指標之一,而且緩存的結構和大小對CPU速度的影響非常大,CPU內緩存的運行頻率極高,一般是和處理器同頻運作,工作效率遠遠大於系統內存和硬碟

『伍』 CPU的一些參數(如一級緩存、二級緩存)有何作用

分類: 無分類
解析:

一級緩存:

高速緩存分為一級緩存(即L1 Cache)和二級緩存(即L2Cache)。CPU在運行時首先從一級緩存讀取數據,然後從二級緩存讀取數據,然後從內存和虛擬內存讀取數據,因此高速緩存的容量和速度直接影響到CPU的工作性能。 一級緩存都內置在CPU內部並與CPU同速運行,可以有效的提高CPU的運行效率。一級緩存越大,CPU的運行效率越高,但受到CPU內部結構的限制,一級緩存的容量都很小。 二級緩存對CPU運行效率的影響也很大,現在的二級緩存一般都集成在中,但有分為晶元內部和外部兩種,集成在晶元內部的二級緩存與CPU同頻率二級緩存(即全速二級緩存),而集成在晶元外部的二級緩存的運行頻率 是CPU的運行頻率的一半(即半速二級緩存),因此運行效率較低。 但是一級緩存和二級緩存的大,它究竟有多少好處呢?你得告訴我們經銷商,實際上你得用最普通的話跟他講。所以我們給他們打個比方,說這個就好比你開汽車的時候,後備箱是整個的一級緩存,假如說扶手裡面有一個小箱子,那是你的二級緩存。二級緩存大好在哪裡呢?就是你隨時開車的時候,隨時在裡面都可以取東西了。假如你二級緩存小的話,你還得把車停下來,到後備箱里取東西。

首先我們來簡單了解一下一級緩存。目前所有主流處理器大都具有一級緩存和二級緩存,少數高端處理器還集成了三級緩存。其中,一級緩存可分為一級指令緩存和一級數據緩存。一級指令緩存用於暫時存儲並向CPU遞送各類運算指令;一級數據緩存用於暫時存儲並向CPU遞送運算所需數據,這就是一級緩存的作用(如果大家對上述文字理解困難的話,可參照下圖所示)。

那麼,二級緩存的作用又是什麼呢?簡單地說,二級緩存就是一級緩存的緩沖器:一級緩存製造成本很高因此它的容量有限,二級緩存的作用就是存儲那些CPU處理時需要用到、一級緩存又無法存儲的數據。同樣道理,三級緩存和內存可以看作是二級緩存的緩沖器,它們的容量遞增,但單位製造成本卻遞減。需要注意的是,無論是二級緩存、三級緩存還是內存都不能存儲處理器操作的原始指令,這些指令只能存儲在CPU的一級指令緩存中,而餘下的二級緩存、三級緩存和內存僅用於存儲CPU所需數據。

根據工作原理的不同,目前主流處理器所採用的一級數據緩存又可以分為實數據讀寫緩存和數據代碼指令追蹤緩存2種,它們分別被AMD和Intel所採用。不同的一級數據緩存設計對於二級緩存容量的需求也各不相同,下面讓我們簡單了解一下這兩種一級數據緩存設計的不同之處。

一、AMD一級數據緩存設計

AMD採用的一級緩存設計屬於傳統的「實數據讀寫緩存」設計。基於該架構的一級數據緩存主要用於存儲CPU最先讀取的數據;而更多的讀取數據則分別存儲在二級緩存和系統內存當中。做個簡單的假設,假如處理器需要讀取「AMD ATHLON 64 3000+ IS GOOD」這一串數據(不記空格),那麼首先要被讀取的「AMDATHL」將被存儲在一級數據緩存中,而餘下的「ON643000+ISGOOD」則被分別存儲在二級緩存和系統內存當中(如下圖所示)。

需要注意的是,以上假設只是對AMD處理器一級數據緩存的一個抽象描述,一級數據緩存和二級緩存所能存儲的數據長度完全由緩存容量的大小決定,而絕非以上假設中的幾個位元組。「實數據讀寫緩存」的優點是數據讀取直接快速,但這也需要一級數據緩存具有一定的容量,增加了處理器的製造難度(一級數據緩存的單位製造成本較二級緩存高)。

二、Intel一級數據緩存設計

自P4時代開始,Intel開始採用全新的「數據代碼指令追蹤緩存」設計。基於這種架構的一級數據緩存不再存儲實際的數據,而是存儲這些數據在二級緩存中的指令代碼(即數據在二級緩存中存儲的起始地址)。假設處理器需要讀取「INTEL P4 IS GOOD」這一串數據(不記空格),那麼所有數據將被存儲在二級緩存中,而一級數據代碼指令追蹤緩存需要存儲的僅僅是上述數據的起始地址(如下圖所示)。

由於一級數據緩存不再存儲實際數據,因此「數據代碼指令追蹤緩存」設計能夠極大地降CPU對一級數據緩存容量的要求,降低處理器的生產難度。但這種設計的弊端在於數據讀取效率較「實數據讀寫緩存設計」低,而且對二級緩存容量的依賴性非常大。

在了解了一級緩存、二級緩存的大致作用及其分類以後,下面我們來回答以下硬體一菜鳥網友提出的問題。

從理論上講,二級緩存越大處理器的性能越好,但這並不是說二級緩存容量加倍就能夠處理器帶來成倍的性能增長。目前CPU處理的絕大部分數據的大小都在0-256KB之間,小部分數據的大小在256KB-512KB之間,只有極少數數據的大小超過512KB。所以只要處理器可用的一級、二級緩存容量達到256KB以上,那就能夠應付正常的應用;512KB容量的二級緩存已經足夠滿足絕大多數應用的需求。

這其中,對於採用「實數據讀寫緩存」設計的AMD Athlon 64、Sempron處理器而言,由於它們已經具備了64KB一級指令緩存和64KB一級數據緩存,只要處理器的二級緩存容量大於等於128KB就能夠存儲足夠的數據和指令,因此它們對二級緩存的依賴性並不大。這就是為什麼主頻同為1.8GHz的Socket 754 Sempron 3000+(128KB二級緩存)、Sempron 3100+(256KB二級緩存)以及Athlon 64 2800+(512KB二級緩存)在大多數評測中性能非常接近的主要原因。所以對於普通用戶而言754 Sempron 2600+是值得考慮的。

反觀Intel目前主推的P4、賽揚系列處理器,它們都採用了「數據代碼指令追蹤緩存」架構,其中Prescott內核的一級緩存中只包含了12KB一級指令緩存和16KB一級數據緩存,而Northwood內核更是只有12KB一級指令緩存和8KB一級數據緩存。所以P4、賽揚系列處理器對二級緩存的依賴性是非常大的,賽揚D 320(256KB二級緩存)與賽揚 2.4GHz(128KB二級緩存)性能上的巨大差距就很好地證明了這一點;而賽揚D和P4 E處理器之間的性能差距同樣十分明顯。

最後,如果您是狂熱的游戲發燒友或者從事多媒體製作的專業用戶,那麼具有1MB二級緩存的P4處理器和具有512KB/1MB二級緩存的Athlon 64處理器才是您理想的選擇。因為在高負荷的運算下,CPU的一級緩存和二級緩存近乎「爆滿」,在這個時候大容量的二級緩存能夠為處理器帶來5%-10%左右的性能提升,這對於那些要求苛刻的用戶來說是完全有必要的。

二級緩存:

二級緩存又叫L2 CACHE,它是處理器內部的一些緩沖存儲器,其作用跟內存一樣。 它是怎麼出現的呢? 要上溯到上個世紀80年代,由於處理器的運行速度越來越快,慢慢地,處理器需要從內存中讀取數據的速度需求就越來越高了。然而內存的速度提升速度卻很緩慢,而能高速讀寫數據的內存價格又非常高昂,不能大量採用。從性能價格比的角度出發,英特爾等處理器設計生產公司想到一個辦法,就是用少量的高速內存和大量的低速內存結合使用,共同為處理器提供數據。這樣就兼顧了性能和使用成本的最優。而那些高速的內存因為是處於CPU和內存之間的位置,又是臨時存放數據的地方,所以就叫做緩沖存儲器了,簡稱「緩存」。它的作用就像倉庫中臨時堆放貨物的地方一樣,貨物從運輸車輛上放下時臨時堆放在緩存區中,然後再搬到內部存儲區中長時間存放。貨物在這段區域中存放的時間很短,就是一個臨時貨場。最初緩存只有一級,後來處理器速度又提升了,一級緩存不夠用了,於是就添加了二級緩存。二級緩存是比一級緩存速度更慢,容量更大的內存,主要就是做一級緩存和內存之間數據臨時交換的地方用。現在,為了適應速度更快的處理器P4EE,已經出現了三級緩存了,它的容量更大,速度相對二級緩存也要慢一些,但是比內存可快多了。緩存的出現使得CPU處理器的運行效率得到了大幅度的提升,這個區域中存放的都是CPU頻繁要使用的數據,所以緩存越大處理器效率就越高,同時由於緩存的物理結構比內存復雜很多,所以其成本也很高。

大量使用二級緩存帶來的結果是處理器運行效率的提升和成本價格的大幅度不等比提升。舉個例子,伺服器上用的至強處理器和普通的P4處理器其內核基本上是一樣的,就是二級緩存不同。至強的二級緩存是2MB~16MB,P4的二級緩存是512KB,於是最便宜的至強也比最貴的P4貴,原因就在二級緩存不同。

二級緩存又叫L2 CACHE,它是處理器內部的一些緩沖存儲器,其作用跟內存一樣。 它是怎麼出現的呢? 要上溯到上個世紀80年代,由於處理器的運行速度越來越快,慢慢地,處理器需要從內存中讀取數據的速度需求就越來越高了。然而內存的速度提升速度卻很緩慢,而能高速讀寫數據的內存價格又非常高昂,不能大量採用。從性能價格比的角度出發,英特爾等處理器設計生產公司想到一個辦法,就是用少量的高速內存和大量的低速內存結合使用,共同為處理器提供數據。這樣就兼顧了性能和使用成本的最優。而那些高速的內存因為是處於CPU和內存之間的位置,又是臨時存放數據的地方,所以就叫做緩沖存儲器了,簡稱「緩存」。它的作用就像倉庫中臨時堆放貨物的地方一樣,貨物從運輸車輛上放下時臨時堆放在緩存區中,然後再搬到內部存儲區中長時間存放。貨物在這段區域中存放的時間很短,就是一個臨時貨場。最初緩存只有一級,後來處理器速度又提升了,一級緩存不夠用了,於是就添加了二級緩存。二級緩存是比一級緩存速度更慢,容量更大的內存,主要就是做一級緩存和內存之間數據臨時交換的地方用。現在,為了適應速度更快的處理器P4EE,已經出現了三級緩存了,它的容量更大,速度相對二級緩存也要慢一些,但是比內存可快多了。緩存的出現使得CPU處理器的運行效率得到了大幅度的提升,這個區域中存放的都是CPU頻繁要使用的數據,所以緩存越大處理器效率就越高,同時由於緩存的物理結構比內存復雜很多,所以其成本也很高。

大量使用二級緩存帶來的結果是處理器運行效率的提升和成本價格的大幅度不等比提升。舉個例子,伺服器上用的至強處理器和普通的P4處理器其內核基本上是一樣的,就是二級緩存不同。至強的二級緩存是2MB~16MB,P4的二級緩存是512KB,於是最便宜的至強也比最貴的P4貴,原因就在二級緩存不同。

『陸』 Hibernate的緩存技術有哪些

緩存是資料庫數據在內存中的臨時容器,它包含了庫表數據在內存中的臨時拷貝,位於資料庫與應用程序之間,其作用是為了降低應用程序對物理數據源訪問的頻次,從而提高應用的運行性能。

Hibernate的緩存機制

1.1持久化層的緩存的范圍

持久層設計中,往往需要考慮幾個不同層次中的數據緩存策略。這些層次的劃分標准針對不同情況有所差異,一般而言,ORM的數據緩存應包含如下幾個層次:

事務級緩存(Transaction Layer Cache)

緩存只能被當前事務訪問。緩存的生命周期依賴於事務的生命周期,當事務結束時,緩存也就結束生命周期。在此范圍下,緩存的介質是內存。事務可以是資料庫事務或者應用事務,每個事務都有獨自的緩存,緩存內的數據通常採用相互關聯的對象形式。

應用級/進程級緩存(Application/Process Layer Cache)

緩存被進程內的所有事務共享。這些事務有可能是並發訪問緩存,因此必須對緩存採取必要的事務隔離機制。緩存的生命周期依賴於進程的生命周期,進程結束時,緩存也就結束了生命周期。進程范圍的緩存可能會存放大量的數據,所以存放的介質可以是內存或硬碟。緩存內的數據既可以是相互關聯的對象形式也可以是對象的鬆散數據形式。對象的鬆散數據形式有點類似於對象的序列化數據,但是對象分解為鬆散的演算法比對象序列化的演算法要求更快。

集群級緩存(Cluster Layer Cache)

在集群環境中,緩存被一個機器或者多個機器的進程共享。緩存中的數據被復制到集群環境中的每個進程節點,進程間通過遠程通信來保證緩存中的數據的一致性,緩存中的數據通常採用對象的鬆散數據形式。對大多數應用來說,應該慎重地考慮是否需要使用集群范圍的緩存,因為訪問的速度不一定會比直接訪問資料庫數據的速度快多少。

持久層提供以上多種層次的緩存。如果在事務級緩存中沒有查到相應的數據,還可以到進程級或集群級緩存內查詢,如果還是沒有查到,那麼只有到資料庫中查詢。事務級緩存是持久化層的第一級緩存,通常它是必需的;進程級或集群級緩存是持久化層的第二級緩存,通常是可選的。

1.2 hibernate緩存機制

Hibernate提供了兩種緩存,第一種是Session的緩存,又稱為一級緩存。由於Session對象的生命周期通常對應一個資料庫事務或者一個應用事務,因此它的緩存是事務范圍的緩存。第一級緩存是必需的,不允許而且事實上也無法卸除。在第一級緩存中,持久化類的每個實例都具有唯一的OID。

『柒』 如何保證資料庫緩存的最終一致性

對於互聯網業務來說,傳統的直接訪問資料庫方式,主要通過數據分片、一主多從等方式來扛住讀寫流量,但隨著數據量的積累和流量的激增,僅依賴資料庫來承接所有流量,不僅成本高、效率低、而且還伴隨著穩定性降低的風險。

鑒於大部分業務通常是讀多寫少(讀取頻率遠遠高於更新頻率),甚至存在讀操作數量高出寫操作多個數量級的情況。因此, 在架構設計中,常採用增加緩存層來提高系統的響應能力 ,提升數據讀寫性能、減少資料庫訪問壓力,從而提升業務的穩定性和訪問體驗。

根據 CAP 原理,分布式系統在可用性、一致性和分區容錯性上無法兼得,通常由於分區容錯無法避免,所以一致性和可用性難以同時成立。對於緩存系統來說, 如何保證其數據一致性是一個在應用緩存的同時不得不解決的問題 。

需要明確的是,緩存系統的數據一致性通常包括持久化層和緩存層的一致性、以及多級緩存之間的一致性,這里我們僅討論前者。持久化層和緩存層的一致性問題也通常被稱為雙寫一致性問題,「雙寫」意為數據既在資料庫中保存一份,也在緩存中保存一份。

對於一致性來說,包含強一致性和弱一致性 ,強一致性保證寫入後立即可以讀取,弱一致性則不保證立即可以讀取寫入後的值,而是盡可能的保證在經過一定時間後可以讀取到,在弱一致性中應用最為廣泛的模型則是最終一致性模型,即保證在一定時間之後寫入和讀取達到一致的狀態。對於應用緩存的大部分場景來說,追求的則是最終一致性,少部分對數據一致性要求極高的場景則會追求強一致性。

為了達到最終一致性,針對不同的場景,業界逐步形成了下面這幾種應用緩存的策略。


1

Cache-Aside


Cache-Aside 意為旁路緩存模式,是應用最為廣泛的一種緩存策略。下面的圖示展示了它的讀寫流程,來看看它是如何保證最終一致性的。在讀請求中,首先請求緩存,若緩存命中(cache hit),則直接返回緩存中的數據;若緩存未命中(cache miss),則查詢資料庫並將查詢結果更新至緩存,然後返回查詢出的數據(demand-filled look-aside )。在寫請求中,先更新資料庫,再刪除緩存(write-invalidate)。


1、為什麼刪除緩存,而不是更新緩存?

在 Cache-Aside 中,對於讀請求的處理比較容易理解,但在寫請求中,可能會有讀者提出疑問,為什麼要刪除緩存,而不是更新緩存?站在符合直覺的角度來看,更新緩存是一個容易被理解的方案,但站在性能和安全的角度,更新緩存則可能會導致一些不好的後果。

首先是性能 ,當該緩存對應的結果需要消耗大量的計算過程才能得到時,比如需要訪問多張資料庫表並聯合計算,那麼在寫操作中更新緩存的動作將會是一筆不小的開銷。同時,當寫操作較多時,可能也會存在剛更新的緩存還沒有被讀取到,又再次被更新的情況(這常被稱為緩存擾動),顯然,這樣的更新是白白消耗機器性能的,會導致緩存利用率不高。

而等到讀請求未命中緩存時再去更新,也符合懶載入的思路,需要時再進行計算。刪除緩存的操作不僅是冪等的,可以在發生異常時重試,而且寫-刪除和讀-更新在語義上更加對稱。

其次是安全 ,在並發場景下,在寫請求中更新緩存可能會引發數據的不一致問題。參考下面的圖示,若存在兩個來自不同線程的寫請求,首先來自線程 1 的寫請求更新了資料庫(step 1),接著來自線程 2 的寫請求再次更新了資料庫(step 3),但由於網路延遲等原因,線程 1 可能會晚於線程 2 更新緩存(step 4 晚於 step 3),那麼這樣便會導致最終寫入資料庫的結果是來自線程 2 的新值,寫入緩存的結果是來自線程 1 的舊值,即緩存落後於資料庫,此時再有讀請求命中緩存(step 5),讀取到的便是舊值。


2、為什麼先更新資料庫,而不是先刪除緩存?

另外,有讀者也會對更新資料庫和刪除緩存的時序產生疑問,那麼為什麼不先刪除緩存,再更新資料庫呢?在單線程下,這種方案看似具有一定合理性,這種合理性體現在刪除緩存成功。

但更新資料庫失敗的場景下,盡管緩存被刪除了,下次讀操作時,仍能將正確的數據寫回緩存,相對於 Cache-Aside 中更新資料庫成功,刪除緩存失敗的場景來說,先刪除緩存的方案似乎更合理一些。那麼,先刪除緩存有什麼問題呢?

問題仍然出現在並發場景下,首先來自線程 1 的寫請求刪除了緩存(step 1),接著來自線程 2 的讀請求由於緩存的刪除導致緩存未命中,根據 Cache-Aside 模式,線程 2 繼而查詢資料庫(step 2),但由於寫請求通常慢於讀請求,線程 1 更新資料庫的操作可能會晚於線程 2 查詢資料庫後更新緩存的操作(step 4 晚於 step 3),那麼這樣便會導致最終寫入緩存的結果是來自線程 2 中查詢到的舊值,而寫入資料庫的結果是來自線程 1 的新值,即緩存落後於資料庫,此時再有讀請求命中緩存( step 5 ),讀取到的便是舊值。


另外,先刪除緩存,由於緩存中數據缺失,加劇資料庫的請求壓力,可能會增大緩存穿透出現的概率。

3、如果選擇先刪除緩存,再更新資料庫,那如何解決一致性問題呢?

為了避免「先刪除緩存,再更新資料庫」這一方案在讀寫並發時可能帶來的緩存臟數據,業界又提出了延時雙刪的策略,即在更新資料庫之後,延遲一段時間再次刪除緩存,為了保證第二次刪除緩存的時間點在讀請求更新緩存之後,這個延遲時間的經驗值通常應稍大於業務中讀請求的耗時。

延遲的實現可以在代碼中 sleep 或採用延遲隊列。顯而易見的是,無論這個值如何預估,都很難和讀請求的完成時間點准確銜接,這也是延時雙刪被詬病的主要原因。


4、那麼 Cache-Aside 存在數據不一致的可能嗎?

在 Cache-Aside 中,也存在數據不一致的可能性。在下面的讀寫並發場景下,首先來自線程 1 的讀請求在未命中緩存的情況下查詢資料庫(step 1),接著來自線程 2 的寫請求更新資料庫(step 2),但由於一些極端原因,線程 1 中讀請求的更新緩存操作晚於線程 2 中寫請求的刪除緩存的操作(step 4 晚於 step 3),那麼這樣便會導致最終寫入緩存中的是來自線程 1 的舊值,而寫入資料庫中的是來自線程 2 的新值,即緩存落後於資料庫,此時再有讀請求命中緩存(step 5),讀取到的便是舊值。

這種場景的出現,不僅需要緩存失效且讀寫並發執行,而且還需要讀請求查詢資料庫的執行早於寫請求更新資料庫,同時讀請求的執行完成晚於寫請求。足以見得,這種 不一致場景產生的條件非常嚴格,在實際的生產中出現的可能性較小 。


除此之外,在並發環境下,Cache-Aside 中也存在讀請求命中緩存的時間點在寫請求更新資料庫之後,刪除緩存之前,這樣也會導致讀請求查詢到的緩存落後於資料庫的情況。


雖然在下一次讀請求中,緩存會被更新,但如果業務層面對這種情況的容忍度較低,那麼可以採用加鎖在寫請求中保證「更新資料庫&刪除緩存」的串列執行為原子性操作(同理也可對讀請求中緩存的更新加鎖)。 加鎖勢必會導致吞吐量的下降,故採取加鎖的方案應該對性能的損耗有所預期。


2

補償機制


我們在上面提到了,在 Cache-Aside 中可能存在更新資料庫成功,但刪除緩存失敗的場景,如果發生這種情況,那麼便會導致緩存中的數據落後於資料庫,產生數據的不一致的問題。

其實,不僅 Cache-Aside 存在這樣的問題,在延時雙刪等策略中也存在這樣的問題。針對可能出現的刪除失敗問題,目前業界主要有以下幾種補償機制。

1、刪除重試機制

由於同步重試刪除在性能上會影響吞吐量,所以常通過引入消息隊列,將刪除失敗的緩存對應的 key 放入消息隊列中,在對應的消費者中獲取刪除失敗的 key ,非同步重試刪除。這種方法在實現上相對簡單,但由於刪除失敗後的邏輯需要基於業務代碼的 trigger 來觸發 ,對業務代碼具有一定入侵性。


鑒於上述方案對業務代碼具有一定入侵性,所以需要一種更加優雅的解決方案,讓緩存刪除失敗的補償機制運行在背後,盡量少的耦合於業務代碼。一個簡單的思路是通過後台任務使用更新時間戳或者版本作為對比獲取資料庫的增量數據更新至緩存中,這種方式在小規模數據的場景可以起到一定作用,但其擴展性、穩定性都有所欠缺。

一個相對成熟的方案是基於 MySQL 資料庫增量日誌進行解析和消費,這里較為流行的是阿里巴巴開源的作為 MySQL binlog 增量獲取和解析的組件 canal(類似的開源組件還有 Maxwell、Databus 等)。

canal sever 模擬 MySQL slave 的交互協議,偽裝為 MySQL slave,向 MySQL master 發送 mp 協議,MySQL master 收到 mp 請求,開始推送 binary log 給 slave (即 canal sever ),canal sever 解析 binary log 對象(原始為 byte 流),可由 canal client 拉取進行消費,同時 canal server 也默認支持將變更記錄投遞到 MQ 系統中,主動推送給其他系統進行消費。

在 ack 機制的加持下,不管是推送還是拉取,都可以有效的保證數據按照預期被消費。當前版本的 canal 支持的 MQ 有 Kafka 或者 RocketMQ。另外, canal 依賴 ZooKeeper 作為分布式協調組件來實現 HA ,canal 的 HA 分為兩個部分:


那麼,針對緩存的刪除操作便可以在 canal client 或 consumer 中編寫相關業務代碼來完成。這樣,結合資料庫日誌增量解析消費的方案以及 Cache-Aside 模型,在讀請求中未命中緩存時更新緩存(通常這里會涉及到復雜的業務邏輯),在寫請求更新資料庫後刪除緩存,並基於日誌增量解析來補償資料庫更新時可能的緩存刪除失敗問題,在絕大多數場景下,可以有效的保證緩存的最終一致性。

另外需要注意的是,還應該隔離事務與緩存,確保資料庫入庫後再進行緩存的刪除操作。 比如考慮到資料庫的主從架構,主從同步及讀從寫主的場景下,可能會造成讀取到從庫的舊數據後便更新了緩存,導致緩存落後於資料庫的問題,這就要求對緩存的刪除應該確保在資料庫操作完成之後。所以,基於 binlog 增量日誌進行數據同步的方案,可以通過選擇解析從節點的 binlog,來避免主從同步下刪除緩存過早的問題。

3、數據傳輸服務 DTS


3

Read-Through


Read-Through 意為讀穿透模式,它的流程和 Cache-Aside 類似,不同點在於 Read-Through 中多了一個訪問控制層,讀請求只和該訪問控制層進行交互,而背後緩存命中與否的邏輯則由訪問控制層與數據源進行交互,業務層的實現會更加簡潔,並且對於緩存層及持久化層交互的封裝程度更高,更易於移植。


4

Write-Through


Write-Through 意為直寫模式,對於 Write-Through 直寫模式來說,它也增加了訪問控制層來提供更高程度的封裝。不同於 Cache-Aside 的是,Write-Through 直寫模式在寫請求更新資料庫之後,並不會刪除緩存,而是更新緩存。


這種方式的 優勢在於讀請求過程簡單 ,不需要查詢資料庫更新緩存等操作。但其劣勢也非常明顯,除了上面我們提到的更新資料庫再更新緩存的弊端之外,這種方案還會造成更新效率低,並且兩個寫操作任何一次寫失敗都會造成數據不一致。

如果要使用這種方案, 最好可以將這兩個操作作為事務處理,可以同時失敗或者同時成功,支持回滾,並且防止並發環境下的不一致 。另外,為了防止緩存擾動的頻發,也可以給緩存增加 TTL 來緩解。

站在可行性的角度,不管是 Write-Through 模式還是 Cache-Aside 模式,理想狀況下都可以通過分布式事務保證緩存層數據與持久化層數據的一致性,但在實際項目中,大多都對一致性的要求存在一些寬容度,所以在方案上往往有所折衷。

Write-Through 直寫模式適合寫操作較多,並且對一致性要求較高的場景,在應用 Write-Through 模式時,也需要通過一定的補償機制來解決它的問題。首先,在並發環境下,我們前面提到了先更新資料庫,再更新緩存會導致緩存和資料庫的不一致,那麼先更新緩存,再更新資料庫呢?

這樣的操作時序仍然會導致下面這樣線程 1 先更新緩存,最後更新資料庫的情況,即由於線程 1 和 線程 2 的執行不確定性導致資料庫和緩存的不一致。這種由於線程競爭導致的緩存不一致,可以通過分布式鎖解決,保證對緩存和資料庫的操作僅能由同一個線程完成。對於沒有拿到鎖的線程,一是通過鎖的 timeout 時間進行控制,二是將請求暫存在消息隊列中順序消費。


在下面這種並發執行場景下,來自線程 1 的寫請求更新了資料庫,接著來自線程 2 的讀請求命中緩存,接著線程 1 才更新緩存,這樣便會導致線程 2 讀取到的緩存落後於資料庫。同理,先更新緩存後更新資料庫在寫請求和讀請求並發時,也會出現類似的問題。面對這種場景,我們也可以加鎖解決。


另在,在 Write-Through 模式下,不管是先更新緩存還是先更新資料庫,都存在更新緩存或者更新資料庫失敗的情況,上面提到的重試機制和補償機制在這里也是奏效的。


5

Write-Behind


Write behind 意為非同步回寫模式,它也具有類似 Read-Through/Write-Through 的訪問控制層,不同的是,Write behind 在處理寫請求時,只更新緩存而不更新資料庫,對於資料庫的更新,則是通過批量非同步更新的方式進行的,批量寫入的時間點可以選在資料庫負載較低的時間進行。

在 Write-Behind 模式下,寫請求延遲較低,減輕了資料庫的壓力,具有較好的吞吐性。但資料庫和緩存的一致性較弱,比如當更新的數據還未被寫入資料庫時,直接從資料庫中查詢數據是落後於緩存的。同時,緩存的負載較大,如果緩存宕機會導致數據丟失,所以需要做好緩存的高可用。顯然,Write behind 模式下適合大量寫操作的場景,常用於電商秒殺場景中庫存的扣減。


6

Write-Around


如果一些非核心業務,對一致性的要求較弱,可以選擇在 cache aside 讀模式下增加一個緩存過期時間,在寫請求中僅僅更新資料庫,不做任何刪除或更新緩存的操作,這樣,緩存僅能通過過期時間失效。這種方案實現簡單,但緩存中的數據和資料庫數據一致性較差,往往會造成用戶的體驗較差,應慎重選擇。


7

總結


在解決緩存一致性的過程中,有多種途徑可以保證緩存的最終一致性,應該根據場景來設計合適的方案,讀多寫少的場景下,可以選擇採用「Cache-Aside 結合消費資料庫日誌做補償」的方案,寫多的場景下,可以選擇採用「Write-Through 結合分布式鎖」的方案 ,寫多的極端場景下,可以選擇採用「Write-Behind」的方案。

『捌』 同級別的CPU,AMD的一級緩存是不是總比INTEL的大一級緩存和二級緩存哪個更重要

再 P4 到 酷睿 這段時間,AMD的主頻比同檔次的INTEL要低,但是一級緩存大,流水量更短,構架更先進,鍵亮所以這段時間的AMD性能比同等INTEL要強。
一級緩存和二級緩存,當然是一級更重要,就好比你是個工人,一級緩存是你手邊的工具,二級緩存是你工具箱里的工具,手邊的工具越多,你的效率就越高,當手邊沒有你要的工具時,你就要花時間去工具箱里找,速度就慢了下來。
納米大小,指的是雕刻的精度,不橘咐管是P4還是酷睿,cpU的大小都沒變,但是酷睿是45UM的,元件就多了很多,性能就高了很多。
這些東西說的稿伍寬比較籠統,希望你能系統學習一下。

『玖』 雲南北大青鳥設計培訓告訴你PHP應用中常用的9大緩存技術

一、全頁面靜態化緩存



也就是將頁面全部生成html靜態頁面,用戶訪問時直接訪問的靜態頁面,而不會去走php伺服器解析的流程。此種方式,在CMS系統中比較常見,比如dedecms;


一種比較常用的實現方式是用輸出緩存:


Ob_start()******要運行的代碼*******$content=Ob_get_contents();****將緩存內容寫入html文件*****Ob_end_clean();


二、數據緩存


顧名思義,就是緩存數據的一種方式;比如,商城中的某個商品信息,當用商品id去請求時,就會得出包括店鋪信息、商品信息等數據,此時就可以將這些數據緩存到一個php文件中,文件名包含商品id來建一個唯一標示;下一次有人想查看這個商品時,首先就直接調這個文件裡面的信息,而不用再去資料庫查詢;其實緩存文件中緩存的就是一個php數組之類;


Ecmall商城系統裡面就用了這種方式;




三、查詢緩存


其實這跟數據緩存是一個思路,就是根據查詢語句來緩存;將查詢得到的數據緩存在一個文件中,下次遇到相同的查詢時,就直接先從這個文件裡面調數據,不會再去查資料庫;但此處的緩存文件名可能就需要以查詢語句為基點來建立唯一標示;


按時間變更進行緩存


就是對於緩存文件您需要設一個有效時間,在這個有效時間內,相同的訪問才會先取緩存文件的內容,但是超過設定的緩存時間,就需要重新從資料庫中獲取數據,並生產最新的緩存文件;比如,我將我們商城的首頁就是設置2個小時更新一次。


四、頁面部分緩存


該種方式,是將一個頁面中不經常變的部分進行靜態緩存,而經常變化的塊不緩存,最後組裝在一起顯示;可以使用類似於ob_get_contents的方式實現,也可以利用類似ESI之類的頁面片段緩存策略,使其用來做動態頁面中相對靜態的片段部分的緩存。


該種方式可以用於如商城中的商品頁;


五、Opcode緩存


首先php代碼被解析為Tokens,然後再編譯為Opcode碼,最後執行Opcode碼,返回結果;所以,對於相同的php文件,第一次運行時可以緩存其Opcode碼,下次再執行這個頁面時,直接會去找到緩存下的opcode碼,直接執行最後一步,而不再需要中間的步驟了。


比較知名的是XCache、TurckMMCache、PHPAccelerator等。


六、按內容變更進行緩存


這個也並非獨立的緩存技術,需結合著用;就是當資料庫內容被修改時,即刻更新緩存文件;


比如,一個人流量很大的商城,商品很多,商品表必然比較大,這表的壓力也比較重;我們就可以對商品顯示頁進行頁面緩存;


當商家在後台修改這個商品的信息時,點擊保存,我們同時就更新緩存文件;那麼,買家訪問這個商品信息時,實際問的是一個靜態頁面,而不需要再去訪問資料庫;


試想,如果對商品頁不緩存,那麼每次訪問一個商品就要去資料庫查一次,如果有10萬人在線瀏覽商品,那伺服器壓力就大了;


七、內存式緩存


提到這個,可能大家想到的首先就是Memcached;memcached是高性能的分布式內存緩存伺服器。一般的使用目的是,通過緩存資料庫查詢結果,減少資料庫訪問次數,以提高動態Web應用的速度、提高可擴展性。


它就是將需要緩存的信息,緩存到系統內存中,需要獲取信息時,直接到內森塌存中取;比較常用的方式就是key_>value方式;緩孝


connect($memcachehost,$memcacheport)ordie("Couldnotconnect");$memcache->set('key','緩存的內容');$get=$memcache->get($key);//獲取信息?>


八、apache緩存模塊


apache安裝完以後,是不允許被cache的。大理IT培訓http://www.kmbdqn.cn/認為如果外接了cache或squid伺服器要求進行web加速的話,就需要在htttpd.conf里進行設置,當然前提是在安裝apache的時候要激活mod_cache的模塊。此哪圓


『拾』 Ceph 分層緩存--Tiering Cache

原文來自Ceph官方文檔: CACHE TIERING

部分摘抄自Ceph中國社區翻譯文檔: 分級緩存

    分層緩存為ceph客戶端中的某些存放在存儲層的數據提供更好的IO性能。分級緩存需創建一個由高速而昂貴存儲設備(如 SSD )組成的存儲池、作為緩存層,以及一個相對低速/廉價設備組成的後端存儲池(或糾刪碼編碼的)、作為經濟存儲層。Ceph 的對象處理器決定往哪裡存儲對象,分級代理決定何時把緩存內的對象刷回後端存儲層;所以緩存層和後端存儲層對 Ceph 客戶端來孫禪孝說是完全透明的。

    緩存代理層管理著數據在緩存層和存儲層之間的自動遷移。但是, 管理員也可以通過配置來干預遷移規則, 下面是對兩個主要場景的介紹:

Writeback Mode: 當管理員將緩存層配置成回寫模式, Ceph客戶端將數據寫入緩存層,並接收返回的ACK。同時,寫入緩存層的數據遷移到存儲層,  然後從緩存層刷掉。 直觀的看, 緩存層在存儲層之前。 當Ceph客戶端需要存在於存儲層的數據時, 緩存層代理會把這些數據遷移到緩存層,然後再發往 Ceph 客戶端。因此,Ceph 客戶端將與緩存層進行 I/O 操作,直到數據不再被讀寫。此模式對於易變數據來說較理想(如照片/視頻編輯、事務數據等)。

Read-proxy Mode: 這個模式將使用一些已經存在於緩存層的數據,但是,如果數據不在緩存層,請求將被代理轉發到底層。這個模式對於從回寫模式過渡到禁用緩存非常有用的, 因為它潤需負載一直工作到緩存乾涸,不再向緩存添加任何數據。

  如果負載過多,分層緩存會降低性能。用戶在使用以下特性時需要極其謹慎。

Workload dependent : 緩存是否能提升性能,高度依賴於負載能力。因為將數據移入或移除緩存會導致額外的開銷,它只在對數據集的訪問有大的偏離時有影響。例如, 眾多的請求訪問小數量的objects,這時,你的緩存池需要非常大,才能在處理所有請求時,避免數據過渡。

Difficult to benchmark : 用戶使用評測性能時,大部分的關於分層緩存bechmarks測試結果,將會是一個糟糕的結果。其中部分原因是很少的bechmarks傾斜於一組小的對象集合的請求 , 這會使緩存經過很長時間後才能「活躍起來」,並且這種「活躍起來」會導致高昂的開銷。

Usually slower : 對於並沒有友好使用分級緩存的工作負載,性能普遍低於一個沒使用分級緩存的普通rados池。

librados object enumeration : 對於librados級別的枚舉對象API並不能連貫存在在這種情況中(The librados-level object enumeration API is not meant to be coherent in the presence of the case)。 如果你的應用直接使用則稿rados,並且依賴於枚舉對象,分級緩存不能向期待的那樣工作. (對於RGW, RBD, or CephFS,沒有這個問題)

Complexity : 在使用RADOS集群時,使用分級緩存意味著大量的額外器械和復雜性。這會增加你遇到未知的BUG(可能其他人未遇到過)的可能性, 並且使你的部署擁有更大的風險。

RGW time-skewed : 如果RGW工作中遇到的大部分操作是朝向最近寫入的數據,一個簡單的分級緩存可以工作得很好。

    下面的配置使用分層緩存效果不佳。

RBD with replicated cache and erasure-coded base : 這是一個普遍的需求, 但是通常不能很好工作。即使合理的傾斜工作負載,仍然會遇到一些對於冷門object的寫操作的情況,並且由於糾刪襲仿碼類型的池還不支持輕微的讀寫操作,為了適應一些小的寫入操作(通常4kb),整個object塊(通常4MB)必須被全部遷移到緩存 。只有少數用戶成功的應用了這種部署方式,並且這種部署方案只能為他們工作是因為他們的數據是極其「冷門」的(例如備份),並且他們對於性能並不敏感。

RBD with replicated cache and base : 在使用備份類型為基礎層時比以糾刪碼為基礎層時,RBD的表現更為良好, 但是它在工作負載中仍然依賴於大量的傾斜,並且很難驗證。用戶需要對他們的工作負載有更好的理解, 並且需要仔細調整分層緩存參數。

    為了建立分層緩存,你必須擁有兩個存儲池。一個作為後端存儲,一個作為緩存。

    建立一個後端存儲池包含兩種場景:

標准存儲 : 在這種場景中,這個池在Ceph存儲集群中存儲一個對象的多個副本。

糾刪碼: 在這種場景中,存儲池用糾刪碼高效地存儲數據,性能稍有損失。

    在標准存儲場景中,你可以用 CRUSH 規則集來標識失敗域(如 osd 、主機、機箱、機架、排等)。當規則集所涉及的所有驅動器規格、速度(轉速和吞吐量)和類型相同時, OSD 守護進程運行得最優。創建規則集的詳情見 CRUSH 圖 。創建好規則集後,再創建後端存儲池。

     在糾刪碼編碼情景中,創建存儲池時指定好參數就會自動生成合適的規則集,詳情見 創建存儲池 。

     在後續例子中,我們把cold-storage當作後端存儲池。