數據庫中間件漫談

1.前言

隨着業務的發展,MySQL數據庫中的表會越來越多,表中的數據量也會越來越大,相應地,數據操作的開銷也會越來越大;另外,無論怎樣升級硬件資源,單臺服務器的資源(CPU、磁盤、內存、網絡IO、事務數、連接數)總是有限的,最終數據庫所能承載的數據量、數據處理能力都將遭遇瓶頸。

分表、分庫和讀寫分離可以有效地減小單臺數據庫的壓力。

本文主要針對業界主流的數據庫中間件的實現、功能、成本等方面進行對比,總結數據庫中間件的實現方式,並展望未來的可能發展。

2. 實現方式

一般來說,對於數據庫中間件,可以在以下六個層次做切入。
在這裏插入圖片描述

2.1 代碼層

在同一個項目中創建多個數據源,採用if else的方式,直接根據條件在代碼中路由。

Spring中有動態切換數據源的抽象類,具體參見AbstractRoutingDataSource。

如果項目不是很龐大,使用這種方式能夠快速的進行分庫。但缺點也是顯而易見的,這種海量的代碼侵入是絕不能被接受的。

而且當查詢結果返回時,需要對跨庫、聚合等查詢結果進行歸併,開發工作量非常巨大。

這種方式瞭解一下即可,一般不會去使用。

2.2 框架層

主要是修改或增強現有ORM框架的功能,在SQL中增加一些自定義原語或者hint來實現。

常見的比如實現一些攔截器(比如Mybatis的Interceptor接口),增加一些自定義解析來控制數據的流向,效果雖然較好,但會改變一些現有的編程經驗。

這種情況適合公司ORM框架統一的情況,但在很多情況下不太現實。

而且大部分情況下要修改框架源碼,因此,也不推薦。

2.3 驅動層

無論是從代碼層還是框架層做處理,都是高侵入、難維護的。

因此,常見的數據庫中間件,至少需要從驅動層開始,我們可以理解爲一個smart-client。

什麼意思是smart-client呢?

通常smart-client是在連接池或者driver的基礎上進行了一層封裝。

這個smart-client內部可以與不同的數據庫建立連接。

服務需要查詢的sql,就交給smart-client進行解析、優化,然後發送給具體的數據庫進行操作。

例如在讀寫分離情況下,smart-client會選擇sql走從庫還是主庫;在分庫分表的情況下,進行sql解析、sql改寫等操作,然後路由到不同的分庫,將得到的結果進行合併,返回給應用。
在這裏插入圖片描述
我們熟知的TDDL、Sharding-JDBC等,都是在此層切入。

優點:

1)實現方便,業務無入侵。smart-client不需要實現客戶端通信協議,只需要在數據數據庫廠商提供的不同語言的數據庫驅動上做封裝即可。例如mysql針對java語言提供了mysql-connector-java驅動,針對python提供了mysql-connector-python驅動。

2)天然去中心化。smart-client以sdk的方式被應用引入,然後部署到不同的服務節點上,不需要有代理層proxy。因此相較於代理方式而言,不需要考慮高可用的問題。只要應用的節點沒有全部宕機,就可以訪問數據庫。(這裏的高可用是相比代理層proxy而言,數據庫本身的高可用還是需要保證的)

缺點:

1)通常僅支持某一種語言。例如tddl、zebra、sharding-jdbc都是使用java語言開發,因此對於使用其他語言的用戶,就無法使用這些中間件。如果其他語言要使用,那麼就要開發多語言客戶端。
2)版本升級困難。因爲應用使用數據源代理就是引入一個jar包的依賴,在有多個應用都對某個版本的jar包產生依賴時,一旦這個版本有bug,所有的應用都需要升級。而數據庫代理升級則相對容易,因爲服務是單獨部署的,只要升級這個代理服務器,所有連接到這個代理的應用自然也就相當於都升級了。
3)去中心化的缺點,比如無法做全局的sql限流

2.4 代理層

在應用中,我們通過一個普通的數據源(c3p0、druid、dbcp等)與代理服務器建立連接,所有的sql操作語句都是發送給這個代理,由這個代理去操作底層數據庫,得到結果並返回給應用。在這種方案下,分庫分表和讀寫分離的邏輯對開發人員是完全透明的。
在這裏插入圖片描述
像MySQL Router、MyCat、ShardingSphere(proxy模式)等,都是在此層切入。

