Pinterest大規(guī)模緩存集群的架構(gòu)剖析,pinterest后臺(tái)分析Pinterest大規(guī)模緩存集群的架構(gòu)剖析作者 Kevin Lin譯者 朱琪珊策劃 萬(wàn)佳隨著越來(lái)越多的用戶到 Pinterest 尋求靈感,Pinterest 核心基礎(chǔ)設(shè)施系統(tǒng)的需求增長(zhǎng)的比以往任何時(shí)候都快。我們的核心存儲(chǔ)系統(tǒng)之一是位于許多微服......
作者 Kevin Lin
譯者 朱琪珊
策劃 萬(wàn)佳
隨著越來(lái)越多的用戶到 Pinterest 尋求靈感,Pinterest 核心基礎(chǔ)設(shè)施系統(tǒng)的需求增長(zhǎng)的比以往任何時(shí)候都快。我們的核心存儲(chǔ)系統(tǒng)之一是位于許多微服務(wù)和數(shù)據(jù)庫(kù)前面的分布式緩存層。它處于 Pinterest 基礎(chǔ)架構(gòu)技術(shù)棧的底部,負(fù)責(zé)吸收由用戶增長(zhǎng)驅(qū)動(dòng)的絕大多數(shù)后端流量。
Pinterest 的分布式緩存集群建立在 AWS 的 EC2 實(shí)例上,由數(shù)千臺(tái)機(jī)器組成,緩存了數(shù)百 TB 的數(shù)據(jù),高峰時(shí),每秒可處理 1.5 億個(gè)請(qǐng)求。該緩存層通過(guò)降低整個(gè)后端技術(shù)棧的延遲,來(lái)優(yōu)化頂層性能,并通過(guò)減少昂貴的后端所需的容量來(lái)提供顯著的成本效率。
本文中,我們將對(duì)支持 Pinterest 的大規(guī)模緩存集群的架構(gòu)進(jìn)行深入的技術(shù)研究。
1應(yīng)用數(shù)據(jù)緩存
每個(gè)對(duì) Pinterest 的 API 請(qǐng)求都會(huì)在內(nèi)部根據(jù)技術(shù)棧分發(fā)到復(fù)雜的 RPC 樹(shù),并在完成其關(guān)鍵路徑前會(huì)涉及數(shù)十個(gè)服務(wù)。這可能包括查詢關(guān)鍵數(shù)據(jù)(例如 Pinterest 的圖片和收藏板)的服務(wù),推快遞相關(guān)圖片的推薦系統(tǒng)和垃圾內(nèi)容檢測(cè)系統(tǒng)。在這些服務(wù)中,只要其輸入數(shù)據(jù)可以被唯一鍵值表示,就可以將該離散的查詢單元的結(jié)果緩存在臨時(shí)存儲(chǔ)系統(tǒng)中,以便將來(lái)重用。
在 Pinterest,分布式緩存層的最常見(jiàn)用途是通過(guò)后備語(yǔ)義(lookaside semantics)來(lái)存儲(chǔ)這類中間計(jì)算的結(jié)果。這使得緩存層能吸收一大部分流量。如果沒(méi)有緩存層,這些流量會(huì)流向涉及復(fù)雜計(jì)算和昂貴存儲(chǔ)的服務(wù)和數(shù)據(jù)庫(kù)。憑借著毫秒級(jí)的尾延遲(tail latency),以及極低的單位請(qǐng)求基礎(chǔ)架構(gòu)成本,這個(gè)分布式緩存層提供了一個(gè)高性能低成本的后端擴(kuò)展機(jī)制,以滿足 Pinterest 不斷增長(zhǎng)的需求。
簡(jiǎn)化版的 Pinterest 的 API 請(qǐng)求生命周期:經(jīng)過(guò)主要 API 服務(wù),其依賴項(xiàng)后端以及分布式緩存層。
通過(guò)提供分布式緩存層即服務(wù),應(yīng)用開(kāi)發(fā)人員可以專注于實(shí)現(xiàn)業(yè)務(wù)邏輯,而不必?fù)?dān)心分布式數(shù)據(jù)的一致性、高可用性或者內(nèi)存容量。緩存層用戶使用通用的路由抽象層,以確保應(yīng)用程序具有容錯(cuò)性和一致的數(shù)據(jù)視圖。此外,緩存服務(wù)端集群可以獨(dú)立于應(yīng)用層橫向擴(kuò)展,從而透明地調(diào)整內(nèi)存或吞吐量,以適應(yīng)資源使用情況的變化。
2分布式緩存的骨干:Memcached 和 Mcrouter
Memcached 和 mcrouter 構(gòu)成了 Pinterest 分布式緩存基礎(chǔ)架構(gòu)的骨干,并且在 Pinterest 的存儲(chǔ)基礎(chǔ)架構(gòu)中起著至關(guān)重要的作用。Memcached 是由純 C 語(yǔ)言編寫(xiě)的開(kāi)源且高效的內(nèi)存鍵值存儲(chǔ)。Mcrouter 是應(yīng)用層的 Memcached 協(xié)議代理,位于 Memcached 集群的前面,并提供強(qiáng)大的高可用性和路由功能。
Memcached 是緩存解決方案中非常有吸引力的選擇:
得益于其異步事件驅(qū)動(dòng)的體系結(jié)構(gòu)和多線程處理模型,memcached 非常高效且易于進(jìn)行橫向擴(kuò)展以滿足容量需求。
Extstore 通過(guò)實(shí)例的 NVMe 閃存磁盤上的二級(jí)溫存儲(chǔ)(secondary warm storage)層,幫助實(shí)現(xiàn)了驚人的存儲(chǔ)效率。
Memcached 精心設(shè)計(jì)的簡(jiǎn)單體系結(jié)構(gòu)提供了在其之上構(gòu)建抽象層的靈活性,以及簡(jiǎn)單易行的水平可擴(kuò)展性以滿足日益增長(zhǎng)的需求。一個(gè) Memcached 進(jìn)程本身只是一個(gè)簡(jiǎn)單的鍵值存儲(chǔ),根據(jù)設(shè)計(jì),它對(duì)其它的 Memceched 進(jìn)程的存在毫無(wú)了解,甚至沒(méi)有 Memcached 集群的概念。
Memcached 在數(shù)十年的開(kāi)發(fā)過(guò)程中已經(jīng)經(jīng)過(guò)準(zhǔn)確性和性能的嚴(yán)格測(cè)試,并擁有非?;钴S的開(kāi)源社區(qū)(該社區(qū)還將多個(gè) Pinterest 提交的補(bǔ)丁合并至上游。)。
Memcached 自帶了對(duì) TLS 終止功能的原生支持,從而使我們能通過(guò) TLS 雙向身份驗(yàn)證的流量(該過(guò)程還額外包括內(nèi)部搭建的基于 SPIFFE 授權(quán)訪問(wèn)控制)來(lái)保護(hù)整個(gè)集群。
Mcrouter 在 2014 年由 Facebook 開(kāi)源,在擴(kuò)展其 Memcached 部署方面發(fā)揮了關(guān)鍵作用。Mcrouter 也非常適合 Pinterest 的架構(gòu),原因如下:
通過(guò)為應(yīng)用開(kāi)發(fā)人員提供與整個(gè)緩存集群進(jìn)行交互的單個(gè)終端節(jié)點(diǎn),Mcrouter 充當(dāng)了 Memcached 服務(wù)器集群的有效抽象。此外,將 mcrouter 用作整個(gè)系統(tǒng)的唯一接口可以確保 Pinterest 上所有服務(wù)和機(jī)器之間有通用及全局一致的流量行為。
Mcrouter 提供了解耦的控制平面和數(shù)據(jù)平面:Memcached 服務(wù)器集群的整個(gè)拓?fù)浣Y(jié)構(gòu)被劃分為多個(gè)“池”(邏輯集群),而管理客戶端和服務(wù)器池之間交互的請(qǐng)求路由策略和行為均被獨(dú)立管理。
Mcrouter 的配置 API 為復(fù)雜的路由提供了強(qiáng)大的基礎(chǔ),包括區(qū)域親和性路由,用于實(shí)現(xiàn)數(shù)據(jù)冗余的復(fù)制,多層緩存層和影子流量。
作為使用 memcached 的 ASCII 協(xié)議的應(yīng)用層代理,mcrouter 開(kāi)放了針對(duì)智能協(xié)議的功能,例如請(qǐng)求處理(TTL 修改、運(yùn)行中壓縮等)。
Mcrouter 原生地提供了豐富的可觀察性功能,并且對(duì)客戶端應(yīng)用來(lái)說(shuō)不需要任何成本。這為我們整個(gè)基礎(chǔ)架構(gòu)中的 Memcached 流量提供了詳細(xì)的可見(jiàn)性。對(duì)我們而言,其中最重要的指標(biāo)包括百分位請(qǐng)求延遲,按單個(gè)客戶端和服務(wù)器維度劃分的吞吐量,與鍵前綴和鍵模式有關(guān)的請(qǐng)求趨勢(shì)以及用于檢測(cè)服務(wù)器行為異常的錯(cuò)誤率。
從 mcrouter 到 Memcached 的請(qǐng)求路由總覽。每個(gè)鍵前綴都與一個(gè)路由策略相關(guān)聯(lián),圖中展示了兩個(gè)例子。
在實(shí)踐中,mcrouter 作為邊車代理(proxy sidecar)被部署在和服務(wù)同一機(jī)器的單獨(dú)進(jìn)程。如圖 2 所示,應(yīng)用程序(可以由任何語(yǔ)言編寫(xiě))在回快遞時(shí)將 Memcached 協(xié)議請(qǐng)求發(fā)快遞給 mcrouter,然后 mcrouter 作為代理將這些請(qǐng)求發(fā)國(guó)際快遞數(shù)千個(gè)上游 memcached 服務(wù)器。這種架構(gòu)能使我們?cè)谕耆泄艿木彺娣?wù)器集群中構(gòu)建強(qiáng)大功能的同時(shí),對(duì)客戶端服務(wù)保持完全透明。
盡管從 Pinterest 早期開(kāi)始,memcached 一直就是 Pinterest 基礎(chǔ)架構(gòu)的一部分,我們對(duì)其客戶端的拓展策略在這些年來(lái)也在不斷進(jìn)化。具體來(lái)說(shuō),路由和服務(wù)發(fā)現(xiàn)在最開(kāi)始是通過(guò)客戶端庫(kù)完成的(這其實(shí)很脆弱,而且它還與二進(jìn)制部署緊密耦合)。然后,該方法被內(nèi)部構(gòu)建的一個(gè)路由代理取代(該路由代理沒(méi)有提供用于高可用性的基礎(chǔ)功能),最終被 mcrouter 取代。
3計(jì)算和存儲(chǔ)效率
Memcached 的效率很高:?jiǎn)蝹€(gè) r5.2xlarge EC2 實(shí)例每秒能支持超過(guò) 10 萬(wàn)個(gè)請(qǐng)求和數(shù)以萬(wàn)計(jì)的并發(fā) TCP 連接,同時(shí)不會(huì)顯著地增加客戶端的延遲。這使 Memcached 成為 Pinterest 吞吐效率最高的生產(chǎn)服務(wù)。這部分歸功于編寫(xiě)良好的 C 語(yǔ)言代碼以及其體系結(jié)構(gòu)。該體系結(jié)構(gòu)利用了多個(gè)工作線程,每個(gè)工作線程獨(dú)立地運(yùn)行由”libevent“驅(qū)動(dòng)的事件循環(huán),來(lái)支持傳入的連接。
在 Pinterest,Memcached 的 extstore 在存儲(chǔ)效率方面取得了巨大的成功,具體的用例包括可視搜索以及個(gè)性化搜索推薦引擎。extstore 擴(kuò)展了緩存數(shù)據(jù)容量,在 DRAM 之外增加了掛載在本地的 NVMe 閃存盤,從而將每個(gè)實(shí)例的可用存儲(chǔ)容量從約 55 GB(r5.2xlarge)增加到將近 1.7 TB(i3.2xlarge),而實(shí)例成本只是略有增長(zhǎng)。
在實(shí)踐中,extstore 大大優(yōu)化了數(shù)據(jù)用量受限的用例,盡管 DRAM 和 SSD 響應(yīng)時(shí)間之間有幾個(gè)數(shù)量級(jí)的差異,extstore 卻沒(méi)有犧牲端到端延遲。extstore 的內(nèi)置調(diào)整工具使我們能找到一個(gè)平衡了磁盤 I/O、磁盤到內(nèi)存的重新緩存速率、壓縮頻率和壓縮程度以及客戶端尾部響應(yīng)時(shí)間的最佳平衡點(diǎn)。
4高可用性
Pinterest 的所有基礎(chǔ)架構(gòu)系統(tǒng)都是高可用的,我們的緩存系統(tǒng)也不例外。通過(guò)利用 mcrouter 提供的豐富的路由功能,我們的 memcached 集群有著一系列的容錯(cuò)功能:
針對(duì)部分失控或完全宕機(jī)的服務(wù)器的自動(dòng)故障轉(zhuǎn)移。網(wǎng)絡(luò)本身就是不可靠且有損耗的。我們整個(gè)緩存架構(gòu)假定這是不可改變的事實(shí),在服務(wù)器不可用或速度緩慢時(shí)也可以保持可用性。幸運(yùn)的是,緩存數(shù)據(jù)在本質(zhì)上是瞬態(tài)的,這放寬了對(duì)數(shù)據(jù)持久性的要求,而持久性存儲(chǔ)(例如數(shù)據(jù)庫(kù))對(duì)數(shù)據(jù)持久性的要求很高。在 Pinterest 中,mcrouter 會(huì)自動(dòng)地在請(qǐng)求響應(yīng)緩慢時(shí),或者某個(gè)服務(wù)器宕機(jī)時(shí)故障轉(zhuǎn)移到全局共享集群,并且 mcrouter 還會(huì)通過(guò)主動(dòng)的運(yùn)行狀況檢查將服務(wù)器加入服務(wù)池中。通過(guò)自動(dòng)故障轉(zhuǎn)移以及一系列的單個(gè)服務(wù)器故障的代理層檢測(cè),運(yùn)維人員可以在最短的生產(chǎn)停機(jī)時(shí)間內(nèi)識(shí)別并更換行為異常的服務(wù)器。
通過(guò)透明的跨區(qū)域復(fù)制實(shí)現(xiàn)數(shù)據(jù)冗余。我們的關(guān)鍵用例是跨不同的 AWS 可用區(qū)(AZ)進(jìn)行多集群復(fù)制的。這樣就可以在完全丟失可用區(qū)的情況下實(shí)現(xiàn)零停機(jī)時(shí)間:所有請(qǐng)求都將自動(dòng)重定向到位于另一個(gè)可用區(qū)中的運(yùn)行狀況良好的副本節(jié)點(diǎn)(replica),在該副本節(jié)點(diǎn)中有完整的數(shù)據(jù)冗余副本。
與實(shí)際生產(chǎn)流量隔離的影子測(cè)試。mcrouter 中的流量路由功能使我們可以進(jìn)行各種彈性測(cè)試,包括集群到集群的暗流量以及在實(shí)際生產(chǎn)請(qǐng)求中人為加入的延遲和停機(jī)時(shí)間的測(cè)試,而不會(huì)影響生產(chǎn)。
5負(fù)載均衡和數(shù)據(jù)分片
分布式系統(tǒng)的關(guān)鍵功能之一是水平可伸縮性,這是一種可以橫向擴(kuò)展而不是縱向擴(kuò)展以適應(yīng)額外的流量增長(zhǎng)的能力。在 Pinterest,我們絕大多數(shù)的緩存工作量都是受吞吐量限制的,這需要集群中實(shí)例的數(shù)量與請(qǐng)求的數(shù)量大致呈線性比例關(guān)系。然而,memcached 本身是一個(gè)非常簡(jiǎn)單的鍵值存儲(chǔ),它本身并不會(huì)知道集群中的其他節(jié)點(diǎn)。那么每秒數(shù)億個(gè)請(qǐng)求是如果通過(guò)網(wǎng)絡(luò)發(fā)國(guó)際快遞正確的服務(wù)器上的呢
Mcrouter 通過(guò)對(duì)每個(gè)請(qǐng)求的緩存鍵運(yùn)用哈希算法,來(lái)將請(qǐng)求確定性地發(fā)國(guó)際快遞池中的某一個(gè)主機(jī)。這對(duì)于在服務(wù)器之間平均分配流量非常有幫助,但是 memcached 有一個(gè)獨(dú)特的要求,即它的集群需要任意可伸縮性,也就是說(shuō)運(yùn)維人員要能夠自由地根據(jù)不斷變化的流量需求,來(lái)調(diào)整集群容量,同時(shí)最大程度地減少客戶端的影響。
一致性哈希確保了在合格分片的總數(shù)增加或減少時(shí),大多數(shù)鍵空間分區(qū)也可以映射到同一服務(wù)器。高度集中和可預(yù)測(cè)的命中率影響,允許系統(tǒng)在擴(kuò)展時(shí)對(duì)客戶端透明,從而防止容量的小范圍變化導(dǎo)致集群命中率出現(xiàn)災(zāi)難性下降。
一致性哈希算法保證了當(dāng)單一節(jié)點(diǎn)加入現(xiàn)有集群時(shí),大多數(shù)鍵值空間所分配的服務(wù)器不變
客戶端路由層將單個(gè)鍵值前綴映射到一個(gè)或多個(gè)這樣的一致哈希池,這些一致哈希池位于某個(gè)路由策略之后,包括跨可用區(qū)復(fù)制集群的可用區(qū)親和性偏好路由,針對(duì)位于基于閃存的容量集群后方的基于內(nèi)存集群的 L1L2 路由(具有穿透)等。這樣可以隔離流量,從而按客戶端的用例情況來(lái)分配容量,并且可以確保來(lái)自 Pinterest 集群中任何客戶端機(jī)器的一致緩存路由行為。
6優(yōu)劣權(quán)衡和我們的考慮
所有足夠復(fù)雜的基礎(chǔ)架構(gòu)系統(tǒng)都具有一個(gè)共同特點(diǎn):充滿了(往往非常細(xì)微的)優(yōu)劣權(quán)衡。在構(gòu)建和擴(kuò)展我們的緩存系統(tǒng)的過(guò)程中,我們權(quán)衡了許多方案的成本和收益。如下是最重要的幾點(diǎn):
中間代理層會(huì)產(chǎn)生大量的計(jì)算和 I/O 開(kāi)銷,特別是對(duì)于具有嚴(yán)格的延遲 SLO 并且注重性能的系統(tǒng)而言。但是,mcrouter 所提供的高可用性抽象,靈活的路由行為以及許多其他功能遠(yuǎn)遠(yuǎn)比性能損耗更重要。
全局共享的代理配置會(huì)給更改部署帶來(lái)風(fēng)險(xiǎn),因?yàn)樵诓渴饡r(shí),所有控制平面更改都會(huì)應(yīng)用到 Pinterest 的含有數(shù)萬(wàn)臺(tái)機(jī)器的整個(gè)集群中。然而,這也確保了全局一致的 memcached 集群拓?fù)浜团c之相關(guān)的路由策略,無(wú)論客戶端通過(guò)何種方式在 Pinterest 內(nèi)何處進(jìn)行部署。
我們管理維護(hù)著約一百個(gè)不同的 Memcached 集群,其中,許多集群具有不同的租戶(tenancy)特征(專用與共享)、硬件實(shí)例類型和路由策略。雖然這給團(tuán)隊(duì)帶來(lái)了相當(dāng)大的運(yùn)維負(fù)擔(dān),但它也允許每個(gè)用例達(dá)到有效的性能和可用性隔離,同時(shí)還能通過(guò)選擇最適合某個(gè)特定工作負(fù)載使用情況的參數(shù)和實(shí)例類型來(lái)達(dá)到效率優(yōu)化。
在大多數(shù)情況下,一致性哈希方案在上游服務(wù)器池之間進(jìn)行負(fù)載分配的效果很好,即使在鍵空間由類似前綴的鍵簇組成的情況下也是如此。但是,這不能解決熱鍵問(wèn)題——特定鍵集的請(qǐng)求量的異常增加仍然會(huì)產(chǎn)生因服務(wù)器集群中的熱分片所導(dǎo)致的負(fù)載不平衡的問(wèn)題。
7展望
展望未來(lái),我們希望繼續(xù)提高 Pinterest 緩存基礎(chǔ)架構(gòu)的效率、可靠性和性能。我們的努力包括當(dāng)前的一些實(shí)驗(yàn)性項(xiàng)目,例如將 memcached 核心直接嵌入到主機(jī)應(yīng)用程序進(jìn)程中,以處理性能關(guān)鍵的用例(這能使 memcached 與服務(wù)流程共享內(nèi)存空間,并消除網(wǎng)絡(luò)和 I/O 開(kāi)銷)。此外還有可靠性項(xiàng)目,例如設(shè)計(jì)一個(gè)穩(wěn)健的多區(qū)域冗余解決方案。
原文鏈接:
https://medium.com/pinterestengineering/scalingcacheinfrastructureatpinterest422d6d294ece
特別聲明:以上文章內(nèi)容僅代表作者本人觀點(diǎn),不代表ESG跨境電商觀點(diǎn)或立場(chǎng)。如有關(guān)于作品內(nèi)容、版權(quán)或其它問(wèn)題請(qǐng)于作品發(fā)表后的30日內(nèi)與ESG跨境電商聯(lián)系。
二維碼加載中...
使用微信掃一掃登錄
使用賬號(hào)密碼登錄
平臺(tái)顧問(wèn)
微信掃一掃
馬上聯(lián)系在線顧問(wèn)
小程序
ESG跨境小程序
手機(jī)入駐更便捷
返回頂部