使用Mycat構建MySQL讀寫分離、主從複製、主從高可用

數據庫讀寫分離對於大型系統或者訪問量很高的互聯網應用來講,是必不可少的一個重要功能。 

從數據庫的角度來講,對於大多數應用來講,從集中到分佈,最基本的一個需求不是數據存儲的瓶頸,而是在於計算的瓶頸,即SQL查詢的瓶頸,咱們知道,正常狀況下,Insert SQL就是幾十個毫秒的時間內寫入完成,而系統中的大多數Select SQL則要幾秒到幾分鐘纔能有結果,不少複雜的SQL,其消耗服務器CPU的能力超強,不亞於死循環的威力。在沒有讀寫分離的系統上,極可能高峯時段的一些複雜SQL查詢就致使數據庫服務器CPU爆表,系統陷入癱瘓,嚴重狀況下可能致使數據庫崩潰。所以,從保護數據庫的角度來講,咱們應該儘可能避免沒有主從複製機制的單節點數據庫。html

環境

最低環境需求

MySQL 5.5及以上
Java JDK 7及以上

主服務器環境

CentOS 7.4.1708
MySQL 5.6.40
Java JDK 10.0.1
Mycat 1.6

從服務器環境

CentOs 7.2.1511
MySQL 5.6.35

安裝

主服務器安裝

安裝MySQL

本人使用的環境爲自動部署上去的,其中已包含Mysql,因此關於MySQL 的單獨安裝請你們參考網上的教程。java

安裝Java JDK

下載地址:http://www.oracle.com/technetwork/java/javase/downloads/index.htmlmysql

 

點擊 DOWNLOADlinux

贊成協議,點擊下載。sql

登陸服務器,建立 Java JDK 安裝目錄shell

mkdir /usr/local/java

上傳 JDK 至目錄數據庫

解壓 JDK 至當前目錄express

tar -zxvf jdk-10.0.1_linux-x64_bin.tar.gz

編輯配置文件,配置環境變量apache

vim /etc/profile

添加以下內容:JAVA_HOME根據實際目錄來
JAVA_HOME=/usr/local/java/jdk-10.0.1
CLASSPATH=$JAVA_HOME/lib/
PATH=$PATH:$JAVA_HOME/bin
export PATH JAVA_HOME CLASSPATH

重啓機器vim

sudo shutdown -r now

查看安裝狀況

java -version

安裝Mycat

MyCAT有提供編譯好的安裝包,支持windows、Linux、Mac、Solaris等系統上安裝與運行。

下載地址:http://dl.mycat.io/

這裏我選擇下載1.6版本:Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz

上傳 Mycat 至服務器 /usr/local

解壓 Mycat 至當前目錄

tar -zxvf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz

移動安裝包至 mycat 文件夾

mv Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz /usr/local/mycat/

建立用戶並設置

useradd Mycat
chown -R Mycat.Mycat /usr/local/mycat/
passwd Mycat

mycat 文件夾目錄說明

/usr/local/mycat
├── bin
├── catlet
├── conf
├── lib
├── logs
└── version.txt

目錄解釋以下:

bin 程序目錄,存放了window版本和linux版本,除了提供封裝成服務的版本以外,也提供了nowrap的shell腳本命令,方便你們選擇和修改,進入到bin目錄:

Linux下運行:./mycat console,首先要chmod +x *

注:mycat支持的命令{ console | start | stop | restart | status | dump }

conf目錄下存放配置文件,server.xml是Mycat服務器參數調整和用戶受權的配置文件,schema.xml是邏輯庫定義和表以及分片定義的配置文件,rule.xml是分片規則的配置文件,分片規則的具體一些參數信息單獨存放爲文件,也在這個目錄下,配置文件修改,須要重啓Mycat或者經過9066端口reload.

lib目錄下主要存放mycat依賴的一些jar文件.

日誌存放在logs/mycat.log中,天天一個文件,日誌的配置是在conf/log4j.xml中,根據本身的須要,能夠調整輸出級別爲debug,debug級別下,會輸出更多的信息,方便排查問題.

