阿里分散式資料庫服務相關介紹

tianxia發表於2022-12-16

TDDL 研發淘寶的歷史和背景

淘寶 DRDS/TDDL 是阿里巴巴自主開發的 服務。 DRDS 脫胎於阿里巴巴開源的 Cobar 分散式資料庫引擎,吸收了 Cobar 核心的 Cobar-Proxy 原始碼,實現了一套類似於 MySQL-Proxy 協議的獨立解析端,可以解析和處理傳入的 SQL ,為應用遮蔽各種複雜的底層 DB 拓撲,獲得與單機資料庫相同的體驗。同時,借鑑淘寶 TDDL 豐富的阿里分散式資料庫實踐經驗,實現了對分散式 Join SUM MAX COUNT AVG 等聚合函式和排序函式的支援,透過異構索引和小表廣播解決了分散式資料庫使用場景中出現的一系列問題,最終形成了完整的分散式資料庫方案。

 

使用場景

分散式資料庫的核心需求是解決單機資料庫的瓶頸。阿里分散式資料庫在使用過程中必然會遇到資料庫容量、連線數、事務數、讀取效能的瓶頸。這些瓶頸的兩種常見解決方案是單機垂直縱向擴充套件模型和水平橫向擴充套件模型。

 

擴充套件模式與硬體資源繫結性強,一般採用升級單機硬體能力的方式來擴充套件資料庫服務能力。比如 MySQL 本來是做單機資料庫的,遇到訪問瓶頸就把磁碟換掉了。當訪問量更高的時候,就需要考慮使用 Oracle 的商用解決方案,高階儲存裝置,高階小型機,也就是 IOE 架構,甚至升級 IOE 裝置來換取更高的擴充套件和服務能力。在這個過程中,會存在裝置升級和資料遷移的成本。

 

多機橫向擴充套件模式使用大量廉價的 PC-Server 透過陣列實現資料庫的橫向擴充套件。優勢在於成本更低,因為不需要淘汰老舊的裝置和系統,不需要頻繁遷移資料。必要時,只需擴大服務叢集的規模。

 

使用分散式多機模式也需要一定的成本。分散式資料庫架構的邏輯和物理分佈與單機資料庫有很大的區別。所以需要將單機資料庫的資料遷移到分散式架構模型,也就是分片的資料切片過程。這個過程包括資料的分散式邏輯設計、資料庫遷移以及 SQL 最佳化和轉換。當然,這種遷移是一次性的。架構遷移完成後,不需要關心資料庫擴充套件和資料遷移,因為分散式資料庫的服務層已經整合了擴充套件功能,架構支援水平擴容。

 

2006 年以前,我們的核心應用普遍採用 Oracle 資料庫,但隨著業務的快速發展,淘寶的資料量和訪問量急劇增加,資料庫存在嚴重的訪問效能問題,導致資料庫頻繁當機,業務停滯。即使當時已經使用了 Oracle 亞洲最大的 RAC 叢集,單機資料庫的擴充套件能力也達到了極限,需要付出巨大的資金和運維成本。所以基於自己的實際情況,我們逐漸開始去 IOE 研發分散式關聯式資料庫服務,實現資料庫的高擴充套件性和成本可控。目前, DRDS 已經成為我們內部分散式資料庫的標準,對外服務於金融、製造、政府機構、電子商務、社會等行業。

 

DRDS 的整體建築

DRDS/TDDL 是一種典型的水平擴充套件分散式資料庫模型,不同於傳統的獨立資料庫共享任何東西的體系結構。 DRDS/TDDL 採用 SHARE NOYTHING 架構, SHARE NOYTHING 架構的核心思想是利用普通伺服器將單機資料拆分成底層多個資料庫例項,透過統一的代理叢集進行 SQL 解析最佳化、路由和結果聚合,從而對外公開簡單唯一的資料庫連結。整體架構如圖 1 所示,包括 DRDS 服務模組、 DRDS 控制模組、配置中心、監控運維、資料庫服務叢集和域名服務模組。

 

 

