傳統的MySql讀寫分離方案是通過在代碼中根據SQL語句的類型動态切換資料源來實作的,那麼有沒有什麼中間件可以自動實作讀寫分離呢?小米開源的資料庫中間件Gaea就可以實作,接下來我們将詳細講解如何使用Gaea來實作MySql的讀寫分離。
Gaea簡介
Gaea是小米中國區電商研發部研發的基于MySql協定的資料庫中間件,目前在小米商城大陸和海外得到廣泛使用,包括訂單、社群、活動等多個業務。Gaea支援分庫分表、SQL路由、讀寫分離等基本特性,其中分庫分表方案相容了mycat和kingshard兩個項目的路由方式。
MySql主從複制
使用Gaea需要依賴MySql的主從複制環境,關于MySql的主從複制可以參考:MySql主從複制,從原理到實踐!
直接在Linux下安裝
目前官方提供的是在Linux下直接安裝的方式,我們先按此方法來安裝Gaea。
安裝Go語言環境
由于Gaea是使用Go語言編寫的,是以我們需要先安裝Go語言的環境。
- 安裝Go語言環境,下載下傳位址:https://golang.org/dl/

- 下載下傳完成後解壓到
目錄下;/mydata
tar -zxvf go1.13.5.linux-amd64.tar.gz -C /mydata/
複制
- 添加
目錄到PATH變量中:/mydata/go/bin
# 編輯環境變量配置檔案
vim /etc/profile
# 在最後一行添加
export GOROOT=mydata/go
export PATH=$PATH:$GOROOT/bin
# 重新整理配置檔案
source /etc/profile
複制
- 檢視版本号,測試是否安裝成功:
go version
複制
- 傳回以下資訊表示Go語言環境已經安裝成功了:
go version go1.13.5 linux/amd64
複制
安裝Gaea
由于Gaea并沒有提供安裝包,是以我們需要自行編譯源碼擷取可執行檔案。
- 下載下傳Gaea的源碼,直接下載下傳
包即可,下載下傳位址:https://github.com/XiaoMi/Gaeazip
- 将下載下傳好的壓縮包進行解壓操作,這裡我們解壓到
目錄下:/mydata/gaea/
unzip Gaea-master.zip
複制
- 進入
目錄下,使用/mydata/gaea/
指令對源碼編譯:make
make build
複制
-
:由于網絡問題,某些Go的依賴會下載下傳不下來導緻編譯失敗,多嘗試幾次即可成功;注意
- 編譯完成後在
目錄下會生成Gaea的執行檔案/mydata/gaea/bin
:gaea
- 由于我們沒有搭建
配置中心,是以需要修改本地配置檔案etcd
,将配置類型改為/mydata/gaea/etc/gaea.ini
:file
; 配置類型,目前支援file/etcd兩種方式,file方式不支援熱加載
config_type=file
複制
- 添加namespace配置檔案,用于配置我們的主從資料庫資訊,配置檔案位址:
/mydata/gaea/etc/file/namespace/mall_namespace_1.json
- 配置檔案内容如下:
{
"name": "mall_namespace_1",
"online": true,
"read_only": false,
"allowed_dbs": {
"mall": true
},
"slow_sql_time": "1000",
"black_sql": [
""
],
"allowed_ip": null,
"slices": [
{
"name": "slice-0",
"user_name": "root",
"password": "root",
"master": "192.168.6.132:3307",
"slaves": ["192.168.6.132:3308"],
"statistic_slaves": null,
"capacity": 12,
"max_capacity": 24,
"idle_timeout": 60
}
],
"shard_rules": null,
"users": [
{
"user_name": "macro",
"password": "123456",
"namespace": "mall_namespace_1",
"rw_flag": 2,
"rw_split": 1,
"other_property": 0
}
],
"default_slice": "slice-0",
"global_sequences": null
}
複制
namespace配置檔案
namespace的配置格式為json,包含分表、非分表、執行個體等配置資訊,都可在運作時改變。
- 整體配置說明:
- slice配置:
- users配置:
在Docker容器中運作
由于官方隻提供了Linux下直接安裝運作的方式,這裡我們提供另一種運作方式,在Docker容器中作為服務運作。
打包成Docker鏡像
Docker Hub 中并沒有打包好的Gaea鏡像,我們需要自行建構一個,下面詳細介紹下如何建構Gaea的Docker鏡像。
- 這裡我們使用Dockerfile建構Docker鏡像,Dockerfile中的内容如下:
# 該鏡像需要依賴的基礎鏡像
FROM golang:latest
# 将目前目錄下的gaea源碼包複制到docker容器的/go/Gaea-master目錄下,對于.tar.gz檔案會自動解壓
ADD Gaea-master.tar.gz /go/Gaea-master
# 将解壓後的源碼移動到/go/gaea目錄中去
RUN bash -c 'mv /go/Gaea-master/Gaea-master /go/gaea'
# 進入/go/gaea目錄
WORKDIR /go/gaea
# 将gaea源碼進行打包編譯
RUN bash -c 'make build'
# 聲明服務運作在13306端口
EXPOSE 13306
# 指定docker容器啟動時執行的指令
ENTRYPOINT ["/go/gaea/bin/gaea"]
# 指定維護者的名字
MAINTAINER macrozheng
複制
- 在此之前我們需要把Gaea的源碼壓縮包轉換為
格式友善在Docker容器中的解壓,可以使用.tar.gz
來實作:壓縮軟體
- 之後使用Docker指令建構Gaea的Docker鏡像:
docker build -t gaea:1.0.2 .
複制
- 建構成功控制台輸出:
- 将本地安裝的Gaea配置檔案複制到
目錄下:/mydata/gaea-docker/etc/
cp -r /mydata/gaea/etc/ /mydata/gaea-docker/etc/
複制
- 使用Docker指令啟動Gaea容器:
docker run -p 13306:13306 --name gaea \
-v /mydata/gaea-docker/etc:/go/gaea/etc \
-d gaea:1.0.2
複制
測試讀寫分離
測試思路:首先我們關閉從執行個體的主從複制,然後通過Gaea代理來操作資料庫,插入一條資料,如果主執行個體中有這條資料而從執行個體中沒有,說明寫操作是走的主庫。然後再通過Gaea代理查詢該表資料,如果沒有這條資料,表示讀操作走的是從庫,證明讀寫分離成功。
- 通過Navicat連接配接到Gaea代理,注意此處賬号密碼為Gaea的namespace中配置的内容,端口為Gaea的服務端口;
- 通過Navicat分别連接配接到主庫和從庫,用于檢視資料,此時建立了以下三個資料庫連接配接;
- 通過
指令關閉stop slave
執行個體的主從複制功能:mysql-slave
- 通過Gaea代理在
表中插入一條資料:test
- 在主庫中檢視
表的資料,發現已有該資料:test
- 在從庫中檢視
表的資料,發現沒有該資料,證明寫操作走的是主庫:test
- 直接在代理中檢視
表中的資料,發現沒有該資料,證明讀操作走的是從庫。test
結合SpringBoot使用
在我們的SpringBoot應用中,我們隻需要把Gaea的代理服務直接當做資料庫服務來使用就可以實作讀寫分離了。這樣就不用在代碼中添加任何讀寫分離邏輯了,是不是很友善!
參考資料
更多資料請參考官方文檔:https://github.com/XiaoMi/Gaea
推薦閱讀
- 推薦一款 IDEA 插件!解決Maven依賴沖突的好幫手!
- MySql主從複制,從原理到實踐!
- Spring 最常用的 7 大類注解,史上最強整理!
- 2020=1024+996,996之年,程式員要如何應對!
- 當下流行的NIO架構,一篇搞懂!
- 前後端分離項目,如何優雅實作檔案存儲!
- 2019 我的 Github 開源之路!
- Github标星25K+Star,SpringBoot實戰電商項目mall出SpringCloud版本啦!
- 涵蓋大部分核心元件使用的 Spring Cloud 教程,一定要收藏哦!
- 我的Github開源項目,從0到20000 Star!