注意:Linux下部署安裝MySQL,默認不忽略表名大小寫,須要手動到/etc/my.cnf 下配置 lower_case_table_names=1 使Linux環境下MySQL忽略表名大小寫,不然使用MyCAT的時候會提示找不到表的錯誤!

增長環境變量

MyCAT在Linux中部署啓動時,首先須要在Linux系統的環境變量中配置MYCAT_HOME,操做方式以下:

vi /etc/profile

在文件中增長
export MYCAT_HOME=/usr/local/mycat

刷新環境變量

source /etc/profile

Mycat 集羣配置

若是是在多臺Linux系統中組建的MyCAT集羣,那須要在MyCAT Server所在的服務器上配置對其餘ip和主機名的映射,配置方式以下:

vi /etc/hosts

例如:我有4臺機器,配置以下:

IP 主機名:

192.168.100.2 sam_server_1

192.168.100.3 sam_server_2

192.168.100.4 sam_server_3

192.168.100.5 sam_server_4

編輯完後,保存文件。

啓動 Mycat

通過以上兩個步驟的配置,就能夠到 /usr/local/Mycat/bin 目錄下執行:(先不要動配置文件)

./mycat start

便可啓動mycat服務!

注:mycat支持的命令{ console | start | stop | restart | status | dump }

初次執行可使用 ./mycat console 命令執行,這樣有失敗信息直接就能顯示出來。

檢驗執行是否成功可使用 ./mycat status 

開放端口

若是開啓防火牆須要開放8066/9066端口,9066和8066分別偵聽管理員和應用程序的鏈接請求。

vim /etc/sysconfig/iptables

添加:
-A INPUT -p tcp -m state --state NEW -m tcp --dport 8066 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 9066 -j ACCEPT

重啓 iptables
systemctl restart iptables.service

從服務器安裝

從服務器主要用到的是 MySQL,環境爲自動部署上去的,其中已包含Mysql,因此關於MySQL 的單獨安裝請你們參考網上的教程。

配置MySQL主從複製

配置mysql端主從的數據自動同步,mycat不負責任何的數據同步問題。

關於 MySQL 主從複製的介紹我很少贅述,其中優缺點有興趣的能夠查閱相關資料。主要複製方式:

  • 基於SQL語句的複製(statement-based replication, SBR),
  • 基於行的複製(row-based replication, RBR),
  • 混合模式複製(mixed-based replication, MBR)。

基於SQL語句的方式最古老的方式,也是目前默認的複製方式,後來的兩種是MySQL 5之後纔出現的複製方式。

主服務器配置

登陸MySQL,建立一個同步帳號,並分配用戶權限

CREATE USER 'AiMasterSlave'@'%' IDENTIFIED BY '123456';

GRANT REPLICATION SLAVE ON *.* TO 'AiMasterSlave'@'%';

修改/etc/my.cnf

server-id = 2 # 每臺服務器標識要惟一,不要設置爲0,爲0會拒絕全部連接

log_bin = mysql-bin

重啓Mysql

service mysqld restart

登陸MySQL,查看二進制日誌

show master status;

記錄下來,一會要用到。

檢查3306端口是否開放,若是沒開放,開放端口,參考上面打開8066端口方法

從服務器配置

先彆着急配置,嘗試遠程連接主服務器,檢驗一下

mysql -h192.168.1.45 -uAiMasterSlave -p123456

若是不能連接,請檢驗主服務器用戶配置

修改/etc/my.cnf

server-id = 1
replicate_wild_do_table=master_slave_test.% # 同步庫
replicate_wild_ignore_table=mysql.% # 排除庫

重啓Mysql

service mysqld restart

登陸MySQL

stop slave;

CHANGE MASTER TO
MASTER_HOST='192.168.1.45',
MASTER_USER='AiMasterSlave',
MASTER_PASSWORD='123456',
MASTER_LOG_FILE='mysql-bin.000013',
MASTER_LOG_POS=680;