分散式叢集管理模組用於控制叢集節點。在資料安全性和服務可用性方面,透過高效的資料同步系統,實現資料庫的擴充套件和資料庫例項的主備資料同步。同時,依靠例項監控模組和 HA 模組實現主備監控和自動容災切換。作為成熟的分散式資料庫產品, TDDL 還擁有完善的運維控制體系,可以實現分散式資料庫多個例項間的配置管理和變更,以及資料同步、擴充套件等任務管理,降低運維成本。

 

DRDS/TDDL 的功能特徵

資料碎片

DRDS 的基本原理是分片,即資料分片。將單機資料庫的資料拆分成多個單機資料庫,對外保持邏輯一致性。拆分的後端資料庫是一個子資料庫,對應的表稱為子表。每個子資料庫負責讀寫一份資料,分散了整體的訪問壓力。當系統容量擴大時,只有透過橫向增加子資料庫數量和遷移相關資料,才能提高 DRDS 系統的整體容量。

 

 

對於資料分片,需要選擇一個分片緯度,這是資料分佈的基礎。例如,對於一個使用者訂單資訊表,如果按照訂單 ID 拆分資料,那麼相同訂單 ID 的資料會被拆分到同一個阿里分散式資料庫 storage 節點;如果根據使用者 ID 分割資料,同一使用者的訂單將被分發到同一資料庫儲存例項的儲存節點。

 

拆分緯度的選擇很重要。一般來說,拆分鍵要根據實際的業務場景來選擇。總的指導原則是儘可能保證每個資料庫節點的資料量和負載更加均衡。單個 SQL 操作儘量在單個資料庫節點執行,不同 SQL 的查詢在不同的阿里分散式資料庫節點執行。這樣可以減少多個節點之間的網路傳輸,保持分散式查詢的效率,平衡負載,方便擴充套件。

 

平滑擴充套件

資料庫擴充套件是資料庫操作和維護中的一種常見操作。當資料庫的資料儲存容量不足時,傳統的單機資料庫需要增加單機的儲存空間來支援更多的資料寫入。但是隨著資料的膨脹,對於同一個 SQL 查詢語句,基礎資料的增加必然會降低查詢效率。同時,隨著資料量的增加,資料庫的訪問壓力通常會翻倍,導致單機資料庫的連線數達到極限。這時單機資料庫需要升級硬體規格,使用磁碟陣列,使用高階儲存介質裝置和更高階的小型機伺服器來承擔資料量和訪問的增加。這個過程將伴隨著大量的資料遷移。為了保證資料的一致性,通常需要停止資料遷移,這對業務影響很大。

 

 

DRDS 的分散式架構採用平滑擴充套件來解決上述問題,透過增加更多的底層資料庫例項來完成整體的叢集擴充套件。

 

平滑擴充套件的前提是使用者需要根據上述子資料庫和子表邏輯將邏輯資料庫拆分成多個物理子資料庫,不同的子資料庫落在不同的底層物理資料庫機上。子資料庫和子表的數量通常建議使用者預估未來 3-5 年資料量的增長情況,並根據這個資料量計算整體資料應該分成多少個子資料庫,因為單個子資料庫的資料量通常有一個建議值,這會導致單個節點的效能下降。有了特定數量的子資料庫,可以根據子資料庫的邏輯將資料分割到不同的儲存例項節點。當承載子資料庫的物理資料庫機出現容量和連線數不足等瓶頸時,可以增加新的物理資料庫節點,將原有的子資料庫遷移到新的物理資料庫節點上,實現整體邏輯資料庫的擴充套件。

 

擴充套件過程實際上就是物理資料遷移的過程。引擎層先在物理節點上根據子資料庫遷移後的邏輯建立一個新的子資料庫,然後預留一個時間點進行全量資料的遷移。完整遷移完成後,將根據之前保留的時間點開始增量資料捕獲。當增量資料趕上兩邊資料幾乎相同時,資料庫瞬間停止寫入,最後一個資料被捆綁。引擎層切換資料庫劃分邏輯的路由。路由規則切換後,核心擴充套件邏輯完成,整個切換過程在毫秒級完成。

 

