PolarDB-X 私有協議:提升集羣的性能和穩定性

作者:辰宇

私有協議是什麼?

PolarDB-X作爲阿里巴巴自主研發的雲原生分佈式數據庫,通過將數據拆分到多個基於MySQL發展而來的存儲節點DN,每個存儲節點DN承擔合適的併發、數據存儲和計算負載,計算節點處理分佈式邏輯,最終得到一個具有穩定可靠、高度擴展性的分佈式關係型數據庫系統。計算節點和存儲節點之間的通信協議,即集羣內部通信協議,是系統的重要組成部分。

PolarDB-X的前身爲TDDL中間件,通過在應用端上採用 Sharding 技術,應對高速增長的數據量,由於後端統一爲 MySQL,中間的通信協議爲傳統 MySQL 的查詢協議。1.0時代的 DRDS+RDS 的組合也延續了之前中間件的技術路線,同樣採用 MySQL 的 SQL 查詢協議作爲計算節點和存儲節點的數據傳輸協議。

雖然 SQL 表示查詢具有簡潔易讀,不用關心後端存儲的物理實現等優點,但對於進入2.0時代(雲原生分佈式數據庫)的PolarDB-X來說,計算節點和存儲節點存在更多的數據交互,存儲節點也不僅僅承擔存儲和處理普通SQL查詢的功能,這時傳統的SQL查詢協議便顯得力不從心了。

傳統的SQL協議基於一問一答的阻塞式模型,是針對C/S模式的應用而設計的,沒有考慮兩個節點間承載大量會話的需要。而目前常見的分佈式系統,特別是分佈式數據庫,爲了保證事務性,節點間需要維持多條處於不同事物的會話。因此分佈式數據庫在集羣內部往往都會實現一套自己的通信協議,通常都會選擇RPC方式實現。例如OceanBase基於 Libeasy 庫,實現了ObRPC,實現了集羣內異步化通信。TiDB則直接使用了gRPC作爲和TiKV的通信協議。爲了充分發揮PolarDB-X底層存儲的高級特性,同時解決傳統SQL協議作爲內部通信協議的侷限性,私有協議應運而生。基於私有協議的加持,可以繞過傳統的MySQL Server層的解析和優化開銷,直接和底下的InnoDB/X-Engine存儲引擎進行高效交互,同時擴展並支持了全局時鐘協議交互、Plan計算下推等能力,這也使得PolarDB-X逐步脫離原有中間件的範疇,演變爲雲原生的分佈式數據庫。

PolarDB-X的私有協議作爲計算節點和存儲節點之間的橋樑,主要實現查詢下發和結果回傳等基礎功能,同時針對一些常用的場景進行了特殊優化。私有協議不僅具備傳統SQL接口執行SQL查詢的功能,還能直接執行自定義的執行計劃,使得計算節點和存儲節點之間的交互更加靈活可控。同時爲了提升網絡交互性能,改善高併發多連接場景下穩定性,私有協議設計時也借鑑了RPC的處理思路,採用了異步化協議設計、會話連接解耦、實例級連接池、流量控制等機制,解決了大部分使用傳統連接池遇到的問題,使得PolarDB-X的性能和穩定性都有所提升。

私有協議的設計和實現

兼容性 & 擴展性

聊到網絡通信協議,首先需要考慮的就是協議兼容性。作爲分佈式系統,整個系統的變更都不可能是一步完成的,在升級或變配過程中,都可能出現多個不同版本的客戶端或服務端。特別是在PolarDB-X中,存在計算節點和存儲節點,在進行升級時,每個節點都可能存在升級前後兩個版本,若通信協議發生了升級,則需要協議具備向前向後兼容的能力。

PolarDB-X私有協議在設計時充分考慮了這種情況,除了定長的協議頭,所有通信協議消息均使用protobuf進行序列化,即使新增了額外的字段,舊版本的節點也能正常工作。考慮到系統的演進,私有協議支持基於SQL語句的查詢,實現對SQL接口的完全替換,這部分擴展了MySQL官方的MySQL X protocol的實現,提供最大的兼容性。如下展示了PolarDB-X私有協議中SQL執行的message定義,在原有StmtExecute基礎上,增加了一些額外字段,提升了會話上下文恢復速度,可避免通過額外SQL進行設置。

message StmtExecute {
  optional string namespace = 3 [ default = "sql" ];
  required bytes stmt = 1;
  repeated Polarx.Datatypes.Any args = 2;
  optional bool compact_metadata = 4 [ default = false ];

  // Extended fields for fast context restore.
  optional string schema_name = 5;
  repeated Polarx.Datatypes.SessionVariable session_variables = 6;
  optional string encoding = 7;
  optional int32 token = 8;

  optional bool reset_error = 9;
  optional uint64 snapshot_seq = 10;
  optional uint64 commit_seq = 11;
}

會話連接解耦 & 異步化 & 流量控制

