當前位置:
首頁 > 科技 > Service Mesh是大方向,那Database Mesh呢?

Service Mesh是大方向,那Database Mesh呢?

接收程序員的 8 點技術早餐

作者|張亮

編輯|郭蕾

出處丨聊聊架構

在微服務和雲原生大潮的卷席之下,服務化一直以來是人們關注的重點。但服務化之後,真正繞不開的數據訪問卻鮮有論道。儘管目前的關係型資料庫遠達不到雲原生的要求,並且對分散式的不友好在長期以來也飽受詬病,但不可否置的是,關係型資料庫至今依然扮演著極其重要的角色。

從其本身以及周邊生態圈的成熟度、數據查詢的靈活度、開發工程師以及 DBA 對其的掌控程度以及招聘到適合人員的難易度等方面來看,無論是 NoSQL 還是 NewSQL,實難於在近期完全取而代之。

那麼,對於微服務架構中越來越多的資料庫垂直拆分,以及數據量急劇膨脹後的資料庫水平拆分,是否存在行之有效的方案來管理呢?當今大為流行的 Service Mesh 理念又能否對資料庫的治理帶來一些啟示呢?

Database Mesh

Database Mesh,一個搭乘 Service Mesh 浪潮衍生出來的新興辭彙。顧名思義,Database Mesh 使用一個嚙合層,將散落在系統各個角落中的資料庫統一治理起來。通過嚙合層集中在一起的應用與資料庫之間的交互網路,就像蜘蛛網一樣複雜而有序。

從這一點來看,Database Mesh 的概念與 Service Mesh 如出一轍。之所以稱其為 Database Mesh,而非 Data Mesh,是因為它的首要目標並非嚙合存儲於資料庫中的數據,而是嚙合應用與資料庫間的交互。

Database Mesh 的關注重點在於如何將分散式的數據訪問應用與資料庫有機串聯起來,它更加關注的是交互,是將雜亂無章的應用與資料庫之間的交互有效的梳理。

使用 Database Mesh,訪問資料庫的應用和資料庫終將形成一個巨大的網格體系,應用和資料庫只需在網格體系中對號入座即可,它們都是被嚙合層所治理的對象。

Service Mesh 回顧

服務治理主要關注服務發現、負載均衡、動態路由、降級熔斷、調用鏈路以及 SLA 採集等非功能性需求。通常來說,可以通過代理端和客戶端這兩種架構方案實現。

代理端的方案是基於網關的。提供服務的應用伺服器被隱藏在網關之後,訪問請求必須經由網關,由網關進行相應的服務治理動作後,再將流量路由至後端應用。Nginx、Kong、Kubernetes Ingress 等採用此類方案。

客戶端的方案則是由部署在應用端的類庫進行相應的服務治理動作,並以點對點的方式訪問服務提供者。Dubbo、Spring Cloud 等採用此種方案。

無論使用代理端還是客戶端進行服務治理,都有其各自的優缺點。

在代理端進行服務治理的優點是應用只需獲取網關地址即可,後端的複雜部署結構被完全屏蔽。缺點則是代理端自身的性能和可用性是整個系統的瓶頸,一旦宕機後果較為嚴重。其中心化架構理念,與雲原生背道而馳。

在客戶端進行服務治理的優點是使用無中心化架構,無需擔心某個節點成為系統瓶頸。缺點則是服務治理對業務代碼的侵入。對於雲原生所看重的零侵入來說,使用客戶端進行服務治理的方式顯然是不可行的。客戶端治理的方案更無法做到對異構語言的支持。

在既希望零入侵、又需要無中心的雲原生架構下,第三種架構模型——Sidecar 則顯得更加契合。Sidecar 以一個獨立的進程啟動,可以每台宿主機共用同一個 Sidecar 進程,也可以每個應用獨佔一個 Sidecar 進程。

所有的服務治理功能,都由 Sidecar 接管,應用的對外訪問僅需要訪問 Sidecar 即可。顯而易見,基於 Sidecar 模式的 Service Mesh 才是雲原生架構的更好的實現方式,零侵入和無中心化使得 Service Mesh 倍受推崇。