為了保證資料本身的安全性,方便卷擴充套件和回滾,路由規範切換後,遷移前後的邏輯子庫資料會實時同步,只有業務確認後才能清理原有的子庫資料。

 

整個擴充套件過程上層的業務接入幾乎察覺不到,是完全平滑的擴充套件。但還是要儘量注意阿里分散式資料庫中擴充套件的操作,尤其是寫低期,避免切換時資料追趕時間過長。

 

分散式 MySQL 執行引擎

分散式資料庫的資料有規律地儲存在多個底層儲存例項中,資料物理儲存的改變會造成與原生資料庫引擎的不相容。單機資料庫的所有資料讀寫和計算都在單臺物理機上進行,資料狀態維護在單機上,主要效能消耗在於磁碟的資料讀取。在分散式架構下,資料和狀態需要在多個資料庫例項之間、底層例項和代理之間傳輸,會造成網路 I/O 消耗,網路 I/O 造成的效能消耗遠大於本地磁碟 I/O 和本地計算。

 

因此,分散式 SQL 引擎的主要目標是實現與單機資料庫 SQL 引擎的完全相容,實現 SQL 的智慧下推。它可以智慧分析 SQL ,分析哪些 SQL 可以直接發出,哪些 SQL 需要最佳化轉換,最佳化成什麼,路由到哪些例項節點執行,充分發揮阿里分散式資料庫 instance 的全部能力,減少網路間的資料傳輸,最終將不同例項處理的少量結果資料彙總返回給應用呼叫者。這就是分散式 SQL 引擎的智慧下推功能。

 

分散式引擎的職責包括四個過程 :SQL 解析、最佳化、執行和合並。

 

智慧的核心原則如下 :

 

減少網路傳輸;

減少計算量,把計算儘量下推到更低的資料節點,讓計算在資料所在的機器上執行;

充分發揮底層儲存的全部容量。

基於上述原則的 SQL 引擎可以實現服務能力的線性擴充套件。比如一個簡單的 AVG 操作,對於一些比較初級的分散式資料庫模型,通常的做法是將 AVG 直接傳送到所有的儲存節點,這樣就造成了語法相容,語義不相容,最後導致錯誤結果。 DRDS 的智慧下推引擎對 SQL 的語法進行了充分的語義相容適配。對於 AVG 操作,引擎只能將邏輯 AVG SQL 解析最佳化為 SUM COUNT SQL ,然後下推。底層阿里分散式資料庫 instance 節點完成求和計數計算,充分利用底層節點的計算能力,聚合計算引擎層各儲存節點的求和計數結果,最終計算 AVG 。這只是一個典型案例。在分散式資料庫模型下,多個資料表的連線操作、合併和排序的相容性非常複雜。這裡,我們將分析 TDDL/DRDS 如何解決分散式場景下的具體問題。

 

彈性膨脹

TDDL/DRDS 採用服務和儲存分離的架構。 DRDS 例項服務層以叢集方式部署,一個服務例項由多個服務節點組成,透過負載均衡和域名服務對外提供服務。多個服務節點是無狀態和同步的,平均負載處理使用者請求。當叢集的業務處理能力不足時,可以隨時擴充套件服務節點,增加業務處理能力。同樣,在業務不景氣時可以適當縮減叢集的規模,從而實現靈活的服務能力擴充套件。

 

對於一些資料量較大的 OLAP 場景,當單個伺服器節點的記憶體資源較高時,可以透過升級其規格來縱向擴充套件單個伺服器節點的能力。

 

 

分散式連線和小表廣播

分散式場景中的 Join 操作不同於單臺機器中的操作。單機資料的 Jion 操作發生在單機上,沒有內部網路資料傳輸。

 

在分散式架構下,對於多個資料表 Join ,如果參與 Join 的多個表的資料拆分緯度不同,那麼資料會按照不同的拆分緯度分散到不同的資料庫例項上。 Join 操作可能產生跨多個物理子資料庫的 Join ,需要多個底層例項進行大量資料傳輸, SQL 的執行效率無法保證。因此,參與連線操作的資料表應儘可能保持拆分緯度一致,使連線操作儘可能發生在單臺機器上,減少跨資料庫連線。如果不能維持拆分緯度的統一性,並且存在跨庫 Join 操作,那麼原則就是儘量減少 Join 操作的輸出傳輸。

 

 

