發(fā)布于:2020-12-31 14:11:02
0
176
0
所以…緩存。它是什么?這是一種快速獲得收益的方法,無需反復(fù)計(jì)算或獲取內(nèi)容,從而獲得性能和成本優(yōu)勢(shì)。這也是它的名字來源,它是“cache -ching!”收銀機(jī)的聲音來自2014年的黑暗時(shí)代,那時(shí)還沒有Apple Pay,實(shí)物貨幣還很流行。我現(xiàn)在是父親了,接受現(xiàn)實(shí)吧。
假設(shè)我們需要調(diào)用一個(gè)API或查詢數(shù)據(jù)庫(kù)服務(wù)器,或者只是取一大堆數(shù)字(谷歌表示這是一個(gè)實(shí)際的單詞,我檢查過了),然后把它們加起來。這些都相當(dāng)昂貴。所以我們緩存結(jié)果——我們讓它便于重用。
我們?yōu)槭裁匆彺妫?/span>
我認(rèn)為討論這個(gè)問題在這里重要的 是多么昂貴 上面的一些東西?,F(xiàn)代計(jì)算機(jī)中已經(jīng)有幾層緩存在起作用。作為一個(gè)具體的例子,我們將使用我們的一個(gè)Web服務(wù)器,該服務(wù)器目前裝有一對(duì) Intel Xeon E5-2960 v3 CPU 和2133MHz DIMM。高速緩存訪問是處理器的“多少個(gè)周期”功能,因此通過知道我們始終以3.06GHz(性能功耗模式)運(yùn)行,我們可以得出延遲(此處為Intel體系結(jié)構(gòu)參考 –這些處理器屬于Haswell一代):
L1(每個(gè)內(nèi)核):4個(gè)周期或 ?1.3ns 延遲– 12x 32KB + 32KB
L2(每個(gè)內(nèi)核):12個(gè)周期或 ?3.92ns 延遲– 12x 256KB
L3(共享):34個(gè)周期或 ?11.11ns 延遲– 30MB
系統(tǒng)內(nèi)存: ?100ns 延遲– 8倍8GB
每個(gè)緩存層都可以存儲(chǔ)更多,但是距離更遠(yuǎn)。在處理器設(shè)計(jì)中要權(quán)衡取舍。例如,平均每個(gè)內(nèi)核更多的內(nèi)存意味著(幾乎可以肯定)意味著將其與內(nèi)核之間的距離更遠(yuǎn),這會(huì)增加延遲,機(jī)會(huì)成本和功耗。在此范圍內(nèi),電子必須行進(jìn)多遠(yuǎn)會(huì)產(chǎn)生重大影響。請(qǐng)記住,距離 每秒乘以 數(shù)十億。
而且我沒有涉及上面的磁盤延遲,因?yàn)槲覀兒苌俳佑|磁盤。為什么?好吧,我想解釋一下,我們需要……看一下磁盤。哦,閃閃發(fā)光的磁盤!但請(qǐng)不要在襪子跑動(dòng)后觸摸它們。在Stack Overflow上,任何不是備份或日志記錄服務(wù)器的產(chǎn)品都位于SSD上。本地存儲(chǔ)通常分為以下幾層:
NVMe SSD:?120μs(來源)
SATA或SAS SSD:?400–600μs(來源)
旋轉(zhuǎn)硬盤:2–6ms(源)
這些數(shù)字一直在變化,所以不要過多地關(guān)注確切的數(shù)字。我們?cè)噲D評(píng)估的是這些存儲(chǔ)層之間差異的大小。讓我們看一下列表(假設(shè)每個(gè)數(shù)字的下限,這是最好的數(shù)字):
L1:1.3ns
L2:3.92ns(慢3倍)
L3:11.11ns(慢8.5倍)
DDR4 RAM:100ns(慢77倍)
NVMe SSD:120,000ns(慢92,307倍)
SATA / SAS SSD:400,000ns(慢307,692x)
旋轉(zhuǎn)硬盤:2–6ms(慢1,538,461x)
Microsoft Live登錄:12次重定向和5秒(慢3,846,153,846倍,大約)
如果數(shù)字不是您的事, 這是Colin Scott提供的簡(jiǎn)潔的開源可視化效果 (使用滑塊?。?nbsp; (您甚至可以查看它們隨著時(shí)間的推移是如何演變的-確實(shí)很簡(jiǎn)潔):
考慮到這些績(jī)效數(shù)字并考慮規(guī)模感,讓我們添加一些每天都很重要的數(shù)字。假設(shè)我們的數(shù)據(jù)源是 X, X 無關(guān)緊要。它可能是SQL,或者是微服務(wù),或者是宏服務(wù),或者是左墊服務(wù),或者是Redis,或者是磁盤上的文件等。這里的關(guān)鍵是我們正在將源的性能與RAM的性能進(jìn)行比較。假設(shè)我們的來源需要……
100ns(從RAM –快速?。?/span>
1ms(慢10,000倍)
100ms(慢100,000倍)
1秒(慢1,000,000倍)
我不認(rèn)為我們需要去進(jìn)一步說明這一點(diǎn): 即只需要1毫秒,即使事情的方式, 方法 比本地內(nèi)存要慢。請(qǐng)記住:毫秒,微秒,納秒–以防萬一其他人忘記了1000ns!= 1ms,就像我有時(shí)做的那樣……
但是并不是所有的緩存都是本地的。例如,我們使用Redis進(jìn)行Web層背后的共享緩存(我們將在稍后介紹))。假設(shè)我們要遍及整個(gè)網(wǎng)絡(luò)來獲取它。對(duì)于我們來說,這是一個(gè)0.17毫秒的往返,您還需要發(fā)送一些數(shù)據(jù)。對(duì)于小物件(通常),總共約為0.2-0.5ms。仍然比本地RAM慢2000–5,000倍,但也比大多數(shù)來源快很多。請(qǐng)記住,這些數(shù)字是因?yàn)槲覀兾挥谛⌒途钟蚓W(wǎng)中。云延遲通常會(huì)更高,因此請(qǐng)查看您的延遲。
當(dāng)我們獲得數(shù)據(jù)時(shí),也許我們也想以某種方式對(duì)其進(jìn)行按摩??赡苁侨鸬淙恕R苍S我們需要總計(jì),也許我們需要過濾,也許我們需要對(duì)其進(jìn)行編碼,也許我們需要隨機(jī)捏弄它以欺騙您。那是一項(xiàng)測(cè)試,看您是否還在閱讀。你通過了!不管原因是什么,通用性通常是 我們想做 <x> 一次,而不是 每次我們服務(wù)時(shí)。
有時(shí)我們節(jié)省延遲,有時(shí)我們節(jié)省CPU。通常,其中一個(gè)或兩個(gè)都是為什么要引入緩存?,F(xiàn)在,讓我們涵蓋另一面...
為什么我們不緩存?
對(duì)于每個(gè)討厭緩存的人,這是給您的部分!是的,我完全扮演雙方的角色。
鑒于上述情況以及獲勝的激烈程度, 我們?yōu)槭裁?不緩存一些東西?好吧,因?yàn)?每個(gè)決策都需要權(quán)衡取舍。每一個(gè) 單。一。它可以很簡(jiǎn)單,只需花費(fèi)時(shí)間或機(jī)會(huì)成本,但仍然需要權(quán)衡取舍。
當(dāng)涉及到緩存時(shí),添加緩存會(huì)帶來一些成本:
在需要時(shí)以及在需要時(shí)清除值(緩存無效- 我們將在少數(shù)幾個(gè)中介紹)
緩存使用的內(nèi)存
訪問緩存的延遲(權(quán)衡了對(duì)源的訪問)
花費(fèi)更多的時(shí)間和精力在調(diào)試更復(fù)雜的事情上
每當(dāng)出現(xiàn)緩存候選對(duì)象(通常具有新功能)時(shí),我們都需要評(píng)估這些內(nèi)容……這并不總是一件容易的事。盡管緩存是一門精確的科學(xué),就像占星術(shù)一樣,它仍然很棘手。
在Stack Overflow,我們的體系結(jié)構(gòu)具有一個(gè)總體主題:使其盡可能簡(jiǎn)單。簡(jiǎn)單易于評(píng)估,推理,調(diào)試和根據(jù)需要進(jìn)行更改。僅在需要時(shí)和更復(fù)雜的情況 下使其更復(fù)雜。這包括緩存。僅在需要時(shí)緩存。它增加了更多的工作并 增加了錯(cuò)誤的機(jī)會(huì),因此除非需要,否則:不需要。至少還沒有。
讓我們開始問一些問題。
命中緩存快得多嗎?
我們要保存什么?
值得儲(chǔ)存嗎?
是否值得清理上述存儲(chǔ)(例如垃圾收集)?
它會(huì)立即在大對(duì)象堆上繼續(xù)嗎?
我們必須多久使它失效一次?
我們認(rèn)為每個(gè)緩存條目會(huì)有多少次點(diǎn)擊?
它會(huì)與其他使無效化復(fù)雜化的事物發(fā)生相互作用嗎?
會(huì)有多少個(gè)變體?
我們是否僅需分配就可以計(jì)算密鑰?
它是本地還是遠(yuǎn)程緩存?
用戶之間共享嗎?
站點(diǎn)之間共享嗎?
它是依靠量子糾纏還是調(diào)試它只是讓您認(rèn)為呢?
緩存是什么顏色?
所有這些都是提出來并影響緩存決策的問題。我將嘗試通過這篇文章覆蓋它們。
堆棧溢出時(shí)的緩存層
我們?cè)赟tack Overflow上擁有自己的“ L1” /“ L2”緩存,但是為了避免與上述CPU緩存混淆,我將避免以這種方式引用它們。我們擁有幾種類型的緩存。在深入探究它們使用的通用位之前,讓我們首先在此處快速介紹本地和內(nèi)存緩存的術(shù)語。
“全局緩存”:內(nèi)存中的緩存(全局,每個(gè)Web服務(wù)器,并在未命中時(shí)由Redis支持)
通常情況下,諸如用戶的最高收入限額之類的東西在網(wǎng)絡(luò)上共享
這將命中本地內(nèi)存(共享密鑰空間),然后是Redis(共享密鑰空間,使用Redis數(shù)據(jù)庫(kù)0)
“站點(diǎn)緩存”:內(nèi)存中緩存(每個(gè)站點(diǎn),每個(gè)Web服務(wù)器,并在未命中時(shí)由Redis支持)
通常,每個(gè)站點(diǎn)的問題列表或用戶列表之類的內(nèi)容
這會(huì)命中本地內(nèi)存(使用前綴的每個(gè)站點(diǎn)密鑰空間),然后是Redis(使用Redis數(shù)據(jù)庫(kù)的每個(gè)站點(diǎn)密鑰空間)
“本地緩存”:內(nèi)存緩存(每個(gè)站點(diǎn),每個(gè)Web服務(wù)器,無任何支持 )
通常情況下,價(jià)格便宜但可串流播放且Redis躍點(diǎn)不值得
這只會(huì)影響本地內(nèi)存(每個(gè)站點(diǎn)的鍵空間,使用前綴)
我們所說的“每站點(diǎn)”是什么意思?堆棧溢出和站點(diǎn)的堆棧交換網(wǎng)絡(luò)是 一個(gè)多租戶架構(gòu)。堆棧溢出只是 數(shù)百個(gè)站點(diǎn)之一。這意味著Web服務(wù)器上的一個(gè)進(jìn)程將托管所有站點(diǎn),因此我們需要在需要的地方拆分緩存。而且我們必須清除它(我們還將介紹它的工作原理)。
Redis
在討論服務(wù)器和共享緩存的工作方式之前,讓我們快速介紹一下共享位的基礎(chǔ):Redis。那么,Redis是什么 ?這是一個(gè)開放源代碼鍵/值數(shù)據(jù)存儲(chǔ),具有許多有用的數(shù)據(jù)結(jié)構(gòu),附加的發(fā)布/訂閱者機(jī)制以及堅(jiān)如磐石的穩(wěn)定性。
為什么不使用Redis <something else>?好吧,因?yàn)樗行А6倚Ч芎?。?dāng)我們需要共享緩存時(shí),這似乎是一個(gè)好主意。這 真是令人難以置信的 堅(jiān)如磐石。我們沒有等待-它的速度非???。我們知道它是如何工作的。我們對(duì)此非常熟悉。我們知道如何監(jiān)視它。我們知道如何拼寫。我們?yōu)榇司S護(hù)了最常用的開源庫(kù)之一。如果需要,我們可以調(diào)整該庫(kù)。
這是我們的基礎(chǔ)設(shè)施 只是不用擔(dān)心。我們基本上認(rèn)為這是理所當(dāng)然的(盡管我們?nèi)匀挥蠬A副本設(shè)置–我們并不 完全 瘋狂)。在選擇基礎(chǔ)架構(gòu)時(shí),您不只是為了獲得可能的價(jià)值而進(jìn)行更改。改變需要付出努力,花費(fèi)時(shí)間并帶來風(fēng)險(xiǎn)。如果您擁有的東西運(yùn)作良好并且需要您做什么,為什么還要花時(shí)間和精力去冒險(xiǎn)?好吧...你不知道。隨著時(shí)間的流逝,您可以做數(shù)千件更好的事情。就像辯論哪個(gè)緩存服務(wù)器是最好的一樣!
我們有一些Redis實(shí)例來區(qū)分應(yīng)用程序的關(guān)注點(diǎn)(但在同一組服務(wù)器上),這是一個(gè)看起來像這樣的示例:
出于好奇,上周二(2019-07-30)的一些快速統(tǒng)計(jì)信息涵蓋了主框上的所有實(shí)例(因?yàn)槲覀儗⑺鼈儾鸱钟糜诮M織工作,而不是性能……一個(gè)實(shí)例可以輕松完成我們的所有工作):
我們的Redis物理服務(wù)器具有256GB內(nèi)存,但使用的內(nèi)存少于96GB。
每天處理1,586,553,473條命令(由于副本,在所有實(shí)例中,每秒3,726,580,897條命令和每秒86,982個(gè)峰值)
整個(gè)服務(wù)器的平均CPU利用率為2.01%(峰值為3.04%)(即使是最活躍的實(shí)例,均<1%)
124,415,398個(gè)活動(dòng)密鑰(包括副本的422,818,481個(gè))
這些數(shù)字遍及308,065,226個(gè)HTTP命中(其中64,717,337個(gè)是問題頁(yè)面)
注意:這些都不是Redis的限制-我們還沒有任何限制。只是我們的實(shí)例上有多少活動(dòng)。
還有其他非緩存原因,我們使用Redis,即:我們還對(duì)Websocket使用pub / sub機(jī)制 , 以提供有關(guān)樂譜,代表等的實(shí)時(shí)更新。Redis5.0 添加了Streams ,這非常適合我們的Websocket,我們當(dāng)其他一些基礎(chǔ)架構(gòu)就緒時(shí)(可能主要受Stack Overflow Enterprise版本的限制),它們可能會(huì)遷移到它們。
作者介紹
熱門博客推薦