您的位置:首頁>正文

雙11 萬億流量下的分散式緩存

本文主要從Tair發展和應用開始談起, 接著談及雙11面臨的挑戰, 重點分享了性能優化方面的實踐, 最後對緩存難題給出了解決方案。 內容如下。

分享嘉賓:

宗岱

宗岱:阿裡巴巴資深技術專家, 2008年加入淘寶, 阿裡分散式緩存、NoSQL資料庫Tair和Tengine負責人。

Tair概覽

Tair發展歷程

Tair在阿裡巴巴被廣泛使用, 無論是淘寶天貓流覽下單, 還是打開優酷流覽播放時, 背後都有Tair的身影默默支撐巨大的流量。 Tair的發展歷程如下:

2010.04 Tair v1.0正式推出@淘寶核心系統;

2012.06 Tair v2.0推出LDB持久化產品, 滿足持久化存儲需求;

2012.10 推出RDB緩存產品, 引入類Redis介面, 滿足複雜資料結構的存儲需求;

2013.03 在LDB的基礎上針對全量導入場景上線Fastdump產品, 大幅度降低導入時間和訪問延時;

2014.07 Tair v3.0 正式上線, 性能X倍提升;

2016.11 泰斗智能運維平臺上線, 助力2016雙11邁入千億時代;

2017.11 性能飛躍, 熱點散列, 資源調度, 支援萬億流量。

Tair是一個高性能、分散式、可擴展、高可靠的key/value結構存儲系統!Tair特性主要體現在以下幾個方面:

高性能:在高吞吐下保證低延遲, 是阿裡集團內調用量最大系統之一, 雙11達到每秒5億次峰值的調用量, 平均訪問延遲在1毫秒以下;

高可用:自動failover 單元化機房內以及機房間容災, 確保系統在任何情況下都能正常運行;

規模化:分佈全球各個資料中心, 阿裡集團各個BU都在使用;

業務覆蓋:電商、螞蟻、合一、阿裡媽媽、高德、阿裡健康等。

Tair除了普通Key/Value系統提供的功能, 比如get、put、delete以及批量介面外, 還有一些附加的實用功能, 使得其有更廣的適用場景。 Tair應用場景包括以下四種:

1.MDB 典型應用場景:用於緩存, 降低對後端資料庫的訪問壓力, 比如淘寶中的商品都是緩存在Tair中;用於臨時資料存儲, 部分資料丟失不會對業務產生較大影響;讀多寫少,

讀qps達到萬級別以上。

2.LDB 典型應用場景:通用kv存儲、交易快照、安全風控等;存儲黑白單數據, 讀qps很高;計數器功能, 更新非常頻繁, 且資料不可丟失。

3.RDB 典型應用場景:複雜的資料結構的緩存與存儲, 如播放清單, 直播間等。

4.FastDump 典型應用場景:週期性地將離線資料快速地導入到Tair集群中, 快速使用到新的資料, 對線上讀取要求非常高;讀取低延遲, 不能有毛刺。

雙 11 挑戰怎麼辦?

2012-2017年資料如圖, 可以看到, 2012年GMV小於200億, 2017年GMV達到1682億, 交易創建峰值從1.4萬達到32.5萬, 峰值QPS從1300萬達到近5億。 我們可以得出, Tair訪問峰值增速:Tair峰值 > 交易峰值 > 總GMV, 如何確保成本不超過交易峰值增速?對於帶資料的分散式系統來說, 緩存問題都是比較難解決的,

緩存流量特別大, 2017年雙11後, 我們徹底解決掉了緩存問題。 我們現在的交易系統和導入系統都是多地域多單元多機房部署的, 如何快速部署業務系統呢?

多地域多單元

多地域多單元首先是中心機房, 我們做了雙機房容災, 兩側還有若干個單元。 機房內系統圖如圖,

從流量接入進統一接入層-應用層-中介軟體-Tair-DB, 在資料層我們會做多地域的資料同步。

彈性建站

我們需要系統具備彈性建站的能力。 Tair是一個複雜的分散式存儲系統, 我們為之建立了一整套運營管控系統泰斗, 在泰斗裡建設彈性建站系統, 它會經過一系列工作步驟將Tair系統建設起來,我們還會從系統層面、集群層面和實例連通層面進行驗證,以確保系統功能、穩定性萬無一失。

Tair的每一個業務集群水位其實是不一樣的,雙11前的每一次全鏈路壓測下,由於業務模型的變化,所用Tair資源會發生變化,造成水位出現變化。在此情況下,我們需要每一次壓測完在多個集群間調度Tair資源,如果水位低,就會把某些機器伺服器資源往水位高挪,達到所有集群水位值接近。

資料同步

對於單元化業務,我們提供了本單元訪問本地Tair的能力,對於有些非單元化業務,我們也提供了更靈活的訪問模型。同步延遲是我們一直在做的事情,2017年雙11每秒同步資料已經達到了千萬級別,那麼,如何更好地解決非單元化業務在多單元寫入資料衝突問題?這也是我們一直考慮的。

性能優化降成本

