譚鵬 朱艷輝 楊蕓樺
摘要:目前互聯(lián)網(wǎng)公司數(shù)據(jù)吞吐量急速上升,傳統(tǒng)的單一數(shù)據(jù)庫服務器架構(gòu)已經(jīng)不再滿足需求。當數(shù)據(jù)庫服務器出現(xiàn)性能瓶頸問題時,僅靠增加服務器性能無法從根本上解決問題,因此需要水平擴展,即將數(shù)據(jù)庫水平擴展到多臺服務器。實現(xiàn)水平擴展的軟件就叫數(shù)據(jù)訪問層中間件,該文采用分布式架構(gòu)設計了兩種數(shù)據(jù)訪問層中間件:客戶端數(shù)據(jù)庫中間件和服務端數(shù)據(jù)庫中間件。使用Java語言進行開發(fā),數(shù)據(jù)庫用的是使用最廣的關(guān)系型數(shù)據(jù)庫MySQL。實現(xiàn)了數(shù)據(jù)庫的分庫分表、讀寫分離等操作,提升了數(shù)據(jù)訪問層的響應速度以及數(shù)據(jù)訪問層的系統(tǒng)穩(wěn)定性。
關(guān)鍵詞:數(shù)據(jù)庫中間件;分庫分表;讀寫分離;限流;MySQL協(xié)議
中圖分類號:TP391 文獻標識碼:A 文章編號:1009-3044(2018)24-0007-03
Abstract: At present the Internet company data throughput grew rapidly, the traditional single database server architecture is no longer meet the demand.When the database server performance bottleneck problems, only by increasing server performance can not fundamentally solve the problem, so you need to scale, the database level extended to multiple servers.Realize the scale of software is called the data access layer middleware, this paper adopts distributed architecture design for two kinds of data access layer middleware: client database middleware and the server database middleware.Using Java language development, database is the most widely use relational database MySQL.Separation for depots table, the database to read and write operations, improve the response speed of the data access layer and data access layer of the system stability.
Key words: Database Middleware; Sharding; Read Write splitting; current-limiting; MySQL protocol
目前互聯(lián)網(wǎng)公司數(shù)據(jù)吞吐量急速上升,傳統(tǒng)的單一數(shù)據(jù)庫服務器架構(gòu)已經(jīng)無法滿足需求。單一數(shù)據(jù)庫服務器的架構(gòu)方式在遇到系統(tǒng)訪問量急劇上升時很容易出現(xiàn)響應速度變慢甚至數(shù)據(jù)庫服務器宕機的情況。如何提升系統(tǒng)數(shù)據(jù)訪問層的響應速度以及如何提升數(shù)據(jù)庫這一層的穩(wěn)定性成為我們急需解決的難題,數(shù)據(jù)庫中間件就是解決上述問題的核心技術(shù)。數(shù)據(jù)庫中間件具有削峰的能力[1],需要像MySQL一樣支持事務操作[1]。
分布式數(shù)據(jù)層中間件(DDLM)把業(yè)務邏輯層的每條SQL語句(下文記作邏輯 SQL 語句)按照垂直、水平拆分的策略解釋成多個SQL語句,解釋后的每條 SQL 語句(下文記作物理 SQL 語句)對一個數(shù)據(jù)源進行操作,從而一條邏輯 SQL語句被解釋成多條物理SQL語句,因此DDLM具有分布式的特性[2]。
數(shù)據(jù)庫中間件在業(yè)界主要有兩種做法,一個是將其部署到客戶端,這種架構(gòu)形式叫作客戶端數(shù)據(jù)庫中間件,另外一種是將其單獨部署在服務器集群上,這種架構(gòu)形式叫作服務端數(shù)據(jù)庫中間件。本文對兩種架構(gòu)形式進行了對比分析設計和實現(xiàn)。
1 系統(tǒng)功能分析
1.1 分庫分表(Sharding)
分庫分表是數(shù)據(jù)庫中間件最為核心的需求,主要包括分庫、分表以及分庫分表等。要求對原計劃發(fā)往一個數(shù)據(jù)庫的SQL請求進行盡可能均勻的分片,使其發(fā)往不同的數(shù)據(jù)庫分片。從而降低單庫的性能瓶頸,提高數(shù)據(jù)訪問層的響應速度。
分庫分表分為垂直切分和水平切分,切分的內(nèi)容又包括數(shù)據(jù)表和數(shù)據(jù)庫。垂直分庫和垂直分表需在業(yè)務端處理,不屬于數(shù)據(jù)庫中間件的范疇。垂直分庫是指將按照業(yè)務模塊來劃分出不同的數(shù)據(jù)庫,而不是像早期一樣將所有的數(shù)據(jù)表都放到同一個數(shù)據(jù)庫中。垂直分表是指將表結(jié)構(gòu)按照字段的常用與不常用進行切分,讓一個表切分成多個表,這樣做的好處在于有些大的字段并非經(jīng)常使用的字段,將其分開之后可以極大地提升數(shù)據(jù)訪問的效率。水平分表是指維持數(shù)據(jù)的表結(jié)構(gòu)不變,按照某個特定的字段采取哈希等方式讓其水平切分到多個表結(jié)構(gòu)相同的表當中。
以上的切分方法各有各自的優(yōu)缺點,所以一般會將其混合使用。目前最常見的方式為水平分庫分表,所謂的水平分庫分表是指在水平分表的基礎(chǔ)上,讓各子表按照一定的規(guī)則劃分到不同的數(shù)據(jù)庫分片當中,讓多個數(shù)據(jù)庫分片同時承擔訪問壓力,這樣就解決了水平分表無法解決單一數(shù)據(jù)庫分片的瓶頸問題,也就提升了數(shù)據(jù)訪問的速度。
1.2 讀寫分離
讀寫分離是數(shù)據(jù)庫中間件的第二核心功能,主要是指在數(shù)據(jù)訪問層將讀操作和寫操作進行分離。所有的寫操作進入master庫,所有的讀操作進入slave庫。主庫和從庫之間采用BinLog的形式進行數(shù)據(jù)同步。這樣做的好處在于:提高數(shù)據(jù)訪問層的響應速度、極大程度的緩解X鎖和S鎖爭用、由于從庫只負責讀,所以可以將從庫的MySQL存儲引擎配置成MyISAM,提升查詢效率、增加冗余,提高系統(tǒng)的可用性。
1.3 限流
在業(yè)務高峰期,整個系統(tǒng)的負載迅速上升,數(shù)據(jù)庫的壓力變大,這時候很容易造成大流量沖擊數(shù)據(jù)庫從而導致數(shù)據(jù)庫響應速度過慢甚至出現(xiàn)宕機等現(xiàn)象,這會嚴重影響用戶體驗。數(shù)據(jù)庫中間件可以做到在數(shù)據(jù)訪問層進行限流操作,利用訪問數(shù)據(jù)庫之前先拿到數(shù)據(jù)庫信號量的形式使得流量以可控的狀態(tài)通往數(shù)據(jù)訪問層下層的數(shù)據(jù)庫層,從而起到限流以及保護數(shù)據(jù)庫的作用。
2 系統(tǒng)設計與實現(xiàn)
2.1 技術(shù)介紹
本系統(tǒng)采用Java語言進行開發(fā),采用了分布式架構(gòu),數(shù)據(jù)庫采用MySQL數(shù)據(jù)庫??蛻舳藬?shù)據(jù)庫中間件以重寫JDBC接口的形式進行實現(xiàn),服務端數(shù)據(jù)庫中間件依賴Netty NIO線程池以及MySQL協(xié)議解析操作進行實現(xiàn)。其中服務端涉及MySQL的三次握手以及報文解析等操作。
目前業(yè)界對于數(shù)據(jù)庫中間件有兩種部署形式,一種是將其部署在客戶端,叫作客戶端數(shù)據(jù)庫中間件,一種是將其部署在服務端,叫作服務端數(shù)據(jù)庫中間件。
2.2 客戶端數(shù)據(jù)庫中間件
客戶端數(shù)據(jù)庫中間件是指將系統(tǒng)打包到公司的maven倉庫當中,所有需要使用的應用程序以依賴導入的形式將其加載進來,然后進行數(shù)據(jù)庫切片以及切片路由規(guī)則的配置就可以直接使用了??蛻舳藬?shù)據(jù)庫中間件的優(yōu)點在于無需單獨部署到服務器集群,節(jié)約了大量的硬件成本。且它的研發(fā)較服務端數(shù)據(jù)庫中間件來說比較簡單,無需涉及MySQL的報文解析等底層操作。但這種形式無法做到數(shù)據(jù)訪問服務的集中管理,且監(jiān)控和升級服務也會十分的不方便。
客戶端數(shù)據(jù)庫中間件的整體流程圖如圖1所示。
2.3.1 配置模塊
配置模塊主要采用Spring schema擴展技術(shù),將對象的創(chuàng)建以xml配置的形式注入Spring容器當中,使得系統(tǒng)部分與功能部分進行大幅度的解耦。
核心步驟為:
1) 編寫自定義類;
2) 編寫schema來描述自定義元素;
3) 編寫Handler ;
4) 編寫Parser;
5) 編寫META-INF/spring.handlers,META-INF/spring.schemas文件對Handler和schema進行注冊。
2.3.2 實現(xiàn)JDBC核心接口
重寫JDBC接口方法是客戶端數(shù)據(jù)庫中間件最核心的一個功能模塊。Sharding、讀寫分離都需要依靠JDBC接口方法重寫進行攔截。本系統(tǒng)主要實現(xiàn)的接口有DataSource接口、Connection接口、Statement接口以及PreparedStatement接口。
2.3.3 分庫分表
分庫分表是本系統(tǒng)最核心的一個功能模塊,主要負責的是將原始的SQL請求進行拆分,使得原計劃通往一個數(shù)據(jù)庫的SQL請求盡可能均勻地切分到不同的分表中,然后分表按照一定的規(guī)則對應不同的數(shù)據(jù)庫分片。讓原本只會發(fā)往一個數(shù)據(jù)庫分片的SQL請求盡可能均勻的發(fā)送到不同的數(shù)據(jù)庫分片中,從而提升系統(tǒng)的響應速度。
2.4 服務端數(shù)據(jù)庫中間件
服務端數(shù)據(jù)庫中間件是指將數(shù)據(jù)庫中間件作為一種服務進行單獨部署。服務端數(shù)據(jù)庫中間件介于客戶端與數(shù)據(jù)庫之間,是數(shù)據(jù)庫的一種代理,用戶可以像使用MySQL一樣使用我們。其中涉及MySQL底層協(xié)議的分析及解析。服務端數(shù)據(jù)庫中間件的優(yōu)點在于支持多語言的應用,不管是Java應用還是Python應用,只要它使用的數(shù)據(jù)庫是MySQL數(shù)據(jù)庫,都可以直接使用我們的服務。但客戶端數(shù)據(jù)庫無法做到這點,客戶端數(shù)據(jù)庫需針對每種語言重寫一套新的接口才能實現(xiàn)多語言的支持。服務端數(shù)據(jù)庫中間件的第二個優(yōu)點在于可以集中管理,監(jiān)控和升級服務也很方便。初次之外,服務端數(shù)據(jù)庫中間件還可以很好地在數(shù)據(jù)訪問層做到數(shù)據(jù)庫的限流操作。缺點在于需單獨部署到服務器集群中,所以存在硬件成本開銷。
服務端數(shù)據(jù)庫中間件的整體流程圖如圖2所示。
2.4.1 系統(tǒng)架構(gòu)說明
服務端數(shù)據(jù)庫中間件是實現(xiàn)MySQL協(xié)議的一種MySQL代理,服務端數(shù)據(jù)庫中間件在接入之后,客戶端無需直連數(shù)據(jù)庫。這種情形下,系統(tǒng)必須考慮高并發(fā)的情況。本系統(tǒng)分為前端和后端,前端后端各啟了一個Netty的NIO線程池,前端負責數(shù)據(jù)庫中間件服務與上層客戶端的通信,后端負責數(shù)據(jù)庫中間件服務于下層數(shù)據(jù)庫之間的通信。
服務端數(shù)據(jù)庫中間件的系統(tǒng)架構(gòu)圖如圖3所示。
2.4.2 分庫分表
與客戶端數(shù)據(jù)庫中間件的分庫分表模塊類似,服務端數(shù)據(jù)庫最核心的功能也是實現(xiàn)數(shù)據(jù)庫的分片操作。將原始的SQL請求進行拆分,使得原計劃通往一個數(shù)據(jù)庫的SQL請求盡可能均勻地切分到不同的數(shù)據(jù)庫分片當中,從而提升系統(tǒng)的響應速度。
2.4.3 讀寫分離
讀寫分離的核心思想是在數(shù)據(jù)訪問層將通往MySQL的請求按照讀寫進行分類,分為讀操作和寫操作。且所有的MySQL數(shù)據(jù)庫分片都自帶一個叫作role的屬性,role可以是master也可以是slave。
將上述兩項內(nèi)容綜合起來就是我們讀寫分離模塊的架構(gòu)了:所有的寫操作全都路由到role為master的數(shù)據(jù)庫分片當中,所有的讀操作都路由到role為slave的數(shù)據(jù)庫分片當中。
將讀寫操作進行分開之后,我們可以將所有的slave分庫的MySQL存儲引擎配置成MyISAM,這樣會提升查詢速度,從而提升數(shù)據(jù)訪問層的響應速度。
3 結(jié)語
本文對數(shù)據(jù)庫中間件進行了一個系統(tǒng)的描述,且按照客戶端數(shù)據(jù)庫中間件和服務端數(shù)據(jù)庫中間件對其分別進行了設計和實現(xiàn),比較了它們各自的優(yōu)缺點。
無論是客戶端數(shù)據(jù)庫中間件還是服務端數(shù)據(jù)庫中間件,都可以很好的提升數(shù)據(jù)訪問層的響應速度,降低單節(jié)點的負載,提升系統(tǒng)的穩(wěn)定性。
兩種數(shù)據(jù)庫中間件的對比:
(1) 客戶端數(shù)據(jù)庫中間件針對不同語言需開發(fā)一套系統(tǒng);
(2) 客戶端數(shù)據(jù)庫中間件在升級時不方便統(tǒng)一管理,不方便監(jiān)控;
(3) 客戶端數(shù)據(jù)庫中間件無需單獨部署,節(jié)約了成本;
(4) 服務端數(shù)據(jù)庫中間件支持多語言;
(5) 服務端數(shù)據(jù)庫中間件在擴展數(shù)據(jù)庫類型時,僅需實現(xiàn)一次數(shù)據(jù)庫協(xié)議;
(6) 服務端數(shù)據(jù)庫中間件需部署到物理服務器,成本較大;
(7) 服務端數(shù)據(jù)庫中間件方便系統(tǒng)升級以及系統(tǒng)打點監(jiān)控;
(8) 服務端數(shù)據(jù)庫中間件是MySQL的一種代理,很方便做到限流
數(shù)據(jù)庫中間件可以極大程度提升數(shù)據(jù)訪問層的響應速度,降低數(shù)據(jù)庫節(jié)點的負載,提高系統(tǒng)的穩(wěn)定性,因此具有很高的經(jīng)濟價值,推廣價值和應用價值。
參考文獻:
[1] 漆紹洋.基于mysql的分布式訪問中間件中sql處理模塊的設計與實現(xiàn)[D].南京:南京大學,2016:26-29.
[2] 李文杰,周劍華.分布式應用層中間件的設計[J]. 微型機與應用, 2011,30(5): 14-16.
[3] 肖戈林.HTTP協(xié)議技術(shù)探析[J].江西通信科技,2001(1):20-27.
[4] MySQL網(wǎng)絡協(xié)議分析[EB/OL]. https://www.colabug.com/1957195.html.
[5] 祝雄鋒.數(shù)據(jù)庫集群中間件MySQL Proxy研究與分析[D].武漢理工大學,2011.
【通聯(lián)編輯:梁書】