天天看點

不懂排序優化,怎麼敢說自己會玩分布式資料庫?

作者:dbaplus社群

一、背景

1、分布式資料庫架構

目前分布式資料庫架構有不少,但是總體架構相差不大,主要元件都包含協調節點、資料分片、中繼資料節點、全局時鐘。一種常見的分布式架構如下圖:

不懂排序優化,怎麼敢說自己會玩分布式資料庫?
  • gtm:全局事務管理器(全局時鐘),一主多備;
  • catalog:中繼資料管理,一主多備;
  • group:水準分片,每個group由一主多備資料存儲節點組成;
  • proxy:協調節點,無狀态,負責處理用戶端的請求,把請求按照分片規則發送到資料分片,彙總資料分片傳回的資料,協同其它元件保證分布式事務的一緻性。

2、排序問題

分布式資料庫中排序也是一種重要的功能。一條查詢排序語句select *from t1 order by field1,需要查詢的資料可能會分布在不同的資料分片中。這就需要proxy對為不同資料分片傳回的有序資料進行重排序,然後給client傳回全局有序的資料。

當相關的資料量不大時,proxy可把不同資料分片傳回的資料儲存在記憶體中,然後對記憶體中的資料重排序後傳回給client。當相關的資料量比較大時,如果把待重排序資料放到記憶體中則可能會導緻OOM,如果把待重排序資料暫存在proxy的磁盤中,則也有耗盡磁盤的風險并且會存在大量的磁盤IO。下面将介紹一種分布式資料庫排序及優化方法。

二、解決方案

1、排序方案介紹

為了提高分布式排序的性能,每個資料分片本身也要參與排序。這樣在proxy上得到分片傳回的資料是有序的,proxy對有序的資料重排序可以采用歸并排序或者優先級隊列排序方法,大大減輕proxy的壓力。

可以根據proxy記憶體大小配置sort buffer大小,通常預設為10M。如果一次查詢語句關聯N個資料分片,則需要到sort buffer按照N份進行切分,每個資料分片對應切分後的sort buffer大小為10M/N。

直接在記憶體中進行,具體步驟如下圖:

不懂排序優化,怎麼敢說自己會玩分布式資料庫?
  • client向proxy下發排序查詢語句 select *from t1 order by id。
  • proxy根據分片鍵以及分片規則向相關的資料分片group1、group2下發排序查詢語句select *from t1 order by id。
  • 資料分片在本地對資料進行查詢排序後,發送有序資料到proxy。
  • proxy把資料分片傳回的有序資料存儲在資料分片對應的sort buffer中,并對有序資料進行歸并排序。
  • proxy把歸并排序好的資料發送給client。

2、排序方案缺陷

這種方法隻能滿足小資料量排序,當排序的資料量較大時我們可以選擇調大proxy上的sort buffer。但是調大sort buffer會占用更多的記憶體資源,是以不能無限制地調大sort buffer。

3、排序優化思路

把資料分片傳回的有序資料儲存到磁盤上,然後對磁盤資料進行重排序。下面将介紹一種優化方案,針對大資料量進行分布式排序的方法。

三、優化方案

1、排序方案介紹

由于記憶體的限制,在記憶體中對大資料量資料進行歸并排序方案不可行,針對這種情況需要把資料分片傳回的資料暫存在磁盤中。具體優化方案步驟如下圖:

不懂排序優化,怎麼敢說自己會玩分布式資料庫?

1)client向proxy下發排序查詢語句 select *from t1 order by id。

2)proxy根據分片鍵向相關的資料分片group1、group2下發排序查詢語句select *from t1 order by id。

3)資料分片在本地對資料進行查詢排序後,發送有序資料到proxy。

4)proxy把資料分片傳回的有序資料存儲在資料分片對應的磁盤檔案中。

5)使用優先級隊列排序方法進行重排序:

  • 每個資料分片出一條資料建構堆,heap包含的節點個數等于資料分片的個數。
  • 為了避免優先級隊列排序過程中從磁盤中逐條讀取資料造成的性能問題,proxy從磁盤檔案中讀取資料預填充到資料分片對應的sort buffer。
  • 每個分片的sort buffer出一條資料構造成一個heap。
  • 從堆頂彈出資料發送給client。
  • 堆頂資料彈出後,從已彈出節點對應的sort buffer再讀取一條資料push到堆。
  • 分片sort buffer中的資料取完後,需要繼續從對應的磁盤檔案中拉取資料,對sort buffer進行填充。
  • 直至取完所有資料發送到client。

2、排序方案缺陷

  • proxy需要收集完所有相關資料分片的有序資料存入磁盤可以解決記憶體不夠的問題,但是磁盤也是有限的,當資料量太大在proxy上磁盤也可能無法容納需要排序的資料。
  • proxy上把資料存在磁盤,存在大量的磁盤IO。
  • 以select * from t1 order by field1 limit 100w為例:如果本次查詢的資料在50個資料分片上,則proxy節點需要從每個資料分片上拉取100w資料然後儲存到磁盤上。這樣需要儲存5000W資料(100w*50),而client隻需要100w條資料,浪費了很多網絡帶寬和磁盤IO。

