從數據庫的角度來講,對於大多數應用來講,從集中到分佈,最基本的一個需求不是數據存儲的瓶頸,而是在於計算的瓶頸,即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 的單獨安裝請你們參考網上的教程。java
下載地址: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有提供編譯好的安裝包,支持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端主從的數據自動同步,mycat不負責任何的數據同步問題。
關於 MySQL 主從複製的介紹我很少贅述,其中優缺點有興趣的能夠查閱相關資料。主要複製方式:
基於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 的詳細配置說明,請到官網去查閱文檔,太多了我就不搬過來了。資料下載:百度雲
<?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>
<?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自己的高可用以及後端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