一起聊聊Mycat實現 Mysql 叢集讀寫分離

2022-01-21 19:00:44
本篇文章給大家介紹了關於MySQL讀寫分離的相關知識,希望對大家有幫助。

MySQL 讀寫分離的概述

  • MySQL 作為目前世界上使用最廣泛的免費資料庫,相信所有從事系統運維的工程師都一定接觸過。

  • 在實際的生產環境中,由單臺 MySQL 作為獨立的資料庫是完全不能滿足實際需求的,無論是在安全性,高可用性以及高並行等各個方面。

  • 因此,一般來說都是通過主從複製(Master-Slave)的方式來同步資料,再通過讀寫分離(MySQL-Proxy/Amoeba)來提升資料庫的並行負載能力進行部署與實施。

讀寫分離工作原理

  • 基本的原理是:

  • 主資料庫處理事務性增、改、刪操作(INSERT、UPDATE、DELETE)

  • 從資料庫處理 SELECT 查詢操作

  • 資料庫複製被用來把事務性操作導致的變更同步到叢集中的從資料庫。

為什麼要讀寫分離

  • 面對越來越大的存取壓力,單臺的伺服器的效能成為瓶頸,需要分擔負載

  • 主從只負責各自的寫和讀,極大程度的緩解 X(寫)鎖和 S(讀)鎖爭用

  • 從庫可設定 myisam 引擎,提升查詢效能以及節約系統開銷

  • 增加冗餘,提高可用性

實現讀寫分離的方式

  • 一般有兩種方式實現
  • 應用程式層實現,網站的程式實現
  • 應用程式層實現指的是在應用程式內部及聯結器中實現讀寫分離

  • 優點:

  • 應用程式內部實現讀寫分離,安裝既可以使用

  • 減少一定部署難度

  • 存取壓力在一定級別以下,效能很好

  • 缺點:

  • 架構一旦調整,程式碼要跟著變

  • 難以實現高階應用,如自動分庫,分表

  • 無法適用大型應用場景

中介軟體層實現:

  • 中介軟體層實現是指在外部中介軟體程式實現讀寫分離

  • 常見的中介軟體程式

  • Cobar:

  • 阿里巴巴 B2B 開發的關係型分散式系統,管理將近 3000 個 MySQL 範例。 在阿里經受住了考驗,後面由於作者的走開的原因 cobar 沒有人維護 了,阿里也開發了 tddl 替代 cobar。

  • MyCAT:

  • 社群愛好者在阿里 cobar 基礎上進行二次開發,解決了 cobar 當時存在的一些問題,並且加入了許多新的功能在其中。目前 MyCAT 社群活躍度很高,已經有一些公司在使用 MyCAT。總體來說支援度比

  • 較高,也會一直維護下去。

  • OneProxy:

  • 資料庫界大牛,前支付寶資料庫團隊領導樓總開發,基於 mysql 官方 的 proxy 思想利用 c 進行開發的,OneProxy 是一款商業收費的中介軟體,樓總捨去了一些功能點,專注在效能和穩定性上。有人測

  • 試過說在高並行下很穩定。

  • Vitess:

  • 這個中介軟體是 Youtube 生產在使用的,但是架構很複雜。 與以往中介軟體不同,使用 Vitess 應用改動比較大,要使用他提供語言的 API 介面,我們可以借鑑他其中的一些設計思想。

  • Kingshard:

  • Kingshard 是前 360Atlas 中介軟體開發團隊的陳菲利用業餘時間 用 go 語言開發的,目前參與開發的人員有 3 個左右, 目前來看還不是成熟可以使用的產品,需要在不斷完善。

  • Atlas:

  • 360 團隊基於 mysql proxy 把 lua 用 C 改寫。原有版本是支援分表, 目前已經放出了分庫分表版本。在網上看到一些朋友經常說在高並行下會經常掛掉,如果大家要使用需要提前做好測試。

  • MaxScale 與 MySQL Route:

  • 這兩個中介軟體都算是官方的,MaxScale 是 mariadb (MySQL 原作者維護的一個版本)研發的,目前版本不支援分庫分表。MySQL Route 是現在 MySQL 官方 Oracle 公司釋出出來的一箇中介軟體。

  • 優點:

  • 架構設計更靈活

  • 可以在程式上實現一些高階控制,如:透明化水平拆分,failover,監控可以依靠技術手段提高 mysql 效能對業務程式碼的影響小,同時也安全

  • 缺點:

  • 需要一定的開發運維團隊的支援。