尤其是配合 Mesos 或 Kubernetes 一起使用時,通過 Marathon 或 DeamonSet 確保 Sidecar 在每個宿主機都能夠啟動,再配合其對容器的動態調度能力,能發揮更大的威力。Kubernetes(Mesos) + Service Mesh = 彈性伸縮 + 零侵入 + 無中心,它們合力完成了一個雲端所需的基礎設施。

二者異同

資料庫應用治理與服務治理的目標既有重疊,又有所不同。相比於服務,資料庫是有狀態的,無法像服務一樣隨意路由到對等節點,因此數據分片是一個重要的能力。相對來說,資料庫實例的自動發現能力則不那麼重要,原因也是資料庫的有狀態性,啟動或停止一個新的資料庫實例,往往意味著數據遷移。當然也可以採用多數據副本、讀寫分離、主庫多寫等方式進行進一步的處理。其他功能諸如對多從庫的負載均衡、熔斷、鏈路採集等,在資料庫治理中也同樣適用。

與服務治理一樣,對資料庫應用的治理同樣可以套用這三種架構方案。

基於代理端的解決方案是使用一個實現相應資料庫通信協議(如 MySQL)的代理伺服器。Cobar、MyCAT、kingshard 以及即將推出的 Sharding-JDBC-Server 等採用此種方案。基於客戶端的解決方案則必須與開發語言強綁定,例如 Java 語言一般可以通過 JDBC 或某個 ORM 框架來實現。TDDL 和 Sharding-JDBC 等採用此種方案。

同理,無論是代理端還是客戶端,都有各自的優缺點。代理端的優點是異構語言的支持,缺點依然是中心化架構。客戶端的優點是無中心化架構,缺點則是無法支持異構語言,因此,對各種資料庫的命令行以及圖形界面的客戶端便無法有效支持。

採用 Sidecar 模式,同樣可以有效的結合代理端與客戶端的優點,並屏蔽其缺點。但是,基於服務治理的 Sidecar 和基於資料庫訪問的 Sidecar 是一樣的么?當然不是。最主要的不同在於數據分片。

分片是一個複雜的過程,如果希望做到對應用透明,業界常見的做法是針對 SQL 進行解析,並將其精準路由至相應的資料庫中執行,最終將執行結果進行歸併,以保證數據在分片的情況下邏輯仍然正確。

一個數據分片的核心流程是 SQL 解析 –> SQL 路由 –> SQL 改寫 –> SQL 執行 –> 結果歸併。為了滿足對遺留代碼的零侵入,還需要對 SQL 的執行協議進行封裝。比如,在代理端則需要模擬 MySQL 或其他相應資料庫的通信協議;在 Java 客戶端實現,則需要覆蓋 JDBC 介面的相應方法。

說了很多,那麼當前是否有 Database Mesh 的實現方案呢?遺憾的是,目前還沒有。即使是流行度很廣的 Service Mesh,它的各個產品也都還是在成熟的路上。

出現稍早的 Linkerd 和 Envoy 雖然可以在生產環境使用,但新一代的 Istio 以更加宏偉的構圖吸引著業界的眼球,只是目前還無法用於生產環境。Database Mesh 作為 Service Mesh 的延展,則更是處於發展的萌芽狀態。

Sharding-JDBC

Sharding-JDBC 於 2016 年由噹噹開源。最初,它是一個在 Java 的 JDBC 層實現分庫分表的資料庫中間層。今年,京東金融雲決定將 Sharding-JDBC 作為其核心的對外輸出。

那麼,Sharding-JDBC 勢必要進行革新,面對雲端,Database Mesh 無疑是正確的發展方向。Sharding-JDBC 決定實現 Sidecar 版本,期望可以成為一個純粹的雲原生資料庫中間層產品。

目標