在傳統SQL接口中,一個TCP連接只能運行一個SQL會話,考慮到傳統單機MySQL是作爲一個服務端對外提供服務的,這個設計是非常合理的。但在PolarDB-X內部,MySQL被作爲內部存儲,在分佈式系統中,存在多個計算節點和存儲節點,在多連接複雜查詢的場景下,後端會話數會因爲數據分片的情況被成倍的放大,這時一個TCP連接對應一個SQL會話這種實現反而會帶來侷限性。因爲TCP連接存在三層握手、內核TCP協議棧開銷、連接鑑權等原因,使得動態擴容連接數是非常重的操作,而保留大量連接不僅耗費了大量系統資源同時增加了維護連接可靠的成本。

針對傳統SQL接口連接池的侷限性,PolarDB-X私有協議採用了會話連接解耦的策略,即採用在協議包頭中添加SessionId字段,標記會話ID,實現在同一個TCP連接上並行運行多個SQL會話。

struct {
  uint64 sid; // Session id. Default -1.
  uint32 length;
  uint8 message_type;
  opaque message_payload[Message.length - 1];
} Message;

在PolarDB-X的存儲節點上,使用一個獨立的調度線程處理TCP上收到的消息,該線程負責會話的創建及生命週期管理,同時將解碼後的消息放到對應的會話FIFO隊列中,由MySQL的任務執行線程進行執行,指令執行完成後,由session所在TCP的socket返回執行結果。

基於PolarDB-X存儲節點請求處理的FIFO特性,PolarDB-X計算節點使用異步調用和請求流水線的方式,最大化降低多指令的延遲。

多會話複用TCP連接,雖然降低了會話開銷,但帶來的額外的侷限,最典型的問題則是多個session對於TCP通道的爭搶。舉個簡單例子,一個TCP連接上,有一個點查和一個全表掃描的請求,計算節點全表掃描的消費速度沒有發送快,導致該TCP通道被全表掃描的數據佔據,點查結果無法及時發送過濾。針對這種場景,PolarDB-X私有協議設計了令牌機制,通過令牌對存儲節點的生產者進行背壓,而不是通過TCP的滑動窗口,從而保證短查詢的時效性。同時在連接使用策略上,優先使用空閒連接,而不是優先複用,儘可能避免爭搶的情況。

執行計劃傳輸

SQL雖然能精簡地描述一個查詢,但這是需要額外使用解析器和優化器爲代價的,在PolarDB-X中,計算節點和存儲節點之間的數據傳輸指令也是用SQL實現的。但是在點查等簡單的查詢場景下,SQL的解析優化也成爲制約存儲節點吞吐量的一個瓶頸。PolarDB-X私有協議結合計算節點的特性,在優化階段將下推執行的查詢直接轉換爲特殊的執行計劃。存儲節點通過私有協議收到執行計劃後,不用進行SQL解析和優化,直接進行數據的讀取和處理。在實際測試中,同樣吞吐量下,使用執行計劃相對於使用SQL查詢,存儲節點的CPU的降低了50%,查詢平均延遲也有近30%的下降。

高級查詢特性支持

在OLAP任務中,常需要從存儲節點拉取大量數據到計算節點進行處理,這對傳輸協議也是很大的挑戰。PolarDB-X計算節點在內存中使用緊湊的列式數據存儲結構,並藉助向量化提升數據處理速度。PolarDB-X私有協議針對這種應用場景,通過自定義的傳輸格式的方式,可以直接以列式方式傳輸結果集,繞過傳統傳輸協議行式傳輸帶來的計算節點行轉列的損失。同時針對列式數據格式的特性,後續也將具備壓縮及壓縮後計算的能力,進一步優化網絡和內存的開銷。

在複雜查詢中,不僅傳輸的數據量大,同時複雜join也是非常常見的情況。通過添加runtime filter是一種有效的優化方法,但是在基於傳統MySQL作爲存儲單元的情況下,這種高級過濾難以通過SQL進行表示。PolarDB-X中使用私有協議實現了bloom filter的傳遞,直接在存儲節點上對數據進行過濾,極大減少了網絡傳輸的壓力。更多有用的高級查詢特性,例如存儲節點數據按規則主動分發、狀態推送等也將逐步增加到PolarDB-X私有協議之中。

性能對比

使用私有協議後,最直接效果則是性能的提升,在點查場景下,私有協議相對於走SQL協議能極大降低後端存儲的壓力,同時提升吞吐量。

sysbench-select

  • 1.6億行數據
  • 300併發
  • 計算節點和存儲節點規格均爲16c64g
  • +39%

sysbench-oltp

  • 1.6億行數據
  • 150併發
  • 計算節點和存儲節點規格均爲16c64g
  • +14.4%


展望

PolarDB-X私有協議實現了對MySQL傳統SQL查詢協議的替換,並針對分佈式數據庫的特殊場景進行了擴展和改造。未來將在查詢性能、網絡開銷和功能擴展上進一步優化和改造,提升PolarDB-X計算節點和存儲節點的交互效率,爲高性能PolarDB-X奠定堅實的基礎。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章