優點:

1)多語言支持。也就是說,不論你用的php、java或是其他語言,都可以支持。以mysql數據庫爲例,如果proxy本身實現了mysql的通信協議,那麼你可以就將其看成一個mysql 服務器,因此不同語言的開發者都可以使用mysql官方提供的對應的驅動來與這個代理服務器建通信。

2)對業務開發同學透明。由於可以把proxy當成mysql服務器,理論上業務同學不需要進行太多代碼改造,既可以完成接入。

缺點:

1)實現複雜。因爲proxy需要實現被代理的數據庫server端的通信協議,實現難度較大。

2)proxy本身需要保證高可用。由於應用本來是直接訪問數據庫,現在改成了訪問proxy,意味着proxy必須保證高可用。否則,數據庫沒有宕機,proxy掛了,導致數據庫無法正常訪問,就尷尬了。

3)租戶隔離。可能有多個應用訪問proxy代理的底層數據庫,必然會對proxy自身的內存、網絡、cpu等產生資源競爭,proxy需要需要具備隔離的能力。

2.5 Sidecar

Sharding-Sidecar是ShardingSphere的第三個產品,目前仍然在規劃中。 定位爲Kubernetes或Mesos的雲原生數據庫代理,以DaemonSet的形式代理所有對數據庫的訪問。

通過無中心、零侵入的方案提供與數據庫交互的的齧合層,即Database Mesh,又可稱數據網格。 Database Mesh的關注重點在於如何將分佈式的數據訪問應用與數據庫有機串聯起來,它更加關注的是交互,是將雜亂無章的應用與數據庫之間的交互有效的梳理。使用Database Mesh,訪問數據庫的應用和數據庫終將形成一個巨大的網格體系,應用和數據庫只需在網格體系中對號入座即可,它們都是被齧合層所治理的對象。
在這裏插入圖片描述

優點:

分佈式雲原生的數據庫中間件模式,集成了jdbc和proxy各自的優點,能滿足高可用、跨語言、無感知升級等多種優勢特性

缺點:

需要整體架構支持雲原生體系

目前還沒正式上線。

2.6 存儲層

這個層次實際上不應該叫數據庫中間件了,需要更換存儲。

比如Aurora、polardb、tidb等分佈式數據庫,通過計算節點和存儲節點分離,計算節點scale up,存儲節點scale out的理念將公有云的關係數據庫產品推向了一個新的高度。

這樣一來,實際上已經不再需要傳統的數據庫中間件了,一切問題天然就不存在了。

3. 功能對比

從上文可以瞭解到,目前最主流的數據庫中間件主要是從驅動層smart-client和代理層proxy切入的。

下面,我們來了解下業界主流的中間件產品在這兩個層次的站隊情況與實現的功能對比。
在這裏插入圖片描述
其他還有比如:

Atlas、Kingshard、DBProxy、mysql router、MaxScale、58 Oceanus、ArkProxy、Ctrip DAL、Tsharding、Youtube vitess、網易DDB、Heisenberg、proxysql、Mango、DDAL、Datahekr、MTAtlas、

我們可以看到,基本各個大廠都擼過一遍自己的中間件產品。不過目前開源而且比較火的已經不多了,主要還是以shardingsphere爲主。

我們從功能維度,來對比一下幾個產品。
在這裏插入圖片描述

4. 展望

從上文的分析可以看出,儘管目前主流的數據庫中間件還是在smart-client和proxy兩個層面進行處理的,但是,已經能看到未來的方向了。雲原生的到來,估計會做進一步的降維打擊。

一方面是作爲sidecar的模式,可能會有一個新的階段,比如shardingsphere推出sidecar模式後。

而另一方面,雲數據庫通過全新的計算存儲分離的架構方式,打破傳統關係型數據庫的性能瓶頸,傳統數據庫中間件將不再需要關注,一切都將以數據庫基礎設施的形式提供給使用者。

看到這裏了,原創不易,點個贊吧,你最好看了~

知識碎片重新梳理,構建Java知識圖譜:https://github.com/saigu/JavaKnowledgeGraph (歷史文章查閱非常方便)

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