天天看點

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

傳統的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/           

複制

  • 添加

    /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并沒有提供安裝包,是以我們需要自行編譯源碼擷取可執行檔案。
  • 下載下傳Gaea的源碼,直接下載下傳

    zip

    包即可,下載下傳位址:https://github.com/XiaoMi/Gaea
  • 将下載下傳好的壓縮包進行解壓操作,這裡我們解壓到

    /mydata/gaea/

    目錄下:
unzip Gaea-master.zip           

複制

  • 進入

    /mydata/gaea/

    目錄下,使用

    make

    指令對源碼編譯:
make build           

複制

  • 注意

    :由于網絡問題,某些Go的依賴會下載下傳不下來導緻編譯失敗,多嘗試幾次即可成功;
  • 編譯完成後在

    /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,包含分表、非分表、執行個體等配置資訊,都可在運作時改變。
  • 整體配置說明:
你還在代碼裡做讀寫分離麼,試試這個中間件吧!
  • 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的源碼壓縮包轉換為

    .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的代理服務直接當做資料庫服務來使用就可以實作讀寫分離了。這樣就不用在代碼中添加任何讀寫分離邏輯了,是不是很友善!

參考資料

更多資料請參考官方文檔: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!