數(shù)據(jù)庫治理利器:動態(tài)讀寫分離
背景
在分布式系統(tǒng)架構(gòu)中,業(yè)務(wù)的流量都是端到端的。每個請求都會經(jīng)過很多層處理,比如從入口網(wǎng)關(guān)再到 Web Server 再到服務(wù)之間的調(diào)用,再到服務(wù)訪問緩存或 DB 等存儲。
對于我們的系統(tǒng)來說,數(shù)據(jù)庫是非常重要的一塊。因此無論是在穩(wěn)定性的治理上,還是在開發(fā)提效等場景下,數(shù)據(jù)庫相關(guān)的治理能力都是我們系統(tǒng)所需具備的能力。下面總結(jié)了微服務(wù)訪問數(shù)據(jù)庫層時,在數(shù)據(jù)庫治理中的常見的一些場景與能力。
OpenSergo 領(lǐng)域中關(guān)于數(shù)據(jù)庫治理的概覽
本文將介紹 MSE 服務(wù)治理最近推出數(shù)據(jù)庫治理利器:無侵入實現(xiàn)數(shù)據(jù)庫訪問的讀寫分離能力。
什么是讀寫分離?
讀寫分離也就是將數(shù)據(jù)庫拆分為主庫和從庫,即主庫負(fù)責(zé)處理事務(wù)性的增刪改操作,從庫負(fù)責(zé)處理查詢操作的數(shù)據(jù)庫架構(gòu)。
為什么要讀寫分離?
穩(wěn)定性
一個大客戶的請求過來,查詢數(shù)據(jù)庫返回上萬條幾百 M 的數(shù)據(jù),數(shù)據(jù)庫的 CPU 直接打滿。不知道大家是否遇到過類似的問題。
性能
在業(yè)務(wù)處理過程中,如果對數(shù)據(jù)庫的讀操作遠(yuǎn)多于寫操作,同時業(yè)務(wù)上對于數(shù)據(jù)查詢結(jié)果的實時性要求不高(例如可以容忍秒級的延遲),那么在做系統(tǒng)性能優(yōu)化時就可以考慮引入讀寫分離的方案,只讀庫可以承擔(dān)主庫的壓力,有效提升微服務(wù)應(yīng)用的性能。
規(guī)模增長
隨著業(yè)務(wù)增長,到了一定規(guī)模之后再擴容,但很多都卡在擴容這一步,極大的限制了應(yīng)對市場變化的速度,其中數(shù)據(jù)庫的擴容是最難的,目前常見的數(shù)據(jù)庫擴容方式有以下幾種方式:
- 垂直升級
- 分庫分表
- 讀寫分離
垂直升級需要中斷服務(wù)且高可用方面不及其它幾種方式,分庫分表在分區(qū)鍵的選擇上會是個難點,SQL 使用上會有諸多限制,同時對業(yè)務(wù)的改造也是非常大的工作量。相對來說讀寫分離是對業(yè)務(wù)的侵入最低也最容易實現(xiàn)擴容方案。根據(jù)經(jīng)驗大多數(shù)應(yīng)用的讀寫比都在 5:1 以上,有些場景甚至大量的高于 10:1,在對數(shù)據(jù)庫有少量寫請求,但有大量讀請求的應(yīng)用場景下,單個實例可能無法承受讀取壓力,甚至對業(yè)務(wù)產(chǎn)生影響。
綜上所述數(shù)據(jù)庫讀寫分離方案可以滿足阿里云上大多數(shù)公司的穩(wěn)定性治理、性能提升以及數(shù)據(jù)庫擴容的需求。
讀寫分離常見方案
目前業(yè)界流行的讀寫分離方案,通常都是基于上述主從模式的數(shù)據(jù)庫架構(gòu)。讀寫分離的實現(xiàn)方案多數(shù)是通過引入 odp、mycat 等數(shù)據(jù)訪問代理產(chǎn)品,通過其讀寫分離功能來幫助實現(xiàn)讀寫分離。引入數(shù)據(jù)訪問代理的好處是源程序不需要做任何改動就可以實現(xiàn)讀寫分離,壞處是由于多了一層中間件做中轉(zhuǎn)代理,性能上會有所下降,數(shù)據(jù)訪問代理也容易成為性能瓶頸。
ShardingSphere 讀寫分離方案[1](摘自 shardingsphere 官網(wǎng))
ShardingSphere[2] 的讀寫分離主要依賴內(nèi)核的相關(guān)功能。包括解析引擎和路由引擎。解析引擎將用戶的 SQL 轉(zhuǎn)化為 ShardingSphere 可以識別的 Statement 信息,路由引擎根據(jù) SQL 的讀寫類型以及事務(wù)的狀態(tài)來做 SQL 的路由。如下圖所示,ShardingSphere 識別到讀操作和寫操作,分別會路由至不同的數(shù)據(jù)庫實例。
MSE 數(shù)據(jù)庫讀寫分離能力
MSE 提供了一種動態(tài)數(shù)據(jù)流量治理的方案,您可以在不需要修改任何業(yè)務(wù)代碼的情況下,實現(xiàn)數(shù)據(jù)庫的讀寫分離能力。下面介紹 MSE 基于 Mysql 數(shù)據(jù)存儲通過的讀寫分離能力。
前提條件
- 應(yīng)用接入 MSE
- 部署 Demo 應(yīng)用
在阿里云容器服務(wù)中部署 A、B、C 三個應(yīng)用,并且將應(yīng)用均接入 MSE 服務(wù)治理[3],用于增加具備數(shù)據(jù)庫治理能力的 Agent。
- 創(chuàng)建 RDS 只讀實例[4]
我們需要創(chuàng)建 RDS 只讀實例,利用只讀實例滿足大量的數(shù)據(jù)庫讀取需求,增加應(yīng)用的吞吐量。
配置讀寫分離規(guī)則
- 我們需要配置以下環(huán)境變量來額外開啟/配置數(shù)據(jù)庫的讀寫分離能力
- 我們可以通過控制臺配置弱讀請求的規(guī)則或者指定某些接口為弱讀請求
上述 OpenSergo 標(biāo)準(zhǔn)的規(guī)則表示 /getLocation 接口的請求為弱讀請求。
我們針對一些大數(shù)據(jù)量查詢、對延時不太敏感的業(yè)務(wù)請求可以配置為 weak 類型
SQL 洞察
如上只需輕松的兩步我們就實現(xiàn)了數(shù)據(jù)庫的讀寫分離能力。基于數(shù)據(jù)庫讀寫分離能力,配合 MSE 數(shù)據(jù)庫治理的 SQL 洞察我們可以快速定位 RT 過大的查詢請求,幫助我們進(jìn)一步分析 SQL 對我們數(shù)據(jù)庫穩(wěn)定性的影響。
我可以觀察應(yīng)用和資源 API 維度的 SQL 請求實時數(shù)據(jù)(細(xì)化至秒級),同時 MSE 還提供了 SQL 的 topN 列表,我們可以一眼看出 RT 高,查詢返回值數(shù)據(jù)量大的 SQL 語句。
總結(jié)
本文詳細(xì)描述了 MSE 即將推出的數(shù)據(jù)庫治理能力矩陣中關(guān)于動態(tài)讀寫分離能力的介紹。通過 MSE 提供的 SQL 洞察能力,結(jié)合我們對業(yè)務(wù)的理解,我們可以快速定位劃分接口請求為弱請求。將對主庫性能以及穩(wěn)定性影響大的讀操作,分流至 RDS 只讀庫,可以有效降低主庫的讀寫壓力,進(jìn)一步提升微服務(wù)應(yīng)用的穩(wěn)定性。
我們從應(yīng)用的視角出發(fā),抽象了我們在訪問以及使用數(shù)據(jù)庫時的一些常見場景以及對應(yīng)的治理能力,整理了我們在穩(wěn)定性治理、性能優(yōu)化、提效等方面的實戰(zhàn)經(jīng)驗。對于每一個后端應(yīng)用來說,數(shù)據(jù)庫無疑是重中之重,我們希望通過我們的數(shù)據(jù)庫治理能力,可以幫助到大家更好地使用數(shù)據(jù)庫服務(wù)。
最后提一下服務(wù)治理的標(biāo)準(zhǔn) OpenSergo:
Q:OpenSergo[5] 是什么
A:OpenSergo 是一套開放、通用的、面向分布式服務(wù)架構(gòu)、覆蓋全鏈路異構(gòu)化生態(tài)的服務(wù)治理標(biāo)準(zhǔn),基于業(yè)界服務(wù)治理場景與實踐形成服務(wù)治理通用標(biāo)準(zhǔn)。OpenSergo 最大特點就是以統(tǒng)一一套配置/DSL/協(xié)議定義服務(wù)治理規(guī)則,面向多語言異構(gòu)化架構(gòu),做到全鏈路生態(tài)覆蓋。無論微服務(wù)的語言是 Java, Go, Node.js 或其它語言,無論是標(biāo)準(zhǔn)微服務(wù)或 Mesh 接入,從網(wǎng)關(guān)到微服務(wù),從數(shù)據(jù)庫到緩存,從服務(wù)注冊發(fā)現(xiàn)到配置,開發(fā)者都可以通過同一套 OpenSergo CRD 標(biāo)準(zhǔn)配置針對每一層進(jìn)行統(tǒng)一的治理管控,而無需關(guān)注各框架、語言的差異點,降低異構(gòu)化、全鏈路服務(wù)治理管控的復(fù)雜度