DRDS 常用的連線演算法是基於巢狀迴圈的。對於 Join 的左表和右表,首先從 Join 的左表 ( 驅動表 ) 中取出資料,然後將取出的資料中的 Join 列的值放入右表並進行 in 查詢,從而完成 Join 過程。因此,左連線表中的資料越少, DRDS 查詢右連線表的次數就越少。如果右表中的資料也很小或者建立了索引,那麼 Join 的速度會更快。因此,在 DRDS 中,連線驅動表的選擇對於連線的最佳化非常重要。

 

但在實際的資料庫場景中,往往會有一些資料量小、更新頻率低的源資訊表,不需要拆分。類似於這些源資訊表,一個邏輯表的資料儲存在一個子資料庫中,通常是 0 ”資料庫,這些表被定義為“小表”,而其他業務資料量大、更新頻率高的表仍然採用子資料庫、子表的拆分方式。當這些“小表”與子資料庫、子表進行連線時,基於巢狀迴圈演算法的原理,小表作為連線的驅動表,會大大減少右表的 in 查詢次數。同時, DRDS 提供的小表廣播功能,可以透過實時資料複製,將“小表”的所有資料和增量變化實時複製到子資料庫中,將跨資料庫的 join 轉化為單機 Join 操作,從而減少多個底層例項中伺服器節點和資料的計算。

 

異質指數

異構索引是 DRDS 提高分散式查詢效率的解決方案之一,可以解決分散式場景下資料拆分緯度和使用緯度進行資料查詢不一致導致的效率低下問題。

 

 

當資料表拆分成多個子資料庫和子表時,資料在子資料庫和子表中的分佈規則是固定的。然而,資料的業務使用場景通常非常複雜。如果資料的查詢緯度符合資料拆分和分佈的規則,則在一個子資料庫和子表中執行一條 SQL 。如果資料查詢的緯度與資料拆分分佈的規範不一致,很可能會在多個子資料庫、子表上執行一條 SQL ,跨資料庫查詢會增加網路 I/O 的成本,查詢效率必然下降。

 

解決這個問題的思路是分散式資料庫的一貫原則,讓 SQL 的執行可以在單個資料庫上完成。實際的做法是使用“空間換效率”的方案,即冗餘儲存同一個資料表的多個副本,根據不同的業務使用場景進行拆分,使拆分緯度和使用緯度保持一致,同時可以在多個資料之間進行實時資料複製,解決資料一致性問題。這就是“異構索引”方案。當然,異構索引表不能被無限濫用。過多的異構索引表會影響同步效率,並對源資料表造成同步壓力。

 

最優方法

分散式 SQL 最佳化

SQL 最佳化是資料庫使用和運維的日常操作。阿里分散式資料庫 SQL 最佳化不僅要考慮磁碟 I/O 開銷,還要注意網路 I/O 開銷。為了最佳化 SQL 執行,其核心最佳化思想是減少網路 I/O ,為此, DRDS 會盡力將原 DRDS 層的工作分配到子庫 ( RDS ) 中。 ) 在最下面。這樣,原本需要經過網路的 I/O 開銷就可以轉化為單機的磁碟 I/O 開銷,從而提高查詢執行效率。所以,如果我們在使用 DRDS 的時候遇到慢 SQL ,就需要根據 DRDS 的特點適當重寫 SQL

 

首先,條件查詢最佳化,根據 split key DRDS 的資料進行水平拆分。如果在查詢中使用 split key ,對於減少 SQL DRDS 中的執行時間具有重要意義。只要查詢儘可能具有子資料庫關鍵字, DRDS 就可以根據子資料庫關鍵字的值將查詢直接路由到特定的子資料庫,這有助於避免 DRDS 掃描整個資料庫。資料庫關鍵字的條件精度越高,查詢速度就越快。只有這樣的最佳化才能充分發揮分散式架構查詢的優勢,便於後續查詢能力的擴充套件。

 