伺服器成本並不是隨著訪問量線性增長,每年以百分之三四十成本在下降,我們主要通過伺服器性能優化、用戶端性能優化和不同的業務解決方案三方面達到此目的。

記憶體資料結構

圖為MDB記憶體資料結構示意圖,我們在進程啟動之後會申請一大塊記憶體,在記憶體中將格式組織起來。主要有slab分配器、hashmap和記憶體池,記憶體寫滿後會經過LRU鏈進行資料淘汰。隨著伺服器CPU核數不斷增加,如果不能很好處理鎖競爭,很難提升整體性能。

參考了各種文獻和作業系統的設計,我們使用了細細微性鎖、無鎖資料結構、CPU本地資料結構和讀拷貝更新(讀鏈表時不需要加鎖)。左圖為未經過優化時鎖競爭各個功能模組消耗圖,可以看到網路部分和資料查找部分消耗最多,優化後(右圖)有80%的處理都是在網路和資料查找,這是符合我們期望的。

使用者態協定棧

鎖優化後,我們發現很多CPU消耗在內核態上,這時我們採用DPDK+Alisocket來替換掉原有內核態協議棧,Alisocket採用DPDK在使用者態進行網卡收包,並利用自身協議棧提供socket API,對其進行集成。我們與業內類似系統進行了對比,如圖。

記憶體合併

單機性能提升足夠高後,帶來問題是單位qps對應記憶體量變少了,怎麼解決呢?我們發現公用集群整體看記憶體還是有的,某些slab沒有辦法寫入, 比如64位元組slab沒有被寫滿,但是72位元組slab全部寫滿了,記憶體池都被申請完了,我們把64位元組slab空閒頁相互合併,這樣可以釋放大量空閒頁。其中不可避免加入模式鎖,在觸發合併閾值情況下,切換成加鎖狀態,合併都是在訪問量低峰期做的,對於業務峰值來說沒有問題。

用戶端優化

用戶端我們做了兩方面優化:網路框架替換,適配協程,從原有的mina替換成netty,輸送量提升40%;序列化優化,集成 kryo和hessian,輸送量提升16%+。

記憶體網格

如何與業務結合來降低整體Tair與業務成本?Tair提供了多級存儲一體化解決業務問題,比如安全風控場景,讀寫量超大、有大量本地計算,我們可以在業務機器本地存下該業務機器所要訪問的資料,大量讀會命中在本地,而且寫在一段時間內是可合併的,在一定週期後,合併寫到遠端Tair集群上作為最終存儲。我們提供讀寫穿透,包括合併寫和原有Tair本身具有多單元複製的能力,雙11時業務對Tair讀取降至27.68%,對Tair寫入降至55.75%。

熱點難題已解決

緩存擊穿

緩存從開始的單點發展到分散式系統,通過資料分片方式組織,但對每一個資料分片來說,還是作為單點存在的。當有大促活動或熱點新聞時,資料往往是在某一個分片上的,這就會造成單點訪問,進而緩存中某個節點就會無法承受這麼大壓力,致使大量請求沒有辦法回應。即便是限流也是有損操作,可能也會造成全系統崩潰。我們發現,問題根源是訪問熱點,需要徹底解決該問題。

熱點散列

經過多種方案的探索,採用了熱點散列方案。我們評估過用戶端本地cache方案和二級緩存方案,它們可以在一定程度上解決熱點問題,但各有弊端。而熱點散列直接在資料節點上加hotzone區域,讓hotzone承擔熱點資料存儲。對於整個方案來說,最關鍵有以下幾步:

智慧識別。熱點資料總是在變化的,或是頻率熱點,或是流量熱點。

即時回饋。採用多級LRU的資料結構,設定不同權值放到不同層級的LRU上,一旦LRU資料寫滿後,會從低級LRU鏈開始淘汰,確保權值高的得到保留。

動態散列。當訪問到熱點時,Appserver和服務端就會聯動起來,根據預先設定好的訪問模型動態散列到其它資料節點hotzone上去訪問,集群中所有節點都會承擔這個功能。

通過這種方式,我們將原來單點訪問承擔的流量通過集群中部分機器來承擔。

可以看到,雙11零點的刹那,我們吸收了800多萬次的熱點訪問。如果沒有做熱點散列,散列前的指數都會超過死亡水位線。

寫熱點

寫熱點與讀熱點有類似的地方,也需要把熱點即時識別出來,然後通過IO執行緒把有熱點key的請求放給合併執行緒去處理,會有定時處理執行緒提交給存儲層。

經過雙11考驗對讀寫熱點的處理,我們現在可以放心的說,我們將緩存包括kv存儲部分的讀寫熱點徹底解決了。

它會經過一系列工作步驟將Tair系統建設起來,我們還會從系統層面、集群層面和實例連通層面進行驗證,以確保系統功能、穩定性萬無一失。

Tair的每一個業務集群水位其實是不一樣的,雙11前的每一次全鏈路壓測下,由於業務模型的變化,所用Tair資源會發生變化,造成水位出現變化。在此情況下,我們需要每一次壓測完在多個集群間調度Tair資源,如果水位低,就會把某些機器伺服器資源往水位高挪,達到所有集群水位值接近。

資料同步

