Zdal分庫分表:支付寶是(shì)如何在分布式環境下(xià)完爆數據庫壓力的?

2018-02-28 17:06:13 ortotra

Zdal是(shì)支付寶自主研發的數據中間件産品,采用标準的JDBC規範,可以在分布式環境下(xià)看上去(qù)像傳統數據庫一樣提供海量數據服務,是(shì)一種通用的分庫分表數據庫訪問框架,解決單庫單表數據庫訪問壓力,Zdal主要提供分庫分表,結果集合并,sql解析,數據庫failover動态切換等功能,提供互聯網金融行業的數據訪問層統一解決方案,目前已經在支付寶的交易,支付,會員(yuán),金融等大部分關鍵應用上使用,并且在2013年雙11大促中運行穩定。


▲系統目标

1.數據訪問路由,将針對數據的讀寫請求發送到最合适的地方。

2.數據存儲的自由擴展,不再受限于單台機器的容量瓶頸和速度瓶頸,平滑遷移。

3.使用zdal組件進行數據庫的拆分,搭建分布式環境下(xià)的海量數據訪問平台。

4.實現(xiàn)mysql,oracle,DB2數據庫訪問能力。


【系統架構和領域模型】

▲系統整體架構



zdal組件主要有5部分組成:

1. Zdal-client:開發編程接口,實現(xiàn)jdbc的Datasource,Connection,Statement,PreparedStatement,ResultSet等接口,實現(xiàn)通用的jdbc-sql訪問,内部還實現(xiàn)讀庫重試,group數據源的選擇器,表名替換,sql執行器等功能。

2. Zdal-parser:支持oracle/mysql/db2等數據庫的sql語句解析,并且緩存。根據規則引擎提供的參數列表,在指定的sql中查找到需要的參數,然後返回拆分字段。

3. Zdal-rule:根據zdal-parser解析後的拆分字段值來确定邏輯庫和物理表名。

4. Zdal-datasource:數據庫連接的管理,支持mysql,oracle,db2數據庫的連接管理。

5. Zdal-common:zdal組件所使用的一些公共組件類。


總體流程



▲Zdal初始化流程


▲分庫分表初始化流程


▲分庫分表sql執行流程



【關鍵技術&第三方框架】

Zdal-client

Zdal-client 模塊主要是(shì)完成以下(xià)幾部分工作:

1.加載配置文件進行初始化工作,初始化groovy規則引擎。

2.對jdbc 标準接口的封裝,包括 DataSource、Connection、Statement、PrepareStatment等,并提供一個一對多的管理容器,可以管理多個jdbc建立的資源。

3.SQL執行:根據規則引擎生成的目标庫id和表名,進行表名替換後在目标庫上執行該sql,如果是(shì)跨庫跨表的sql,需要進行多個結果集的merge。

4.讀庫重試,即在讀庫發生斷連接問題的時候,Zdal會自動的嘗試從對等的其他讀庫中去(qù)查詢這條數據,盡最大努力保證在數據庫還有訪問能力的情況下(xià),保證數據的可訪問性。

5.将傳入的sql 和 參數進行包裝後,調用 zdal-parser 和zdal-rule的 相(xiàng)關接口,進行sql的解析以及計算相(xiàng)應的分庫分表結果。在此模塊将會實現(xiàn)表名替換的功能,即将sql的邏輯表名替換成帶後綴的物理表名。

6.動态指定讀庫功能,即可以讓業務根據實際需求指定一組中的某個讀庫進行操作,也可以指定到寫庫讀。

7.聚合函數結果集合并,針對count,sum,max,min等聚合函數在多個數據源的執行結果,進行結果集的合并。



▲Zdal-parser

Parser組件包括如下(xià)幾個部分:

1. Lexer 詞法解析。

2.Parser,Parser包括ExprParser,各種StatementParser。

3. AST, Abstract Syntax TreeParse出來的結果就是(shì)AST。

4.StatementParser:解析各種sql語句,按照詞法分析和語法分析提煉sql的關鍵字。

5.Visitor:根據StatementParser的解析結果對AST做各種處理,比如FormatOutput,遍曆,tableName,表達式,函數,綁定參數,分頁參數,獲取sql解析的結果。


Zdal-Parser的主要核心類圖如下(xià):


▲Zdal-rule

Zdal-rule 主要是(shì)完成規則的計算,包括分庫的計算和分表的計算,相(xiàng)當于是(shì)一個二次路由的過程,包括單庫單表、單庫多表以及多庫多表等幾種情況。爲了适應規則的靈活配置,目前主要是(shì)采用書(shū)寫groovy腳本的方式來配置規則,或者在代碼裏封裝拆分規則靜态方法,在規則裏調用該靜态方法即可。


我們假設分庫規則是(shì) user_id % 9  /  3 分表規則是(shì)user_id % 9 % 3