start slave;

查看狀態

show slave status \G;

若是上面兩處都爲 Yes 說明配置就沒問題。爲 NO 或者 connecting 請檢查配置和防火牆設置是否準確。

測試主從複製

 

我在主服務器寫的數據,從服務器會自動同步,說明配置生效。

配置Mycat讀寫分離

關於 Mycat 的詳細配置說明,請到官網去查閱文檔,太多了我就不搬過來了。資料下載:百度雲

server.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- - - Licensed under the Apache License, Version 2.0 (the "License"); 
    - you may not use this file except in compliance with the License. - You 
    may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 
    - - Unless required by applicable law or agreed to in writing, software - 
    distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT 
    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the 
    License for the specific language governing permissions and - limitations 
    under the License. -->
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
    <system>
    <property name="useSqlStat">0</property>  <!-- 1爲開啓實時統計、0爲關閉 -->
    <property name="useGlobleTableCheck">0</property>  <!-- 1爲開啓全加班一致性檢測、0爲關閉 -->

        <property name="sequnceHandlerType">2</property>
      <!--  <property name="useCompression">1</property>--> <!--1爲開啓mysql壓縮協議-->
        <!--  <property name="fakeMySQLVersion">5.6.20</property>--> <!--設置模擬的MySQL版本號-->
    <!-- <property name="processorBufferChunk">40960</property> -->
    <!-- 
    <property name="processors">1</property> 
    <property name="processorExecutor">32</property> 
     -->
        <!--默認爲type 0: DirectByteBufferPool | type 1 ByteBufferArena-->
        <property name="processorBufferPoolType">0</property>
        <!--默認是65535 64K 用於sql解析時最大文本長度 -->
        <!--<property name="maxStringLiteralLength">65535</property>-->
        <!--<property name="sequnceHandlerType">0</property>-->
        <!--<property name="backSocketNoDelay">1</property>-->
        <!--<property name="frontSocketNoDelay">1</property>-->
        <!--<property name="processorExecutor">16</property>-->
        <!--
            <property name="serverPort">8066</property> <property name="managerPort">9066</property> 
            <property name="idleTimeout">300000</property> <property name="bindIp">0.0.0.0</property> 
            <property name="frontWriteQueueSize">4096</property> <property name="processors">32</property> -->
        <!--分佈式事務開關,0爲不過濾分佈式事務,1爲過濾分佈式事務(若是分佈式事務內只涉及全局表,則不過濾),2爲不過濾分佈式事務,可是記錄分佈式事務日誌-->
        <property name="handleDistributedTransactions">0</property>
        
            <!--
            off heap for merge/order/group/limit      1開啓   0關閉
        -->
        <property name="useOffHeapForMerge">1</property>

        <!--
            單位爲m
        -->
        <property name="memoryPageSize">1m</property>

        <!--
            單位爲k
        -->
        <property name="spillsFileBufferSize">1k</property>

        <property name="useStreamOutput">0</property>

        <!--
            單位爲m
        -->
        <property name="systemReserveMemorySize">384m</property>


        <!--是否採用zookeeper協調切換  -->
        <property name="useZKSwitch">true</property>


    </system>
    
    <!-- 全局SQL防火牆設置 -->
    <!-- 
    <firewall> 
       <whitehost>
          <host host="127.0.0.1" user="mycat"/>
          <host host="127.0.0.2" user="mycat"/>
       </whitehost>
       <blacklist check="false">
       </blacklist>
    </firewall>
    -->

    <user name="mycat">
        <property name="password">123456</property>
        <property name="schemas">TESTDB</property>
        <property name="readOnly">false</property>
    </user>

</mycat:server>
View Code