其次,針對連線的最佳化,選擇條件查詢資料量小的連線表作為左表 ( 驅動表 ) ,減少右表的 in 查詢次數。在涉及“廣播表”的資料量少、變化小的 Jion 操作中,使用“廣播表”作為驅動表。

 

對於 LIMIT OFFSET COUNT 語句, DRDS 的實際 SQL 執行是依次讀出 OFFSET 前記錄的資料並丟棄,只留下 OFFSET 後的資料,這樣當 OFFSET 很大時,讀取資料記錄的數量很少,效率也很低,因為需要大量的磁碟 I/O 讀取操作來讀取 OFFSET 前的資料。最佳化方法是將 SQL 最佳化為兩步 : 鍵的偏移讀取和 in 操作。首先讀取偏移後的記錄鍵,將這些鍵快取在記憶體中,然後透過 in 查詢獲得完整的記錄資訊。這將大大減少磁碟 I/O ,明顯提高效率。

 

分散式事務最佳化

分散式資料庫事務和 SQL 查詢最佳化的邏輯是相同的原理。嘗試在單個資料庫中執行事務。只有在單個資料庫中執行事務,才能在保持事務的 ACID 特性的同時,線性擴充套件事務能力。這種單庫交易通常被稱為“強交易”。

 

在實踐中,業務經常面臨分散式資料庫架構,資料庫事務將不可避免地跨資料庫執行。跨資料庫事務必須涉及一個事務的多個分支中事務分支的執行和狀態同步。與單機事務相比,分散式跨資料庫事務的吞吐量和延遲會大大增加。一個事務涉及的儲存庫越多,事務邊界就越大,事務延遲就越高,效能就呈線性衰減。

 

當遇到跨庫事務時,通常的實踐最佳化方法是透過 “最終一致性”事務來保證事務執行的吞吐量。“最終一致性”事務的原理是優先執行核心事務分支的前向執行,然後儲存事務的中間狀態,其他事務分支非同步執行。執行完成後,達到最終的事務一致性,避免了跨資料庫事務時序執行的阻塞,提高了事務吞吐量。如圖 8 所示,事務 3 和事務 5 是跨資料庫事務。事務分支先在左資料庫中執行,非同步事務分支在右資料庫中執行,分別在各自的子資料庫中執行,最終實現事務一致性。

 

單機資料庫遷移到 DRDS 的過程

單機資料庫遷移到分散式資料庫是為了保證業務的正常執行,平穩過渡,減少運維。整個遷移分為三個步驟。

 

第一步,保持對原資料庫的讀寫,資料透過複製機制寫入分散式資料庫,前提是分散式目標資料庫表已經建立;

 

第二步,驗證雲上的資料是否正確,切一部分讀取流程到目標分散式資料庫進行讀取線上壓力驗證 ( 測試環境也可以提前驗證 )

 

第三步 : 口述業務幾分鐘,將讀寫流量切換到目標資料庫,將資料反向複製到源單機資料庫,保證隨時可以切換回單機資料庫,同時也可以做雲下的資料備份。

 

 

未來的發展

在分散式資料庫上讀取線上壓力驗證 ( 測試環境也可以提前驗證 )

 

第三步 : 口述業務幾分鐘,將讀寫流量切換到目標資料庫,將資料反向複製到源單機資料庫,保證隨時可以切換回單機資料庫,同時也可以做雲下的資料備份。

 

 

未來的發展

DRDS 作為分散式資料系統中資料庫服務的中間層,未來將適應更多的底層儲存引擎。在充分利用底層儲存節點計算能力的同時,最佳化自身服務的計算能力,解決 OLAP 場景,成為一個完整的分散式資料庫服務體系,能夠完全覆蓋 OLTP OLAP 等資料庫服務場景。同時完整的分散式資料庫邏輯層的運維支援和分散式強一致事務的支援是完整的。



來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70025223/viewspace-2928418/,如需轉載,請註明出處,否則將追究法律責任。

相關文章