3、排序優化思路

這種方法是proxy把相關資料分片的有序資料全部拉取到proxy上,然後再進行排序。我們是否分批從資料分片拉取資料,批量資料處理後再從資料分片拉取下一批資料呢?下面将介紹一種分批排序的方法。

四、最終方案

1、排序方案介紹

proxy上磁盤上不儲存資料分片資料,一次從資料分片拉取固定大小的有序資料,proxy把拉取的資料填充到分片對應的sort buffer,sort buffer中資料使用完後再次從對應的資料分片上拉取。具體步驟如下圖:

不懂排序優化,怎麼敢說自己會玩分布式資料庫?

1)client向proxy下發排序查詢語句 select *from t1 order by id。

2)proxy根據分片鍵向相關的資料分片group1、group2下發排序查詢語句select *from t1 order by id。

3)資料分片在本地對資料進行查詢排序後,發送固定大小有序資料到proxy。

4)proxy把資料分片傳回的有序資料存儲在資料分片對應的sort buffer中。

5)優先級隊列排序。

  • 每個資料分片對應的sort buffer出一條資料建構堆,堆節點的個數等于資料分片的個數
  • 從堆頂彈出資料發送給client
  • 堆頂資料彈出後,從已彈出節點對應的sort buffer再讀取一條資料push到堆
  • 分片sort buffer中的資料取完後,需要繼續從對應的資料分片節點中拉取資料,對sort buffer進行填充
  • 直至取完所有資料發送到client

2、排序方案分析

針對優化方案3.2存在的三個缺陷的解決情況。

1)缺陷1:proxy需要收集完所有相關資料分片的有序資料存入磁盤解決記憶體不夠的問題,但是磁盤也是有限的,當資料量太大在proxy上磁盤也可能無法容納需要排序的資料。

解決情況:從圖中可以看出proxy的磁盤上不儲存資料分片的資料。

2)缺陷2 :proxy上把資料存在磁盤,存在大量的磁盤IO。

解決情況:proxy的磁盤上不儲存資料分片的資料,是以不存在磁盤壓力太大問題。

3)缺陷3:select * from t1 order by field1 limit 100w為例:如果本次查詢的資料在50個資料分片上,則proxy節點需要從每個資料分片上拉取100w資料然後儲存到磁盤上,需要儲存5000W資料(100w*50),而client隻需要100w條資料,浪費了很多網絡帶寬和磁盤IO。

解決情況:每次從資料分片拉取固定大小的資料,邊排序邊給用戶端傳回資料,當給用戶端傳回的資料達到100W時則完成本次查詢,網絡帶寬浪費得到大大改善。

假設proxy上資料分片對應的sort buffer大小為2M,從資料分片拉取的資料量:

  • 最壞情況:拉取的資料量為 2M*50+100W,并且不需要儲存磁盤。
  • 最好情況:資料分布很均勻,給client傳回100w資料後,所有sort buffer分片對應的資料正好基本取空(都剩下一條),此時拉取的資料量為 100W+50。

3、方案使用限制

1)資料分片節點本身支援排序,絕大多數資料分片都是支援排序的。

2)資料分片需要支援分批讀取。

以MySQL作為資料分片為例,則需要proxy上可以使用流式查詢或者遊标查詢。另外有些分布式資料庫在設計時就考慮到一些分布式的問題,它們資料分片節點在查詢結束前一直保留上下文,它們的分批讀取性能更高,這裡就不再舉例。

>>>>

參考資料

  • JDBC操作MySQL(3)—查詢
  • https://www.jianshu.com/p/c7c5dbe63019
  • MySQL JDBC StreamResult通信原理淺析
  • https://blog.csdn.net/xieyuooo/article/details/83109971/

作者丨vivo網際網路伺服器團隊-Xia Qianyong

來源丨公衆号:vivo網際網路技術(ID:vivoVMIC)

dbaplus社群歡迎廣大技術人員投稿,投稿郵箱:[email protected]

活動推薦

第八屆DAMS-中國資料智能管理峰會将于2023年3月31日在上海舉辦,與大家一起探索大資料與雲原生強強聯合的方式、挖掘由此激發的軟體發展和技術進步。

報名連結:

https://www.bagevent.com/event/8100960?bag_track=TT

演講嘉賓所在機關:阿裡、騰訊、京東、美團、華為雲、位元組、螞蟻、網易、新浪、攜程、哔哩哔哩、小紅書、vivo、快狗打車、貨拉拉、工商銀行、建設銀行、中國銀行、平安銀行、光大銀行、彙豐銀行、微衆銀行、複旦大學等産學研界技術領跑機關。

演講議題聚焦:

  • 大資料&資料資産管理:資料治理丨存算分離丨雲原生OLAP丨湖倉一體丨智能分析
  • 資料庫:雲原生分布式丨時間序列丨服務自治丨中間件丨跨雲多活
  • 運維:AIOps丨故障分析丨性能優化丨離線上混部丨高可用建設
  • 金融科技:規模化監控丨實時數倉丨分布式改造丨國産化替代丨數字化轉型丨混沌工程
不懂排序優化,怎麼敢說自己會玩分布式資料庫?

繼續閱讀