1. 程式人生 > >假如讓你來設計資料庫中介軟體

假如讓你來設計資料庫中介軟體

轉自:https://mp.weixin.qq.com/s/6kuVgdO7RBs9gs229wG3wA     架構師之路

13年底負責資料庫中介軟體設計時的設計文件,拿出來和大家分享:

  • 可以瞭解下資料庫中介軟體技術

  • 可以瞭解下架構師系統設計的思路

一、總體目標

資料庫中間層專案背景不再展開,根據前期的調研以及和公司同事的討論,中間層的核心目標主要有兩個:

  • db虛擬化:讓db對業務線透明(本文的db均指mysql),業務線不再需要知道db的真實ip,port,主從關係,讀寫關係,高可用等

  • 分庫的支援:讓db的分庫對業務線透明

二、實現的功能

上述目標相對比較寬泛,具體來說,資料庫中間層需要實現以下功能。

(1)統一接入入口

如果統一接入入口,從今以後,不再有

db1.58.com:3306

db2.58.com:3306

im.58.com:3306

jiaoyou.58.com:3306

只有

db.58.com:3306

所有的業務線,對db的訪問,都只有一個入口,由資料庫中間層來進行許可權驗證,由中介軟體來路由請求,這是一種完美的情況。

當然,統一一個總入口目標有點巨集大,可以循序漸進,先各業務線統一讀寫訪問入口,故折衷的目標可以是,從今以後,不再有

im.read.db1.58.com:3306

im.read.db2.58.com:3306

im.write.db.58.com:3306

而只有

im.58.com:3306


im業務對db的訪問,統一到一個入口上來了,由中間層來對請求進行智慧路由。

更簡化的,甚至可以初期同一個業務線的db讀寫都不對業務線透明,資料庫中間層只做簡單的請求轉發,先初步的把資料庫訪問入口收攏到資料庫中間層來,為後續的統一,再統一打下基礎。


ROAD-MAP規劃如下:

  • 業務線入口統一(中轉請求)

  • 業務線入口統一(智慧路由)

  • 全域性入口統一

(2)保持訪問介面


原來db的訪問方式主要有以上三種:

  • 手工用mysql客戶端連mysql,直連資料庫執行命令

  • java使用jdbc連線資料庫

  • c/c++使用libmysqlclient.a來對mysql進行訪問

所謂保持訪問介面,是指上游對資料庫的訪問介面完全不用變,中介軟體服務對上游來說,就是資料庫


由於SQL協議是非常複雜的,在db的客戶端與伺服器插入了一箇中間層之後,不一定能對所有的SQL功能都進行支援,支援哪些SQL是需要慎重考慮的。

(3)遮蔽讀寫分離


業務層不需要在關注讀寫分離,由中介軟體來進行讀寫請求路由。

(4)支援的分庫

58的db的水平擴充套件,基本是用的分庫的方式(分庫比較好,很容易實現例項的擴容),即:

db.table會水平拆分為:

db1.table

db2.table

db3.table

db4.table

這樣的話,dao層對於table就只有一個table例項了,比較方便。


根據前期與各業務線同學的溝通,58在分庫上的業務訪問需求為(這個調研的週期比較長,和很多業務線進行了溝通):

  • patition key普通查詢

  • patition key上的IN查詢

  • 非patition key上的查詢

  • 有限功能的排序+分頁查詢

故對分庫上的分散式SQL功能,資料庫中間層只需要支援上上述四項即可。

(5)高可用性的支援

高可用的支援又分為兩個部分:

第一部分,故障自動發現:下游資料庫掛了,能夠自動發現問題,並報警周知相關人員。

第二部分,故障自動轉移

  • 主庫掛了,能夠自動切換,或者遮蔽寫請求

  • 從庫掛了,能夠自動自動切換讀請求量流量

  • 中介軟體掛了,自動切換中介軟體流量,高可用

(6)可運維性的支援

  • 支援一些統計資料的展現

  • 支援一些管理命令

  • 支援頁面話的運維

however,只要總的框架設計具備可擴充套件性,這些功能可以循序漸進,逐步新增。

三、設計折衷

(1)協議與整體架構

既然選擇了mysql client server protocol作為業務層與中間層之間的協議,那麼中間層必然是作為mysql-server接收上游的請求作為mysql-client向真正的mysql傳送請求的,中間層的整體結構如下:


這樣的話,需要對mysql client server protocol做詳盡的研究,瞭解:

  • 連線的建立過程

  • 許可權認證的過程

  • 壓縮解壓縮的過程

  • 請求響應二進位制協議各種細節

協議這一塊的掌握必須詳盡,好在官方文件相對比較全面:

http://dev.mysql.com/doc/internals/en/client-server-protocol.html

(2)架構細節


總體架構細節圖如上。

(2.1)上游

  • mysql客戶端,java使用jdbc作為上游連線,c/c++使用libmysql.a作為上游連線,使用的是Mysql Client Server協議

  • DBA亦可以向中介軟體傳送一些管理命令,或者檢視一些統計資訊,使用的是自己定義的內部協議

(2.2)下游

處於系統體系結構中的最後端,系統中介軟體的下游就是mysql叢集了,中介軟體與mysql之間使用的也是Mysql Client Server協議。

(2.3)中間層-ConfigMgr

中間層配置檔案管理元件ConfigMgr是中間層中非常重要的一個部分,請求的轉發,讀寫分離,分庫功能的支援,都需要通過配置來完成。

<mysql>

<db id=0 logic_db="im"type=1>

       <item ip="10.58.1.100" port=3306 name="im" />

</db>

<db id=1 logic_db="umc"type=2 patition_count=2 key="uid" hash="mod">

   <patition id=0>

       <item ip="10.58.1.100" port=3306 role="w" />

       <item ip="10.58.1.101" port=3306 role="r" />

       <item ip="10.58.1.102" port=3306 role="r" />

   </patition>

   <patition id=1>

       <item ip="10.58.1.100" port=3316 role="w" />

       <item ip="10.58.1.101" port=3316 role="r" />

       <item ip="10.58.1.102" port=3316 role="r" />

   </patition>

</db>

</mysql>

從配置檔案可以看出,ConfigMgr需要管理的mysql配置型別有兩種:

type=1請求轉發

<db id=0 logic_db="im"type=1>