Sharding-JDBC 的終極目標是像使用一個資料庫一樣透明的使用散落在各個系統中的資料庫。讓應用開發者和 DBA 儘可能順暢地將其工作遷移至基於 Sharding-JDBC 的雲原生環境中。Sharding-JDBC 希望提供一個無中心化、零侵入以及跨語言的雲原生解決方案。

演進歷程

Sharding-JDBC 一直以來,以 JDBC 層分片作為其核心理念。它的架構圖如下:

它分為分片模塊、柔性事務模塊以及資料庫治理模塊。作為其核心的分片模塊完整的實現了 SQL 解析、路由、改寫、執行和歸併的過程。但是,作為一個立志服務於雲原生架構的產品,僅在 JDBC 層提供服務是遠遠不夠的。

Sharding-JDBC 將分別實現 Driver、Server 以及 Sidecar 這三個不同的版本,一起組成 Sharding-JDBC 的生態圈,為不同的需求與環境提供更加具有針對性的差異化服務。近期,Sharding-JDBC 將發布其 Server 版本。在不久的將來,Sharding-JDBC 的 Sidecar 版本也將投入開發。原有的 Sharding-JDBC 將重命名為 Sharding-JDBC-Driver。由於分片的核心功能已經實現完畢,因此架構模型的調整並不複雜,Sharding-JDBC-Server 的核心代碼仍然使用 Sharding-JDBC 的原有分片邏輯,只是在外圍包裝了 MySQL 協議,未來也將提供其他資料庫的兼相關容協議。架構圖如下:

由於 Sharding-JDBC-Server 的出現,使得原來 DBA 通過 Sharding-JDBC-Driver 無法對數據進行操作的缺憾得到了補償。由於 Sharding-JDBC-Driver 無需通過代理層進行二次轉發,因此線上性能更佳,可以通過以下的混合部署方案使用 Sharding-JDBC:

線上應用使用 Sharding-JDBC-Driver 直連資料庫以獲取最優性能,使用 MySQL 命令行或 UI 客戶端連接 Sharding-JDBC-Server 方便的查詢數據和執行各種 DDL 語句。它們使用同一個註冊中心集群,通過管理端配置註冊中心中的數據,即可由註冊中心自動將配置變更推送至 Driver 和 Server 應用。若資料庫拆分的過多而導致連接數會暴漲,則可以考慮直接在線上使用 Sharding-JDBC-Server,以達到有效控制連接數的目的。

在不久的將來,Sharding-JDBC-Sidecar 也將問世,它的部署架構是這樣的:

基於 Sharding-JDBC 的 Database Mesh 與 Service Mesh 互不干擾,相得益彰。服務之間的交互由 Service Mesh Sidecar 接管,基於 SQL 的資料庫訪問由 Sharding-JDBC-Sidecar 接管。

對於業務應用來說,無論是 RPC 還是對資料庫的訪問,都無需關注其真實的物理部署結構,做到真正的零侵入。由於 Sharding-JDBC-Sidecar 是隨著宿主機的生命周期創建和消亡的,

因此,它並非靜態 IP,而是完全動態和彈性的存在,整個系統中並無任何中心節點的存在。對於數據運維等操作,仍然可以通過啟動一個 Sharding-JDBC-Server 的進程作為靜態 IP 的入口,通過各種命令行或 UI 客戶端進行操作。

撥開 Sharding-JDBC 的迷霧

Sharding-JDBC 自誕生以來,使用手冊已經比較完善。但由於它一直處於高速發展的狀態中,因此很少對外披露其內部的實現細節。雖然代碼都是開源的,但要求技術人員在選型時將第三方的代碼都通讀一遍,顯然是不現實的。篇幅有限,本文無法將 Sharding-JDBC 的所有源碼從頭到尾分析一遍,但可以對常見的疑問給予解答。

1. Sharding-JDBC 的 SQL 解析是如何做的,效率是否有問題?

