阿里妹導讀:阿里云智能數據庫Tair團隊主要負責自研分布式鍵值存儲(KVS)系統,幾乎涵蓋了淘寶、天貓、阿里媽媽、菜鳥、釘釘、優酷、高德等阿里巴巴所有核心業務。十多年來,始終如一為阿里業務提供著高可靠、高性能、低成本的數據存儲與訪問服務。
作者:民泰
01概述
近日,Tair團隊的一篇論文——HotRing:AHotspot-AwareIn-MemoryKey-ValueStore被FAST'20ResearchTrack接收(USENIXConferenceonFileandStorageTechniques(FAST),CCFA類會議,存儲領域頂會,2020年接受率16%)。
HotRing是Tair團隊的創新性純內存KV存儲引擎設計。其引擎吞吐性能可達600Mops/s,與目前很快的KVS系統相比,可實現2.58倍的性能提升。HotRing很重要的創新點是:極大的提升了KVS引擎對于熱點訪問的承載能力。這對于KVS系統的穩定性以及成本控制尤為 關鍵。
為了方便大家更通俗全面的理解這篇論文,本文將從阿里巴巴的雙十一零點峰值講起,介紹峰值下數據庫整體架構所面臨的熱點問題,再介紹Tair團隊在解決熱點方面一次次的優化提升,很后介紹Tair的創新性引擎HotRing。
02背景
2021年天貓雙11再次刷新世界紀錄,零點的訂單峰值達到54.4萬筆/秒。有訂單就涉及到交易,有交易就需要數據庫的事務保證,因此阿里巴巴數據庫將在這時面臨巨大的沖擊。
現實往往更加嚴重,在業務方面,一次訂單隨著業務邏輯在后端會放大為數十次的訪問;在客戶方面,大量的客戶只是瘋狂的訪問,并沒有生成訂單。因此,在雙11的零點峰值,業務實際的訪問量級是10億次/秒。
Tair作為高并發分布式的KVS系統,在這時發揮了重要作用。如下面的邏輯圖所示,Tair作為數據庫的分布式緩存系統,緩存了大量的熱點數據(例如商品,庫存,風控信息等),為數據庫反抗了巨大的訪問量。2021年雙11,Tair的峰值訪問為9.92億次/秒。
在業務層面,熱點問題很好理解,很典型的就是雙十一零點秒殺。這會導致數據訪問呈現嚴重傾斜的冪律分布。
我們分析了多種業務的數據訪問分布,如下圖所示,大量的數據訪問只集中在少部分的熱點數據中,若用離散冪率分布(Zipfian)刻畫,其θ參數約為1.22。相似地,Facebook的一篇論文同樣也展示了近似的數據訪問分布(參考論文[3])。
直觀上可以用下圖來解釋。以蘋果新手機發售舉例。手機的庫存等信息只存在KVS的一個節點中。當新手機發售后,大量的果粉瘋狂進行搶購下單,業務的訪問量基本都聚集在這一個節點上。節點可能無法承載大量的熱點訪問,進而引發系統崩潰,嚴重影響用戶體驗。
為了保證雙十一絲般順滑的購物體驗,Tair針對熱點問題進行了多層優化:
客戶端緩存:通過預先標記熱點,設置客戶端層面的緩存。以上圖來理解,就是將訪問在業務層面返回,直接減小了KVS系統的負載壓力。
熱點散列技術:通過將熱點數據備份到多個KVS節點上,分攤熱點訪問。以少量成本的資源與系統開銷,換取了成倍的系統承載力。
RCU無鎖引擎:通過采用Read-Copy-Update的方式,實現內存KV引擎的無鎖化(lock-free)訪問(參考論文[1,2])。成倍提升KVS引擎的性能,進而提高熱點的承載力。
HotRing:在RCU無鎖引擎基礎上,我們進行索引結構的熱點感知設計,提出了一種名為HotRing的新型熱點感知內存KVS。HotRing可動態識別熱點,并實時的進行索引結構的無鎖調整,對于冪律分布場景實現成倍的引擎性能提升。
經過十年的技術沉淀,我們已將集團Tair數據庫的緩存技術釋放到云上,普惠大眾,即“阿里云Redis企業版”。
03HotRing
現有的內存KVS引擎通常采用鏈式哈希作為索引,結構如下圖所示。首先,根據數據的鍵值(k)計算其哈希值h(k),對應到哈希表(Hashtable)的某個頭指針(Headi)。根據頭指針遍歷相應的沖突鏈(CollisionChain)的所有數據(Item),通過鍵值比較,找到目標數據。假如目標數據不在沖突鏈中(readmiss),則可在沖突鏈頭部插入該數據。
在鏈式哈希索引結構中,訪問位于沖突鏈尾部的數據,需要經過更多的索引跳數,即更多次的內存訪問。很直觀的想法是,假如可以將熱點數據放置在沖突鏈頭部,那么系統對于熱點數據的訪問將會有更快的響應速度。
但是,數據在沖突鏈中的位置由數據的插入順序決定,這和數據的冷熱程度是互相獨立的。因此,如圖所示,熱點數據(HotItem)在沖突鏈中的位置是完全均勻分布。
理想的設計也很直觀,就是將所有熱點數據移動到沖突鏈的頭部。但有兩方面因素使得這個問題非常難解。一方面,數據的熱度是動態變化的,必須實現動態的熱點感知保證熱點時效性。另一方面,內存KVS的引擎性能是很敏感的(一次訪問的時延通常是100ns量級),必須實現無鎖的熱點感知維持引擎的高并發與高吞吐特性。
HotRing在傳統鏈式哈希索引基礎上,實現了有序環式哈希索引設計。如下圖所示,將沖突鏈首尾連接形式沖突環,保證頭指針指向任何一個item都可以遍歷環上所有數據。然后,HotRing通過lock-free移動頭指針,動態指向熱度較高的item(或根據算法計算出的很優item位置),使得訪問熱點數據可以更快的返回。
下面通過如下4方面進行介紹:
設計1:為什么要實現為有序環?
設計2:如何動態識別熱點并調整頭指針?
設計3:如何保證無鎖的并發訪問?
設計4:如何根據熱點數據量的動態變化進行無鎖rehash?
實現環式哈希索引后,第一個問題是要保證查詢的正確性。若為無序環,當一個readmiss操作遍歷沖突環時,它需要一個標志來判定遍歷何時終止,否則會形式死循環。但是在環上,所有數據都會動態變化(更新或刪除),頭指針同樣也會動態移動,沒有標志可以作為遍歷的終止判定。
利用key排序可以解決這個問題,若目標key介于連續兩個item的key之間,說明為readmiss操作,即可終止返回。由于實際系統中,數據key的大小通常為10~100B,比較會帶來巨大的開銷。哈希結構利用tag來減少key的比較開銷。
如下圖所示,tag是哈希值的一部分,每個key計算的哈希值,前k位用來哈希表的定位,后n-k位作為沖突鏈中進一步區分key的標志。為了減小排序開銷,我們構建字典序:order=(tag,key)。先根據tag進行排序,tag相同再根據key進行排序。
下圖比較了HotRing與傳統鏈式哈希。以itemB舉例,鏈式哈希需要遍歷所有數據才能返回readmiss。而HotRing在訪問itemA與C后,即可確認Breadmiss。因此針對readmiss操作,鏈式哈希需要遍歷整個沖突鏈;而HotRing利用字典序,不僅可以正確終止,且平均只需遍歷1/2沖突環。
HotRing實現了兩種策略來實現周期性的熱點識別與調整。每R次訪問為一個周期(R通常設置為5),第R次訪問的線程將進行頭指針的調整。兩種策略如下:
隨機移動策略:每R次訪問,移動頭指針指向第R次訪問的item。若已經指向該item,則頭指針不移動。該策略的優勢是,不需要額外的元數據開銷,且不需要采樣過程,響應速度極快。
采樣分析策略:每R次訪問,嘗試啟動對應沖突環的采樣,統計item的訪問頻率。若第R次訪問的item已經是頭指針指向的item,則不啟動采樣。
采樣所需的元數據結構如下圖所示,分別在頭指針處設置TotalCounter,記錄該環的訪問總次數,每個item設置Counter記錄該item的訪問次數。因為內存指針需要分配64bits,但實際系統地址索引只使用其中的48bits。我們使用剩余16bits設置標志位(例如TotalCounter、Counter等),保證不會增加額外的元數據開銷。該策略的優勢是,通過采樣分析,可以計算選出很優的頭指針位置,穩態時性能表現更優。
這一部分的細節設計有很多:
采樣分析策略如何選出很優位置;
針對RCU更新操作的采樣優化,
熱點繼續防止冷啟動。
本文不再具體描述,有愛好請參考HotRing論文。
Tair的RCU無鎖引擎是HotRing的設計基礎。參考論文[1,2]對如何實現無鎖鏈表進行了具體講解,后續的所有無鎖設計基本都沿用了他們的策略。有愛好可以讀一下。這里我們舉一個典型的并發示例進行介紹。
如下圖所示,在鏈A->B->D上,線程1進行插入C的操作,同時線程2進行RCU更新B的操作,嘗試更新為B'。線程1修改B的指針指向C,完成插入。而線程2修改A的指針指向B'完成更新。兩個線程并發修改不同的內存,均可成功返回。但是這時遍歷整條鏈(A->B'->D),將發現C無法被遍歷到,導致正確性問題。
解決措施是利用上圖(ItemFormat)中的Occupied標志位。當線程2更新B時,首先需要將B的Occupied標志位置位。線程1插入C需要修改B的指針(NextItemAddress),若發現Occupied標志位已置位,則需要重新遍歷鏈表,嘗試插入。通過使并發操作競爭修改同一內存地址,保證并發操作的正確性。
利用相同原理,我們保證了頭指針移動操作,與CRUD操作的并發正確性。因此實現了HotRing的無鎖并發訪問。
如背景所述,對于極端的冪率分布場景,大量的數據訪問只集中在少部分的熱點數據中。因此只要保證熱點數據可以位于頭指針位置,沖突環即使很長,對于引擎的性能表現并不影響。引擎性能的降低,必然是因為沖突環上存在多個熱點。因此HotRing設計了適應熱點數據量的無鎖rehash策略來解決這一問題。
HotRing利用訪問所需平均內存訪問次數(accessoverhead)來替代傳統rehash策略的負載因子(loadfactor)。在冪率分布場景,若每個沖突環只有一個熱點,HotRing可以保證accessoverhead
在本論文中,我們進行索引結構的熱點感知設計,提出了一種名為HotRing的新型熱點感知內存KVS,針對冪率分布的熱點場景進行大量優化。HotRing可動態識別熱點,并實時的進行索引結構的無鎖調整,進而提供高并發高性能的無鎖化訪問。

與傳統的內存KVS索引相比,HotRing采用輕量級的熱點識別策略,且沒有增加元數據存儲開銷。但在冪律分布的應用場景中,HotRing的引擎吞吐性能可達600Mops/s,與目前很快KVS相比,可實現2.58倍的性能提升。
文章地址:http://www.meyanliao.com/article/online/12530.html