隨着業務的發展,MySQL數據庫中的表會愈來愈多,表中的數據量也會愈來愈大,相應地,數據操做的開銷也會愈來愈大;另外,不管怎樣升級硬件資源,單臺服務器的資源(CPU、磁盤、內存、網絡IO、事務數、鏈接數)老是有限的,最終數據庫所能承載的數據量、數據處理能力都將遭遇瓶頸。php
分表、分庫和讀寫分離能夠有效地減少單臺數據庫的壓力。java
本文主要針對業界主流的數據庫中間件的實現、功能、成本等方面進行對比,總結數據庫中間件的實現方式,並展望將來的可能發展。python
通常來講,對於數據庫中間件,能夠在如下六個層次作切入。mysql
在同一個項目中建立多個數據源,採用if else的方式,直接根據條件在代碼中路由。git
Spring中有動態切換數據源的抽象類,具體參見AbstractRoutingDataSource。github
若是項目不是很龐大,使用這種方式可以快速的進行分庫。但缺點也是顯而易見的,這種海量的代碼侵入是毫不能被接受的。面試
並且當查詢結果返回時,須要對跨庫、聚合等查詢結果進行歸併,開發工做量很是巨大。sql
這種方式瞭解一下便可,通常不會去使用。數據庫
主要是修改或加強現有ORM框架的功能,在SQL中增長一些自定義原語或者hint來實現。編程
常見的好比實現一些攔截器(好比Mybatis的Interceptor接口),增長一些自定義解析來控制數據的流向,效果雖然較好,但會改變一些現有的編程經驗。
這種狀況適合公司ORM框架統一的狀況,但在不少狀況下不太現實。
並且大部分狀況下要修改框架源碼,所以,也不推薦。
不管是從代碼層仍是框架層作處理,都是高侵入、難維護的。
所以,常見的數據庫中間件,至少須要從驅動層開始,咱們能夠理解爲一個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限流
在應用中,咱們經過一個普通的數據源(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須要須要具有隔離的能力。
Sharding-Sidecar是ShardingSphere的第三個產品,目前仍然在規劃中。 定位爲Kubernetes或Mesos的雲原生數據庫代理,以DaemonSet的形式代理全部對數據庫的訪問。
經過無中心、零侵入的方案提供與數據庫交互的的齧合層,即Database Mesh,又可稱數據網格。 Database Mesh的關注重點在於如何將分佈式的數據訪問應用與數據庫有機串聯起來,它更加關注的是交互,是將雜亂無章的應用與數據庫之間的交互有效的梳理。使用Database Mesh,訪問數據庫的應用和數據庫終將造成一個巨大的網格體系,應用和數據庫只需在網格體系中對號入座便可,它們都是被齧合層所治理的對象。
優勢:
分佈式雲原生的數據庫中間件模式,集成了jdbc和proxy各自的優勢,能知足高可用、跨語言、無感知升級等多種優點特性
缺點:
須要總體架構支持雲原生體系
目前還沒正式上線。
這個層次實際上不該該叫數據庫中間件了,須要更換存儲。
好比Aurora、polardb、tidb等分佈式數據庫,經過計算節點和存儲節點分離,計算節點scale up,存儲節點scale out的理念將公有云的關係數據庫產品推向了一個新的高度。
這樣一來,實際上已經再也不須要傳統的數據庫中間件了,一切問題自然就不存在了。
從上文能夠了解到,目前最主流的數據庫中間件主要是從驅動層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爲主。
咱們從功能維度,來對比一下幾個產品。
從上文的分析能夠看出,儘管目前主流的數據庫中間件仍是在smart-client和proxy兩個層面進行處理的,可是,已經能看到將來的方向了。雲原生的到來,估計會作進一步的降維打擊。
一方面是做爲sidecar的模式,可能會有一個新的階段,好比shardingsphere推出sidecar模式後。
而另外一方面,雲數據庫經過全新的計算存儲分離的架構方式,打破傳統關係型數據庫的性能瓶頸,傳統數據庫中間件將再也不須要關注,一切都將以數據庫基礎設施的形式提供給使用者。
看到這裏了,原創不易,點個關注、點個贊吧,你最好看了~
知識碎片從新梳理,構建Java知識圖譜:https://github.com/saigu/JavaKnowledgeGraph(歷史文章查閱很是方便)
掃碼關注個人公衆號「阿丸筆記」,第一時間獲取最新更新。同時能夠免費獲取海量Java技術棧電子書、各個大廠面試題。