什麼是 MyCAT

  • 一個徹底開源的,面向企業應用開發的巨量資料庫叢集

  • 支援事務、ACID、可以替代 MySQL 的加強版資料庫

  • 一個可以視為 MySQL 叢集的企業級資料庫,用來替代昂貴的 Oracle 叢集

  • 一個融合記憶體快取技術、NoSQL 技術、HDFS 巨量資料的新型 SQL Server

  • 結合傳統資料庫和新型分散式資料倉儲的新一代企業級資料庫產品

  • 一個新穎的資料庫中介軟體產品


MyCat 服務安裝與設定

  • MyCat 有提供編譯好的安裝包,支援 Windows、Linux、Mac、Solaris 等系統上安裝與執行

  • 官方下載主頁 http://www.mycat.org.cn/

  • 實驗架構:
  • 192.168.2.2 Mycat CentOS 8.3.2011
  • 192.168.2.3 主伺服器 CentOS 7.6
  • 192.168.2.5 從伺服器 CentOS 7.6
  • 執行 Mycat 需要JDK 1.7 或者以上版

  • 下載 Mycat
  • wget http://dl.mycat.org.cn/1.6.7.6/20210303094759/Mycat-server-1.6.7.6-release-20210303094759-linux.tar.gz
  • tar xf Mycat-server-1.6.7.6-release-20210303094759-linux.tar.gz -C /usr/local/
  • sudo useradd -M -N -s /sbin/nologin mycat && echo "123456" | sudo passwd --stdin mycat
  • sudo chown -R mycat. /usr/local/mycat/

  • bin 程式目錄,Linux 下執行:./mycat console,首先要 chmod +x *
    注:mycat 支援的命令{ console | start | stop | restart | status | dump }
    conf 目錄下存放組態檔:server.xml 是 Mycat 伺服器引數調整和使用者授權的組態檔,schema.xml 是邏輯庫定義和表以及分片定義的組態檔,rule.xml 是分片規則的組態檔,分片規則的具體一些引數資訊單獨存放為檔案,也在這個目錄下,組態檔修改,需要重新啟動 Mycat 生效。
    lib 目錄下主要存放 mycat 依賴的一些 jar 檔案。
    紀錄檔存放在 logs/mycat.log 中,每天一個檔案,紀錄檔的設定是在 conf/log4j.xml 中,根據自己的需要,可以調整輸出級別為 debug,在 debug 級別下,會輸出更多的資訊,方便排查問題。

MyCat 服務啟動與啟動設定

  • MyCAT 在 Linux 中部署啟動時,首先需要在 Linux 系統的環境變數中設定 MYCAT_HOME,操作方式如下:

  • sudo vim /etc/profile.d/mycat.sh
    MYCAT_HOME=/usr/local/mycat PATH=$MYCAT_HOME/bin:$PATH

  • 使環境變數生效

  • . /etc/profile.d/mycat.sh

  • 啟動服務
  • /usr/local/mycat/bin/mycat start
  • cat /usr/local/mycat/logs/wrapper.log

mycat 的使用者賬號和授權資訊是在 conf/server.xml 檔案中設定

  • vim /usr/local/mycat/conf/server.xml

  • 這裡定義的是在 192.168.2.2 上登陸 mycat 的使用者名稱和密碼,名稱可以自定義。192.168.2.2 上沒有執行 mysqld 服務,schemas裡面指定的資料庫名是伺服器端必須存在的資料庫!