對於單元化業務,我們提供了本單元訪問本地Tair的能力,對於有些非單元化業務,我們也提供了更靈活的訪問模型。同步延遲是我們一直在做的事情,2017年雙11每秒同步資料已經達到了千萬級別,那麼,如何更好地解決非單元化業務在多單元寫入資料衝突問題?這也是我們一直考慮的。

性能優化降成本

伺服器成本並不是隨著訪問量線性增長,每年以百分之三四十成本在下降,我們主要通過伺服器性能優化、用戶端性能優化和不同的業務解決方案三方面達到此目的。

記憶體資料結構

圖為MDB記憶體資料結構示意圖,我們在進程啟動之後會申請一大塊記憶體,在記憶體中將格式組織起來。主要有slab分配器、hashmap和記憶體池,記憶體寫滿後會經過LRU鏈進行資料淘汰。隨著伺服器CPU核數不斷增加,如果不能很好處理鎖競爭,很難提升整體性能。

參考了各種文獻和作業系統的設計,我們使用了細細微性鎖、無鎖資料結構、CPU本地資料結構和讀拷貝更新(讀鏈表時不需要加鎖)。左圖為未經過優化時鎖競爭各個功能模組消耗圖,可以看到網路部分和資料查找部分消耗最多,優化後(右圖)有80%的處理都是在網路和資料查找,這是符合我們期望的。

使用者態協定棧

鎖優化後,我們發現很多CPU消耗在內核態上,這時我們採用DPDK+Alisocket來替換掉原有內核態協議棧,Alisocket採用DPDK在使用者態進行網卡收包,並利用自身協議棧提供socket API,對其進行集成。我們與業內類似系統進行了對比,如圖。

記憶體合併

單機性能提升足夠高後,帶來問題是單位qps對應記憶體量變少了,怎麼解決呢?我們發現公用集群整體看記憶體還是有的,某些slab沒有辦法寫入, 比如64位元組slab沒有被寫滿,但是72位元組slab全部寫滿了,記憶體池都被申請完了,我們把64位元組slab空閒頁相互合併,這樣可以釋放大量空閒頁。其中不可避免加入模式鎖,在觸發合併閾值情況下,切換成加鎖狀態,合併都是在訪問量低峰期做的,對於業務峰值來說沒有問題。

用戶端優化

用戶端我們做了兩方面優化:網路框架替換,適配協程,從原有的mina替換成netty,輸送量提升40%;序列化優化,集成 kryo和hessian,輸送量提升16%+。

記憶體網格

如何與業務結合來降低整體Tair與業務成本?Tair提供了多級存儲一體化解決業務問題,比如安全風控場景,讀寫量超大、有大量本地計算,我們可以在業務機器本地存下該業務機器所要訪問的資料,大量讀會命中在本地,而且寫在一段時間內是可合併的,在一定週期後,合併寫到遠端Tair集群上作為最終存儲。我們提供讀寫穿透,包括合併寫和原有Tair本身具有多單元複製的能力,雙11時業務對Tair讀取降至27.68%,對Tair寫入降至55.75%。

熱點難題已解決

緩存擊穿

緩存從開始的單點發展到分散式系統,通過資料分片方式組織,但對每一個資料分片來說,還是作為單點存在的。當有大促活動或熱點新聞時,資料往往是在某一個分片上的,這就會造成單點訪問,進而緩存中某個節點就會無法承受這麼大壓力,致使大量請求沒有辦法回應。即便是限流也是有損操作,可能也會造成全系統崩潰。我們發現,問題根源是訪問熱點,需要徹底解決該問題。

熱點散列

經過多種方案的探索,採用了熱點散列方案。我們評估過用戶端本地cache方案和二級緩存方案,它們可以在一定程度上解決熱點問題,但各有弊端。而熱點散列直接在資料節點上加hotzone區域,讓hotzone承擔熱點資料存儲。對於整個方案來說,最關鍵有以下幾步:

智慧識別。熱點資料總是在變化的,或是頻率熱點,或是流量熱點。

即時回饋。採用多級LRU的資料結構,設定不同權值放到不同層級的LRU上,一旦LRU資料寫滿後,會從低級LRU鏈開始淘汰,確保權值高的得到保留。

動態散列。當訪問到熱點時,Appserver和服務端就會聯動起來,根據預先設定好的訪問模型動態散列到其它資料節點hotzone上去訪問,集群中所有節點都會承擔這個功能。

通過這種方式,我們將原來單點訪問承擔的流量通過集群中部分機器來承擔。

可以看到,雙11零點的刹那,我們吸收了800多萬次的熱點訪問。如果沒有做熱點散列,散列前的指數都會超過死亡水位線。

寫熱點

寫熱點與讀熱點有類似的地方,也需要把熱點即時識別出來,然後通過IO執行緒把有熱點key的請求放給合併執行緒去處理,會有定時處理執行緒提交給存儲層。

經過雙11考驗對讀寫熱點的處理,我們現在可以放心的說,我們將緩存包括kv存儲部分的讀寫熱點徹底解決了。

同類文章
Next Article
喜欢就按个赞吧!!!
点击关闭提示