schema.xml

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

    <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1"></schema>

    <dataNode name="dn1" dataHost="aiMasterSlave" database="master_slave_test" />

    <dataHost name="aiMasterSlave" maxCon="1000" minCon="10" balance="3"
              writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
        <heartbeat>select user()</heartbeat>
        <!-- can have multi write hosts -->
        <writeHost host="hostM1" url="192.168.1.45:3306" user="AiMasterSlave"
                   password="123456">
            <!-- can have multi read hosts -->
            <readHost host="hostS2" url="192.168.1.239:3306" user="aliyun" password="123456" />
        </writeHost>
    </dataHost>

</mycat:schema>

測試讀寫分離

開啓debug級別日誌(生產環境不要一直設置日誌級別爲debug) 

vi /usr/local/mycat/conf/log4j2.xml 

重啓Mycat

使用本地 Shell 測試

檢驗物理數據庫

數據已同步,說明沒問題!

查看Mycat日誌

能夠看到讀和寫分別走兩個服務器。至此,讀寫分離和主從配置完畢!

Mycat高可用方案

Mycat做爲一個代理層中間件,Mycat系統的高可用涉及到Mycat自己的高可用以及後端MySQL的高可用。在大多數狀況下,建議採用標準的MySQL主從複製高可用性配置並交付給Mycat來完成後端MySQL節點的主從自動切換。

應用強制走寫/從

一個查詢SQL語句以/*balance*/註解來肯定其是走讀節點仍是寫節點。 1.6之後添加了強制走讀走寫處理:

強制走從:

/*!mycat:db_type=slave*/ select * from travelrecord 
/*#mycat:db_type=slave*/ select * from travelrecord 

強制走寫:
/*#mycat:db_type=master*/ select * from travelrecord /*!mycat:db_type=master*/ select * from travelrecord

根據主從延時切換

1.4開始支持MySQL主從複製狀態綁定的讀寫分離機制,讓讀更加安全可靠,配置以下:

MyCAT心跳檢查語句配置爲 show slave status ,dataHost 上定義兩個新屬性: switchType="2" 與 slaveThreshold="100",此時意味着開啓MySQL主從複製狀態綁定的讀寫分離與切換機制,Mycat心跳機制經過檢測 show slave status 中的 "Seconds_Behind_Master", "Slave_IO_Running", "Slave_SQL_Running" 三個字段來肯定當前主從同步的狀態以及Seconds_Behind_Master主從複製時延, 當Seconds_Behind_Master>slaveThreshold時,讀寫分離篩選器會過濾掉此Slave機器,防止讀到好久以前的舊數據,而當主節點宕機後,切換邏輯會檢查Slave上的Seconds_Behind_Master是否爲0,爲0時則表示主從同步,能夠安全切換,不然不會切換。

<dataHost name="localhost1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native"
          switchType="2" slaveThreshold="100">
    <heartbeat>show slave status</heartbeat> <!-- can have multi write hosts -->
    <writeHost host="hostM1" url="localhost:3306" user="root" password="123456"></writeHost>
    <writeHost host="hostS1" url="localhost:3316" user="root" password="123456"/>
</dataHost>

1.4.1 開始支持MySQL 集羣模式,讓讀更加安全可靠,配置以下: MyCAT心跳檢查語句配置爲 show status like ‘wsrep%’ , dataHost 上定義兩個新屬性: switchType="3"
此時意味着開啓MySQL集羣複製狀態狀態綁定的讀寫分離與切換機制,Mycat心跳機制經過檢測集羣複製時延時,若是延時過大或者集羣出現節點問題不會負載改節點。 

<dataHost name="localhost1" maxCon="1000"
minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="3" >
    <heartbeat> show status like ‘wsrep%’</heartbeat>
    <writeHost host="hostM1" url="localhost:3306" user="root" password="123456"></writeHost>
    <writeHost host="hostS1" url="localhost:3316" user="root" password="123456"></writeHost>
</dataHost>

主從數據監控

關於主從監控(數據一致性,延遲監測),我使用的是 percona-toolkit 

關於 percona-toolkit 的配置與使用,能夠參考:http://www.cnblogs.com/kevingrace/p/6261091.html

相關文章
相關標籤/搜索