編輯 MyCAT 的組態檔 schema.xml,關於 dataHost 的設定資訊如下:

  • 備份原先的組態檔
  • \cp /usr/local/mycat/conf/schema.xml{,.bak}
  • 編輯 組態檔
  • vim /usr/local/mycat/conf/schema.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mycat:schema SYSTEM "schema.dtd">
    <mycat:schema xmlns:mycat="http://io.mycat/"> 注意這裡的網址,錯寫會啟動失敗!
    <schema name="mydata" checkSQLschema="false" sqlMaxLimit="100" dataNode='dn1'>
    </schema>

    <dataNode name="dn1" dataHost="dthost" database="mydata"/>
    <dataHost name="dthost" maxCon="500" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="-1" slaveThreshold="100">
    <heartbeat>show slave status</heartbeat>
    <writeHost host="c7_2_3" url="192.168.2.3:3306" user="mycat" password="123456"> 寫伺服器
    </writeHost>
    <writeHost host="c7_2_5" url="192.168.2.5:3306" user="mycat" password="123456"> 讀伺服器
    </writeHost>

    </dataHost>
    </mycat:schema>

  • 強制所有的讀操作都在讀伺服器上執行,只有寫入資料時才切換到寫伺服器

  • 注意這裡的 mycat 使用者都要在 主從資料庫 上 192.168.2.3 和 2.5 授權

  • GRANT ALL PRIVILEGES ON *.* TO 'mycat'@'%' IDENTIFIED BY '123456';

  • 或者指定網段

  • GRANT ALL PRIVILEGES ON *.* TO 'mycat'@'192.168.2.%' IDENTIFIED BY '123456';

  • flush privileges;

  • 如果報這個錯誤,伺服器執行正常的話,首先檢查有沒有授權

  • ERROR 1184 (HY000): Invalid DataSource:0

  schema:邏輯庫,與MySQL中的Database(資料庫)對應,一個邏輯庫中定義了所包括的Table。
  table:表,即物理資料庫中儲存的某一張表,與傳統資料庫不同,這裡的表格需要宣告其所儲存的邏輯資料節點DataNode,這是通過表格的分片規則定義來實現的,table可以定義其所屬的「子表(childTable)」,子表的分片依賴於與「父表」的具體分片地址,簡單的說,就是屬於父表裡某一條記錄A的子表的所有記錄都與A儲存在同一個分片上。
分片規則:是一個欄位與函數的捆繫結義,根據這個欄位的取值來返回所在儲存的分片(DataNode)的序號,每個表格可以定義一個分片規則,分片規則可以靈活擴充套件,預設提供了基於數位的分片規則,字串的分片規則等。
  dataNode: MyCAT的邏輯資料節點,是存放table的具體物理節點,也稱之為分片節點,通過DataSource來關聯到後端某個具體資料庫上,一般來說,為了高可用性,每個DataNode都設定兩個DataSource,一主一從,當主節點宕機,系統自動切換到從節點。
  dataHost:定義某個物理庫的存取地址,用於捆綁到dataNode上。

MyCAT目前通過組態檔的方式來定義邏輯庫和相關設定:
  MYCAT_HOME/conf/schema.xml中定義邏輯庫,表、分片節點等內容;
  MYCAT_HOME/conf/rule.xml中定義分片規則;
  MYCAT_HOME/conf/server.xml中定義使用者以及系統相關變數,如埠等。

註解:
schema 標籤用於定義 MyCat 範例中的邏輯庫,name:後面就是邏輯庫名 MyCat 可以有多個邏輯庫,每個邏輯庫都有自己的相關設定。可以使用 schema 標籤來劃分這些不同的邏輯庫。
checkSQLschema 這個屬性預設就是 false,官方檔案的意思就是是否去掉表前面的資料庫的名稱,」select * from db1.testtable」 ,設定為 true 就會去掉 db1。但是如果 db1 的名稱不是
schema 的名稱,那麼也不會被去掉,因此官方建議不要使用這種語法。同時預設設定為 false。
sqlMaxLimit 當該值設定為某個數值時。每條執行的 SQL 語句,如果沒有加上 limit 語句,MyCat 也會自動的加上所對應的值。例如設定值為 100,執行」select * from test_table」,則效果為
「selelct * from test_table limit 100」.
dataNode 標籤定義了 MyCat 中的資料節點,也就是我們通常說所的資料分片

  • 重新啟動服務
  • /usr/local/mycat/bin/mycat restart
    Stopping Mycat-server...
    Stopped Mycat-server.
    Starting Mycat-server...
    tail /usr/local/mycat/logs/wrapper.log

