你還在代碼裏作讀寫分離麼,試試這個中間件吧!

SpringBoot實戰電商項目mall(25k+star)地址:github.com/macrozheng/…mysql

摘要

傳統的MySql讀寫分離方案是經過在代碼中根據SQL語句的類型動態切換數據源來實現的,那麼有沒有什麼中間件能夠自動實現讀寫分離呢?小米開源的數據庫中間件Gaea就能夠實現,接下來咱們將詳細講解如何使用Gaea來實現MySql的讀寫分離。linux

Gaea簡介

Gaea是小米中國區電商研發部研發的基於MySql協議的數據庫中間件,目前在小米商城大陸和海外獲得普遍使用,包括訂單、社區、活動等多個業務。Gaea支持分庫分表、SQL路由、讀寫分離等基本特性,其中分庫分表方案兼容了mycat和kingshard兩個項目的路由方式。git

MySql主從複製

使用Gaea須要依賴MySql的主從複製環境,關於MySql的主從複製能夠參考:MySql主從複製,從原理到實踐!github

直接在Linux下安裝

目前官方提供的是在Linux下直接安裝的方式,咱們先按此方法來安裝Gaea。golang

安裝Go語言環境

因爲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語言環境已經安裝成功了:
go version go1.13.5 linux/amd64
複製代碼

安裝Gaea

因爲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
複製代碼
  • 添加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,包含分表、非分表、實例等配置信息,均可在運行時改變。

  • 總體配置說明:

    字段名稱 字段類型 字段含義
    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

在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的源碼壓縮包轉換爲.tar.gz格式方便在Docker容器中的解壓,能夠使用壓縮軟件來實現:

  • 以後使用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的代理服務直接當作數據庫服務來使用就能夠實現讀寫分離了。這樣就不用在代碼中添加任何讀寫分離邏輯了,是否是很方便!

參考資料

更多資料請參考官方文檔:github.com/XiaoMi/Gaea

公衆號

mall項目全套學習教程連載中,關注公衆號第一時間獲取。

公衆號圖片
相關文章
相關標籤/搜索