1. 程式人生 > >mycat+mysql叢集:實現讀寫分離,分庫分表

mycat+mysql叢集:實現讀寫分離,分庫分表

1.mycat文件:https://github.com/MyCATApache/Mycat-doc  
    官方網站:http://www.mycat.org.cn/
2.mycat的優點
  • 配置簡單,靈活
  • 可實現讀寫分離
  • 可利用多種規則實現分庫分表
  • 心跳機制,自動踢出故障機組
  • 免費開源,長期維護,社群活躍
    mycat的缺點:
  • 主要是分片之後有一些限制,如只能2表join
3.架構圖:可實現讀寫分離,分庫分表


4.所需軟體,機器配置與ip地址
名稱 版本 下載地址
mysql server mysql  Ver 14.14 Distrib 5.6.27, for Linux (x86_64) yum源安裝,yum源地址:http://dev.mysql.com/get/mysql57-community-release-el6-7.noarch.rpm
mycat 1.3.0.3 https://github.com/MyCATApache/Mycat-download/blob/master/1.3.0.3-release/Mycat-server-1.3.0.3-release-20150527095523-linux.tar.gz
keepalived http://www.keepalived.org/download.html


機器名  ip地址 配置 用途
mycat1 192.168.2.155/192.168.10.30 4G,4C mycat+keepalived (主)
mycat2 192.168.2.156/192.168.10.31 4G,4C mycat+keepalived (備)
db1 192.168.10.155 8G,4C mysql master1
db2 192.168.10.156 8G,4C mysql master2
db3 192.168.10.157 8G,4C mysql slave1

5.安裝,配置mysql server
  • 獲取官方yum源:  wget http://dev.mysql.com/get/mysql57-community-release-el6-7.noarch.rpm
  • 安裝源:yum install mysql57-community-release-el6-7.noarch.rpm
  • 預設yum安裝的是5.7,我們修改yum源,下載5.6的mysql server
  • 進入yum源配置檔案:cd /etc/yum.repos.d/
  • 找到並編輯:vim mysql-community.repo
  • 找到下面這些內容:enabled=1就是可用,把[mysql56-community]段的enabled=0改為enabled=1,相應的把[mysql57-community]段的改為0,儲存退出

                # Enable to use MySQL 5.6
                [mysql56-community]
                name=MySQL 5.6 Community Server
                baseurl=http://repo.mysql.com/yum/mysql-5.6-community/el/6/$basearch/
                enabled=0
                gpgcheck=1
                gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql
                
                [mysql57-community]
                name=MySQL 5.7 Community Server
                baseurl=http://repo.mysql.com/yum/mysql-5.7-community/el/6/$basearch/
                enabled=1
                gpgcheck=1
                gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql

  • 查詢安裝包(會更新源,時間幾分鐘,看你的網速咯):yum list |grep mysql
  • 如果順利就會看到這一行:mysql-community-server.x86_64              5.6.27-2.el6
  • 沒錯就是它,安裝:yum install -y mysql-community-server.x86_6
  • 啟動(這一步會自動初始化一些內容):service mysqld start
  • 修改root密碼:mysqladmin -uroot --password ‘xxxxx’
  • 修改配置檔案,我測試時候的配置檔案:
  • db1:

[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
character_set_server = utf8

back_log=1024
max_connections = 10000
max_connect_errors = 1000
read_buffer_size = 4M
query_cache_size = 64M
key_buffer_size=400M
max_allowed_packet=128M
innodb_flush_log_at_trx_commit=0
innodb_log_file_size = 200M
innodb_log_files_in_group = 3
innodb_buffer_pool_size = 2048M
innodb_log_buffer_size = 16M
query_cache_size = 0
#init_connect='SET autocommit=0'
innodb_lock_wait_timeout = 50

# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0

# Recommended in standard MySQL setup
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
#replication setting
server-id=1
log-bin=mysql-bin
relay-log=mysql-relay-bin
binlog-do-db=33hao
binlog-do-db=jaydb
binlog-do-db=sbtest
binlog-do-db=shopnc
binlog-ignore-db=mysql
binlog-ignore-db=performance_schema
binlog-ignore-db=information_schema
log-slave-updates=1
master-info-repository=table
relay-log-info-repository=table
relay-log-recovery=1
#for mmm setting
#read_only=1
#general log
general_log=1
general_log_file=/var/log/mysql/mysql-row.log
#no lower_case
lower_case_table_names = 1
#slow log
slow_query_log=1
slow_query_log_file=/var/log/mysql/mysql-slow.log
long_query_time=2
log-queries-not-using-indexes
#default timestamp
explicit_defaults_for_timestamp=true

[mysqld_safe]
log-error=/var/log/mysql/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

  • db2:

[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
character_set_server = utf8

back_log=1024
max_connections = 10000
max_connect_errors = 1000
read_buffer_size = 4M
query_cache_size = 64M
key_buffer_size=400M
max_allowed_packet=128M
innodb_flush_log_at_trx_commit=0
innodb_log_file_size = 200M
innodb_log_files_in_group = 3
innodb_buffer_pool_size = 2048M
innodb_log_buffer_size = 16M
query_cache_size = 0
#init_connect='SET autocommit=0'
innodb_lock_wait_timeout = 50

# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0

# Recommended in standard MySQL setup
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
#replication setting
server-id=2
log-bin=mysql-bin
relay-log=mysql-relay-bin
binlog-do-db=33hao
binlog-do-db=jaydb
binlog-do-db=sbtest
binlog-do-db=shopnc
binlog-ignore-db=mysql
binlog-ignore-db=performance_schema
binlog-ignore-db=information_schema
log_slave_updates=1
master-info-repository=table
relay-log-info-repository=table
relay-log-recovery=1
#for mmm setting
#read_only=1
#general log
general_log=1
general_log_file=/var/log/mysql/mysql-row.log
#no lower_case
lower_case_table_names = 1
#slow log
slow_query_log=1
slow_query_log_file=/var/log/mysql/mysql-slow.log
long_query_time=2
log-queries-not-using-indexes
#default timestamp
explicit_defaults_for_timestamp=true


[mysqld_safe]
log-error=/var/log/mysql/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

  • db3:    

[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
character_set_server = utf8

back_log=1024
max_connections = 10000
max_connect_errors = 1000
read_buffer_size = 4M
query_cache_size = 64M
key_buffer_size=400M
max_allowed_packet=128M
innodb_flush_log_at_trx_commit=0
innodb_log_file_size = 200M
innodb_log_files_in_group = 3
innodb_buffer_pool_size = 2048M
innodb_log_buffer_size = 16M
query_cache_size = 0
#init_connect='SET autocommit=0'
innodb_lock_wait_timeout = 50

# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0

# Recommended in standard MySQL setup
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
#replication setting
server-id=3
#log-bin=mysql-bin
relay-log=mysql-relay-bin
binlog-do-db=33hao
binlog-do-db=jaydb
binlog-do-db=sbtest
binlog-do-db=shopnc
binlog-ignore-db=mysql
binlog-ignore-db=performance_schema
binlog-ignore-db=information_schema
master-info-repository=table
relay-log-info-repository=table
relay-log-recovery=1
#for mmm setting
#read_only=1
#general log
general_log=1
general_log_file=/var/log/mysql/mysql-row.log
#no lower_case
lower_case_table_names = 1
#slow log
slow_query_log=1
slow_query_log_file=/var/log/mysql/mysql-slow.log
long_query_time=2
log-queries-not-using-indexes
#default timestamp
explicit_defaults_for_timestamp=true


[mysqld_safe]
log-error=/var/log/mysql/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

6.從最上面的架構圖中可以看出,這裡只有一個主主(db1,db2),一個主從(db1,db3),下面分別配置主主,主從

7.mysql主主複製配置

(1)分別編輯db1,db2配置檔案,把第5步相應的內容複製到/etc/my.cnf中
(2)接下來手動同步資料
(3)mysql>FLUSH TABLES WITH READ LOCK
(4)不要退出終端,另外開一個,用mysqldump工具匯出所有資料庫資料,到db2資料庫中
(5)在db1(192.168.10.155)的mysql上授權:grant replication slave on *.* to 'repl_user'@'192.168.10.156' identified by 'repl_password';
(6)檢視db1的master狀態,設定從(db2機器的mysql)的時候需要

                mysql> show master status;
                +------------------+----------+--------------+------------------+-------------------+
                | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
                +------------------+----------+--------------+------------------+-------------------+
                | mysql-bin.000001 |      336 |              |                  |                   |
                +------------------+----------+--------------+------------------+-------------------+
(7)在db2中設定master引數,(master_log_file,master_log_pos,都來自上一步)
                mysql> change master to master_host='192.168.10.156', master_user='repl_user',master_password='repl_passwd',master_log_file='mysql-bin.000001',master_log_pos=336;
(8)啟動db2從的複製
                mysql>slave start;
(9)檢視從的狀態
                mysql>show slave status\G;
                Slave_IO_Running: Yes
                Slave_SQL_Running: Yes
                Seconds_Behind_Master: 0
                看到這幾行說明覆製成功。
(10)把db1設定為db2的從
                方法同上,重複(5)-(9),只是把db1和db2,相應的IP地址互換即可,注意重複第(7)的時候master_log_file,master_log_pos是db2的master status了。

8.把db3(192.168.10.157)設定為db1的從

方法通與7步類似,重複其中的(1)-(7)步,只是把db2和192.168.10.156換成db3和192.168.10.157。

9.至此,mysql的設定全部完成。

10.下載,安裝mycat

  • wget https://github.com/MyCATApache/Mycat-download/blob/master/1.3.0.3-release/Mycat-server-1.3.0.3-release-20150527095523-linux.tar.gz
  • tar -zxf Mycat-server-1.3.0.3-release-20150527095523-linux.tar.gz
  • 解壓完成就可以使用,建議把解壓後的資料夾放在/opt下,並建立mycat的軟連線(ln -s “解壓出來的資料夾” mycat),方便以後升級,維護。

11.配置mycat/conf/schema.xml

(1)在這裡,我對33hao資料庫實現讀寫分離
(2)對sbtest資料庫所有表實現,讀寫不分離(當然,也可以針對某一張表,這種設定應對讀寫實時要求很高的情況,即單表或單庫讀寫不分離)
(3)對transdb資料庫的表實現分片,users表不分片(type="global")提高join效率,orders表,用id通過mod-log規則分片(primaryKey="id" rule="mod-long")

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


    <schema name="33hao" checkSQLschema="false" dataNode="dn1">
    </schema>
    <schema name="sbtest" checkSQLschema="false" dataNode="dn2">
    </schema>
    <schema name="jaydb" checkSQLschema="false" dataNode="dn3">
    </schema>
    <schema name="transdb" checkSQLschema="false">
        <table name="users" primaryKey="id" type="global" dataNode="dn4,dn5,dn6" />

                <!-- random sharding using mod sharind rule -->
            <table name="orders" primaryKey="id" rule="mod-long" dataNode="dn4,dn5,dn6" />
    </schema>
    <schema name="shopnc" checkSQLschema="false" dataNode="dn7">
    </schema>
    <dataNode name="dn1" dataHost="localhost1" database="33hao" />
    <dataNode name="dn2" dataHost="localhost2" database="sbtest" />
    <dataNode name="dn3" dataHost="localhost1" database="jaydb" />
    <dataNode name="dn4" dataHost="localhost4" database="transdb" />
    <dataNode name="dn5" dataHost="localhost5" database="transdb" />
    <dataNode name="dn6" dataHost="localhost6" database="transdb" />
    <dataNode name="dn7" dataHost="localhost1" database="shopnc" />

    <dataHost name="localhost1" maxCon="100000" minCon="10" balance="1"
        writeType="0" dbType="mysql" dbDriver="native">
        <heartbeat>select user()</heartbeat>
        <!-- can have multi write hosts -->
        <writeHost host="hostM1" url="db1:3306" user="root"
            password="123456">
            <!-- can have multi read hosts -->
            <readHost host="hostS1" url="db3:3306" user="root" password="123456"/>
            <readHost host="hostS2" url="db2:3306" user="root" password="123456"/>
        </writeHost>
        <writeHost host="hostM2" url="db2:3306" user="root"
            password="123456">
            <!-- can have multi read hosts -->
        </writeHost>
        <!-- <writeHost host="hostM2" url="db2:3306" user="root" password="123456"/> -->
    </dataHost>
    <dataHost name="localhost2" maxCon="100000" minCon="10" balance="1"
        writeType="0" dbType="mysql" dbDriver="native">
        <heartbeat>select user()</heartbeat>
        <!-- can have multi write hosts -->
        <writeHost host="hostM1" url="db1:3306" user="root"
            password="123456">
        </writeHost>
    </dataHost>
    <dataHost name="localhost4" maxCon="100000" minCon="10" balance="0"
        writeType="0" dbType="mysql" dbDriver="native">
        <heartbeat>select user()</heartbeat>
        <!-- can have multi write hosts -->
        <writeHost host="hostM1" url="db1:3306" user="root" password="123456"></writeHost>
    </dataHost>
    <dataHost name="localhost5" maxCon="100000" minCon="10" balance="0"
        writeType="0" dbType="mysql" dbDriver="native">
        <heartbeat>select user()</heartbeat>
        <!-- can have multi write hosts -->
        <writeHost host="hostM2" url="db2:3306" user="root" password="123456"></writeHost>
    </dataHost>
    <dataHost name="localhost6" maxCon="100000" minCon="10" balance="0"
        writeType="0" dbType="mysql" dbDriver="native">
        <heartbeat>select user()</heartbeat>
        <!-- can have multi write hosts -->
        <writeHost host="hostS1" url="db3:3306" user="root" password="123456"></writeHost>
    </dataHost>

12.設定mycat/conf/server.xml

  • 這裡是針對mycat的設定,如外部訪問mycat的埠,使用者名稱,密碼,mycat的資料庫有哪些等

<?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://org.opencloudb/">
        <system>
        <property name="defaultSqlParser">druidparser</property>
              <property name="processors">32</property>
              <property name="processorExecutor">32</property>
              <property name="serverPort">3306</property>
              <property name="managerPort">9066</property>

        </system>
        <user name="root">
                <property name="password">123456</property>
                <property name="schemas">33hao,sbtest,jaydb,transdb,shopnc</property>
        </user>
</mycat:server>
13.啟動mycat

  • /opt/mycat/bin/mycat start

14.連線mycat

  • 和連線mysql方法一樣,如果連線不上,看看是否在沒個節點上都授予了mycat機器通過root/123456(在schema.xml中配置的)的方式訪問:
  • mysql -uroot -p123456 -h127.0.0.1 -P3306

15.測試mycat

  • 我開起了general_log,資料庫任何操作都會被記錄,依次開啟三個db1 db2 db3的日誌:tail -f /var/log/mysql/mysql-row.log
  • 透過mycat連線資料庫 mysql -uroot -p123456 -h127.0.0.1 -P3306
  • 在相應的資料庫中執行操作,並觀察日誌。
  • 比如對33hao的寫總是在db1上,然後replication到db2,db3,如果db1宕機,寫總是在db2上,db1恢復後,db2不會被搶佔寫的角色。讀在db2,db3上隨機執行。
  • 而transdb的orders表被均勻地複製到db1,db2,db3的transdb的orders表中,users則在所有mysql(這裡為db1,db2,db3)中儲存副本(因為在schema.xml中設定為:type="global")。