設定 MySQL 主從

  • 在2臺伺服器上分別安裝、設定mariadb,具體步驟請參閱:https://blog.csdn.net/gaofei0428/article/details/103829676?spm=1001.2014.3001.5501
  • 首先在主資料庫端 192.168.2.3 編輯 /etc/my.cnf

  • /etc/my.cnf
    [mysqld]
    datadir=/var/lib/mysql
    socket=/var/lib/mysql/mysql.sock

    symbolic-links=0

    log-bin=/data/mysql/mysql-bin
    server-id=1
    binlog-ignore-db=mysql
    binlog-ignore-db=information_schema
    binlog-ignore-db=performance_schema
    binlog-ignore-db=test
    innodb_flush_log_at_trx_commit=1
    binlog-do-db=mydata
    replicate-do-db=mydata
  • lower_case_table_names=1 開啟大小寫匹配
  • 注意需要同步的資料庫必須事先存在

  • 啟動無誤後在然後在從伺服器 192.168.2.5 上設定 /etc/my.cnf

  • vim /etc/my.cnf  1
    [mysqld]
    datadir=/var/lib/mysql
    socket=/var/lib/mysql/mysql.sock

    symbolic-links=0

    log-bin=/data/mysql/mysql-bin
    server-id=2
    relay-log-index=/data/mysql/slave-relay-bin.index
    relay-log=/data/mysql/slave-relay-bin
    lower_case_table_names=1
  • read_only=1 開啟唯讀模式,防止資料回寫,不會影響 slave 同步複製
  • lower_case_table_names=1 開啟大小寫匹配

  • 重新啟動 從資料庫服務後進行以下操作
  • 停止從伺服器的slave,建立slave資料庫使用者
  • mysql -uroot -p123456 -e "stop slave"
    mysql -uroot -p123456 -e "grant replication slave on *.* to 'slave'@'%' identified by '123456'"
    mysql -uroot -p123456 -e "select user,password from mysql.user"

  • mysql -uroot -p123456 -e "change master to master_host='192.168.2.3',master_user='slave',master_password='123456',master_log_file='mysql-bin.000002',master_log_pos=245;"
    mysql -uroot -p123456 -e "start slave"
    mysql -uroot -p123456 -e "show slave status"

  • 測試

  • 首先匯出主伺服器 192.168.2.3 的所有庫的備份

  • mysqldump -uroot -p --all-databases > /tmp/all_dbs.sql

  • 然後在從伺服器 192.168.2.5 匯入

  • mysql -uroot -p < /tmp/all_dbs.sql

  • 在主資料庫端 192.168.2.3 新增一些資料,觀測從資料庫是否同步

  • 在從伺服器端檢視

  • 如果同步出錯,需要在從伺服器 stop slave,然後重新 change master

  • 使用 slave 使用者登陸測試


  • 回到 mycat 伺服器 192.168.2.2

  • 嘗試登陸
  • mysql -uroot -p123456 -h192.168.2.2 -P8066
  • 8066 為 mycat 執行時的埠號

  • 測試讀寫分離

  • mysql -uroot -p123456 -h192.168.2.2 -P9066 -e "show @@datasource"
  • 9066為 mycat 管理埠
  • select * from mydata.mylist;

  • 寫入資料或者更改資料

  • insert into mydata.mylist values(10,'test');

  • 模擬故障,首先停止 從伺服器 192.168.2.5

  • systemctl stop mariadb.service

  • 在 192.168.2.2 上嘗試寫入資料
  • insert into mydata.mylist values(7,'gf');

  • 在 主伺服器 192.168.2.3 上檢視

  • 開啟 從伺服器 192.168.2.5

  • 模擬 主伺服器 192.168.2.3 宕機

  • 查詢正常,嘗試寫入資料

  • 查詢正常但是不能寫入


  • 新增多個庫
  • vim cat /usr/local/mycat/conf/server.xml
  • <!--多個庫指定標籤用逗號隔開 -->
    <property name="schemas">mydata,wordpress</property>

  • vim /usr/local/mycat/conf/schema.xml
  • <schema name="wordpress" checkSQLschema="false" sqlMaxLimit="100" dataNode='dn2'>
    </schema>
  • <dataNode name="dn2" dataHost="dthost1" database="wordpress"/>

  • 新增完重新啟動服務
  • /usr/local/mycat/bin/mycat restart
  • tail /usr/local/mycat/logs/wrpper.log


  • 報錯處理
    Startup failed: Timed out waiting for a signal from the JVM.
    JVM did not exit on request, terminated

    解決辦法
    在wrapper.conf中新增
    wrapper.startup.timeout=300 //超時時間300秒
    wrapper.ping.timeout=120

推薦學習:

以上就是一起聊聊Mycat實現 Mysql 叢集讀寫分離的詳細內容,更多請關注TW511.COM其它相關文章!