SpringBoot實戰電商項目mall(25k+star)地址:github.com/macrozheng/…mysql
傳統的MySql讀寫分離方案是經過在代碼中根據SQL語句的類型動態切換數據源來實現的,那麼有沒有什麼中間件能夠自動實現讀寫分離呢?小米開源的數據庫中間件Gaea就能夠實現,接下來咱們將詳細講解如何使用Gaea來實現MySql的讀寫分離。linux
Gaea是小米中國區電商研發部研發的基於MySql協議的數據庫中間件,目前在小米商城大陸和海外獲得普遍使用,包括訂單、社區、活動等多個業務。Gaea支持分庫分表、SQL路由、讀寫分離等基本特性,其中分庫分表方案兼容了mycat和kingshard兩個項目的路由方式。git
使用Gaea須要依賴MySql的主從複製環境,關於MySql的主從複製能夠參考:MySql主從複製,從原理到實踐!github
目前官方提供的是在Linux下直接安裝的方式,咱們先按此方法來安裝Gaea。golang
因爲Gaea是使用Go語言編寫的,因此咱們須要先安裝Go語言的環境。sql
/mydata
目錄下;tar -zxvf go1.13.5.linux-amd64.tar.gz -C /mydata/
複製代碼
/mydata/go/bin
目錄到PATH變量中:# 編輯環境變量配置文件
vim /etc/profile
# 在最後一行添加
export GOROOT=mydata/go
export PATH=$PATH:$GOROOT/bin
# 刷新配置文件
source /etc/profile
複製代碼
go version
複製代碼
go version go1.13.5 linux/amd64
複製代碼
因爲Gaea並無提供安裝包,因此咱們須要自行編譯源碼獲取可執行文件。docker
下載Gaea的源碼,直接下載zip
包便可,下載地址:github.com/XiaoMi/Gaea數據庫
將下載好的壓縮包進行解壓操做,這裏咱們解壓到/mydata/gaea/
目錄下:json
unzip Gaea-master.zip
複製代碼
/mydata/gaea/
目錄下,使用make
命令對源碼編譯:make build
複製代碼
注意
:因爲網絡問題,某些Go的依賴會下載不下來致使編譯失敗,多嘗試幾回便可成功;vim
編譯完成後在/mydata/gaea/bin
目錄下會生成Gaea的執行文件gaea
:
etcd
配置中心,因此須要修改本地配置文件/mydata/gaea/etc/gaea.ini
,將配置類型改成file
:; 配置類型,目前支持file/etcd兩種方式,file方式不支持熱加載
config_type=file
複製代碼
/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的配置格式爲json,包含分表、非分表、實例等配置信息,均可在運行時改變。
總體配置說明:
字段名稱 | 字段類型 | 字段含義 |
---|---|---|
name | string | namespace名稱 |
online | bool | 是否在線,邏輯上下線使用 |
read_only | bool | 是否只讀,namespace級別 |
allowed_dbs | map | 容許經過代理訪問的數據庫 |
default_phy_dbs | map | 默認數據庫名, 與allowed_dbs一一對應 |
slow_sql_time | string | 慢sql時間,單位ms |
black_sql | string數組 | 黑名單sql |
allowed_ip | string數組 | 白名單IP |
slices | map數組 | 一主多從的物理實例,slice裏map的具體字段可參照slice配置 |
shard_rules | map數組 | 分庫、分表、特殊表的配置內容,具體字段可參照shard配置 |
users | map數組 | 應用端鏈接gaea所須要的用戶配置,具體字段可參照users配置 |
slice配置:
字段名稱 | 字段類型 | 字段含義 |
---|---|---|
name | string | 分片名稱,自動、有序生成 |
user_name | string | 數據庫用戶名 |
password | string | 數據庫密碼 |
master | string | 主實例地址 |
slaves | string數組 | 從數據庫地址,能夠配置多個 |
statistic_slaves | string數組 | 統計型從實例地址列表 |
capacity | int | gaea_proxy與每一個實例的鏈接池大小 |
max_capacity | int | gaea_proxy與每一個實例的鏈接池最大大小 |
idle_timeout | int | gaea_proxy與後端mysql空閒鏈接存活時間,單位:秒 |
users配置:
字段名稱 | 字段類型 | 字段含義 |
---|---|---|
user_name | string | 數據庫代理用戶名,客戶端經過該用戶名訪問 |
password | string | 數據庫代理密碼,客戶端經過該用戶名訪問 |
namespace | string | 對應的命名空間 |
rw_flag | int | 讀寫標識, 只讀=1, 讀寫=2 |
rw_split | int | 是否讀寫分離, 非讀寫分離=0, 讀寫分離=1 |
other_property | int | 目前用來標識是否走統計從實例, 普通用戶=0, 統計用戶=1 |
因爲官方只提供了Linux下直接安裝運行的方式,這裏咱們提供另外一種運行方式,在Docker容器中做爲服務運行。
Docker Hub 中並無打包好的Gaea鏡像,咱們須要自行構建一個,下面詳細介紹下如何構建Gaea的Docker鏡像。
# 該鏡像須要依賴的基礎鏡像
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
複製代碼
.tar.gz
格式方便在Docker容器中的解壓,能夠使用壓縮軟件
來實現:docker build -t gaea:1.0.2 .
複製代碼
/mydata/gaea-docker/etc/
目錄下:cp -r /mydata/gaea/etc/ /mydata/gaea-docker/etc/
複製代碼
docker run -p 13306:13306 --name gaea \
-v /mydata/gaea-docker/etc:/go/gaea/etc \
-d gaea:1.0.2
複製代碼
測試思路:首先咱們關閉從實例的主從複製,而後經過Gaea代理來操做數據庫,插入一條數據,若是主實例中有這條數據而從實例中沒有,說明寫操做是走的主庫。而後再經過Gaea代理查詢該表數據,若是沒有這條數據,表示讀操做走的是從庫,證實讀寫分離成功。
stop slave
命令關閉mysql-slave
實例的主從複製功能:test
表中插入一條數據:test
表的數據,發現已有該數據:test
表的數據,發現沒有該數據,證實寫操做走的是主庫:test
表中的數據,發現沒有該數據,證實讀操做走的是從庫。在咱們的SpringBoot應用中,咱們只須要把Gaea的代理服務直接當作數據庫服務來使用就能夠實現讀寫分離了。這樣就不用在代碼中添加任何讀寫分離邏輯了,是否是很方便!
更多資料請參考官方文檔:github.com/XiaoMi/Gaea
mall項目全套學習教程連載中,關注公衆號第一時間獲取。