回答:Sharding-JDBC 採用詞法 + 語法解析的方式解析 SQL,先將 SQL 拆成一個個詞根,再根據 SQL 語法配合其上下文進行語法解析。Sharding-JDBC 的 SQL 解析並不會產生 AST(抽象語法樹),而是直接將分片所需的解析上下文提煉出來,如:Tables、Select Items、Conditions、Order Items、Group By Items、Limit 等。並直接將解析上下文應用於路由,免去了對 AST 的二次遍歷,進一步提升了性能。Sharding-JDBC 的一個較為複雜的 SQL 解析大約需要 10ms,相對於 JSqlParser 等基於 JavaCC 的 SQL 解析器,性能會快數倍甚至十倍以上。

2. Sharding-JDBC 對於分頁、排序和分組等查詢,是否需要將數據全部取到內存中進行操作,這樣內存是否會被撐爆?

回答: Sharding-JDBC 使用流式歸併和內存歸併兩種歸併方式,流式歸併是完全不佔用內存的,其原理與 JDBC 的 ResultSet 一樣,每調用一次 next,數據的游標會下移一位;而內存歸併是需要佔用內存的,會將 ResultSet 中所有的數據全部取出放入內存才能進行歸併。可能與大部分人的想像不同,Sharding-JDBC 僅在一種情況下才會使用內存歸併,即 ORDER BY 與 GROUP BY 同時存在且排序不一致時。

而 LIMIT、僅 ORDER BY、僅 GROUP BY 以及 ORDER BY 與 GROUP BY 同時存在但順序相同的情況下,都是流式歸併,不會佔用額外內存。具體的實現細節在本文中無法詳盡說明,以後會有更多的文章另行分析。總之,Sharding-JDBC 在內核方面做了大量優化。

具不完全統計,已經有幾十甚至上百家公司在使用 Sharding-JDBC,這其中不乏一些知名企業。在逐漸撥開迷霧的同時,希望 Sharding-JDBC 能夠為技術選型者帶來充足的信心。

未來規劃

2018 年的 Sharding-JDBC 仍將是快速發展一年。未來的規劃重點在以下四個方面:

雲原生。Sharding-JDBC-Driver 已經比較成熟,Sharding-JDBC-Server 即將於近期發布,Sharding-JDBC-Sidecar 也將於近期提上日程。Sharding-JDBC 將全面擁抱這三種架構模型。讓其在雲原生架構中熠熠生輝。

SQL 兼容性。目前 Sharding-JDBC 的 SQL 內核支持除了子查詢和 OR 之外的絕大部分 DQL、DML、DDL、DCL 以及 MySQL 的 admin 等相關語句。作為一個資料庫產品的最核心模塊,Sharding-JDBC 也將加大對子查詢和 OR 的支持力度,爭取支持盡量多的 SQL,真正的達到對遺留代碼的最大限度兼容。

功能閉環。資料庫中間層關注的重點是數據分片、分散式事務和資料庫治理這三方面。Sharding-JDBC 在數據分片方面涉獵較多,其餘兩方面則是分身乏術。未來,在完善數據分片的同時,也會逐漸對其他兩個方面加強投入。Database Mesh 是對數據訪問層和資料庫兩個部分的治理,目前的 Sharding-JDBC 對資料庫治理這塊的功能還有待展開。分散式事務這塊,Sharding-JDBC 也會對柔性事務進行改進,通過解析 binlog 的方式自動回滾數據。

鏈路採集。Sharding-JDBC 目前已經支持 opentracing 協議,並獲得其官方的首肯。與另外一個 APM 知名項目 SkyWalking 也完成了集成,可以通過 SkyWalking 直接查看和分析 Sharding-JDBC 的調用鏈路。對於京東金融雲的另一個核心產品分散式服務跟蹤平台 SGM(Service Governance And Monitoring)也會進行整合,使得京東金融雲提供更加一體化的對外服務。更多 SGM 的官方信息將於近期披露。

如果讀者對 Sharding-JDBC 感興趣,歡迎訪問 GitHub:

https://github.com/shardingjdbc。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 InfoQ 的精彩文章:

介於公有雲與私有雲之間 專有雲緣何興起?
從理論到實踐,理解微服務關鍵問題

TAG:InfoQ |