LVS+MYCAT+讀寫分離+MYSQL主備同步部署手冊
1.6.3 執行change master to系列命令… 3
1 配置MYSQL主備同步
1.1 測試環境
mysql版本:5.6.24;
操作系統版本:Linux-3.13-0-32
主數據庫IP:192.168.10.3;
主數據庫名:db351353;
備用數據庫IP:192.168.10.4;
備用數據庫名:db352354。
1.2 配置主數據庫
1.2.1 編輯my.cnf文件
#服務器唯一ID,一般取IP最后一段
server_id = 3
#啟用二進制日志
log_bin=mysql_bin
#需要備份的數據庫名 多個庫以逗號分隔
Binlog_do_db =db351353
#若涉及及同步函數或者存儲過程需要配置,否則主備會產生異常不能同步
log_bin_trust_function_creators=TRUE
1.2.2 重啟數據庫
# service myql.server restart
1.3 鎖定主數據庫DDL操作
mysql> flush tables with read lock;
1.4 主備已有數據同步
用navicat for mysql將主數據庫數據同步到備數據庫
1.5 停止從服務
mysql>stop slave;
1.6 配置備用數據庫
1.6.1 編輯my.cnf文件
#服務器唯一ID,一般取IP最后一段
server_id = 5
1.6.2 登錄主數據庫查看master狀態
mysql>show master status;
1.6.3 執行change master to系列命令
mysql> change master to
master_host=’192.168.10.3′,
master_user=’iom’,–該用戶要有Repl_slave_priv權限,沒有可用grant replication slave on *.* to ‘iom’@’%’ identified by ‘xf4851213’授權
master_password=’123’,
master_log_file=’mysql_bin.000005’, –根據主服務器show master status出來的File結果填寫
master_log_pos=1192; –根據主服務器show master status出來的Position結果填寫
1.7 重啟從服務
mysql>start slave;
1.8 解鎖主數據庫
mysql> unlock tables;
1.9 驗證主從同步
在備份數據庫上執行
mysql>show slave status;
slave_IO_running和slave_SQL_running 為yes。
主數據庫新建一個表,往表里插入幾條數據,備份數據庫可以同步過來表和表中的數據。
2 MYCAT安裝與配置
2.1 MYCAT安裝
參見 MyCat_In_Action_CN.doc
2.2 參數設置
重點介紹rule.xml schema.xml router.xml server.xml log4j.xml
2.2.1 rule.xml
分片規則配置文件,mycat支持的所有分片規則都在這個文件里。定義一個規則需要兩個節點,一個是tableRule,一個是function。
以一致性哈希分片為例,function節點定義了分片規則的實現類與初始化參數和分片規則的算法名稱。
屬性name為規則算法名稱
class為規則實現類
property子節點為初始化規則的參數,使用seed count virtualBucketTimes就可初始化一致性哈希規則
<function name=”murmur” class=”org.opencloudb.route.function.PartitionByMurmurHash”>
<property name=”seed”>0</property><!– 默認是0–>
<property name=”count”>2</property><!– 要分片的數據庫節點數量,必須指定,否則沒法分片–>
<property name=”virtualBucketTimes”>160</property><!– 一個實際的數據庫節點被映射為這么多虛擬節點,默認是160倍,也就是虛擬節點數是物理節點數的160倍–>
</function>
tableRule節點定義了分片規則名(注意此處是規則名,前面的function節點的name屬性是算法名)rule子節點指定用來分片的數據庫表字段和分片算法名,也就是前面的function節點的name屬性。
<tableRule name=”sharding-by-murmur”>
<rule>
<columns>id</columns>
<algorithm>murmur</algorithm>
</rule>
</tableRule>
任何自定義的分片規則也可以這樣配置
2.2.2 server.xml
此文件用來配置mycat全局參數
<system>節點
<property name=”defaultSqlParser”>druidparser</property>,指定SQL解析器,默認是fdbparser,經測試druidparser效率更高
<property name=”sequnceHandlerType”>1</property>,指定mycat自動序列號生成方式。0:在借助本地文件生成序列號,1:借助數據庫生成序列號,更多信息請參考Mycat in action
<property name=”serverPort”>8066</property>指定mycat服務端口號,mycat通過這個端口接收數據庫客戶端的訪問請求。
另外還有一個9066端口沒有出現在配置文件中,用來接收mycat監控命令、查詢mycat運行狀況、重新加載配置文件等。更多信息請參考Mycat in action。
<user>節點
name屬性指定mycat用戶名
<property name=”password”>password</property><!—用戶密碼–>
<property name=”schema”>database_name</property><!—數據庫名,用客戶端建立連接后要操作的數據庫名 –>
<property name=”readOnly”>false</property><!—指定是不是只讀庫–>
可以有多個user節點。
2.2.3 router.xml
<queryRouter schema=”schema”><!—沒太搞清楚這個文件的意義,我把schema屬性、<name>、<queryNode>都配置成了一樣的,而且都與要連接的數據庫名保持一致 –>
<!—schema的值會在schema.xml用到 –>
<dataNode>
<name>dataNodeName</name>
<queryNode>queryNode</queryNode>
</dataNode>
</queryRouter>
2.2.4 schema.xml
<schema name=”TESTDB” checkSQLschema=”true” sqlMaxLimit=”100″>
其中checkSQLschema表明是否檢查並過濾SQL中包含schema的情況,如邏輯庫為 TESTDB,則可能寫為select * from TESTDB.aaa,此時會自動過濾TESTDB,SQL變為select * from aaa,若不會出現上述寫法,則可以關閉屬性為false
<schema name=”schema”><!—就是router.xml命名的schema–>
<table name=”table_name” <!—要與它代理的數據庫物理表名一致–>
primaryKey=”pk” <!—被用作主鍵的字段名–>
dataNode=”dataNodeName” <!—下面將會出現的dataNode節點–>
rule=”sharding-by-murmur”<!—rule.xml的tableRule節點name屬性值,指定這個節點表示用這個規則執行分片–>
authIncrement=”true”><!—插入數據時是否由mycat自動生成分片,指定true時,如果insert sql內沒有指定主鍵的值,而主鍵又是自增長的,mycat會自動插入生成主鍵的代碼,並在生成主鍵時按照指定的分片規則將數據保存到數據庫–>
<!—mycat有自己的自增序列命令,更多信息請參考Mycat in action–>
<!—此處可以指定多個table子節點,一個table節點表示一張表–>
</schema>
<dataNode name=”dataNodeName” dataHost=”localhost“ database=”database”/>
<!—分別是節點名,就是schema節點里的table子節點dataNode屬性
dataHost是節點主機名,在下面要出現的dataHost定義
database數據庫名
–>
<dataHost name=”localhost” maxCon=”1000” minCon=”10” balance=”0”
wrteType=”0” dbType=”mysql” dbDriver=”native>
<!—name屬性是dataHost名
maxCon minCon分別是連接到物理數據庫的最大最小連接數
dbType指定數據庫類型
dbDriver只有兩個取值,分別是native和jdbc。native為mycat自帶驅動,只支持mysql,jdbc為使用jdbc實現連接數據庫,指定什么數據庫的jdbc驅動就可以訪問什么數據庫,更靈活,但效率不如native
可以有多個dataHost節點
–>
<heartbeat>select 1</heartbeat><!—保持連接不斷的心跳sql–>
<writeHost host=”hostM1” url=”localhost:3306” user=”user” password=”password”>
<reeadHost host=”hostS1” url=”localhost:3306″ user=”root” password=”123456″/>
</writeHost>
<!—可以有多個writeHost,一個writeHost里要吧有多個readHost–>
</dataHost>
2.3 啟動和使用MyCat
2.3.1 啟動MyCat
# mycat console
2.3.2 訪問MyCat
訪問MyCat同訪問MySQL的方式完全相同, 常用訪問方式如下:
mysql –h 127.0.0.1 –u test –p test -P8066 –DTESTDB
2.3.3 自測
可以自己編寫一些語句進行測試,看是否按規則進行分配。
3 KEEPALIVED配置
編輯/etc/keepalived/keepalived.cnf文件,紅色字體是為mycat新加的
global_defs {
router_id LVS_MASTER #BACKUP上修改為LVS_BACKUP
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.10.252 #virtual server
192.168.10.253 #mycat
}
}
virtual_server 192.168.10.252 8080 {
delay_loop 6
lb_algo rr
lb_kind DR
#lb_kind NAT
# persistence_timeout 3
protocol TCP
real_server 192.168.10.3 8080 {
weight 3
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 8080
}
}
real_server 192.168.10.4 8080 {
weight 3
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 8080
}
}
}
virtual_server 192.168.10.253 8066 {
delay_loop 6
lb_algo rr
lb_kind DR
#lb_kind NAT
# persistence_timeout 3
protocol TCP
real_server 192.168.10.3 8066 {
weight 3
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 8066
}
}
real_server 192.168.10.4 8066 {
weight 3
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 8066
}
}
}
4 mycat服務器執行腳本
lvs_mycat.sh腳本內容:
#!/bin/bash
VIP=192.168.10.253
case “$1” in
start)
ifconfig lo:0 $VIP netmask 255.255.255.255 broadcast $VIP
/sbin/route add -host $VIP dev lo:0
echo “1” >/proc/sys/net/ipv4/conf/lo/arp_ignore
echo “2” >/proc/sys/net/ipv4/conf/lo/arp_announce
echo “1” >/proc/sys/net/ipv4/conf/all/arp_ignore
echo “2” >/proc/sys/net/ipv4/conf/all/arp_announce
sysctl -p >/dev/null 2>&1
echo “lvs_vip server start ok!”;;
stop)
ifconfig lo:0 down
/sbin/route del $VIP >/dev/null 2>&1
echo “0” >/proc/sys/net/ipv4/conf/lo/arp_ignore
echo “0” >/proc/sys/net/ipv4/conf/lo/arp_announce
echo “0” >/proc/sys/net/ipv4/conf/all/arp_ignore
echo “0” >/proc/sys/net/ipv4/conf/all/arp_announce
echo “lvs_vip server stoped.”;;
*)
echo “arg start|stop.”
exit 1
esac
exit 0
在腳本所在目錄執行#./lvs_mycat.sh start;腳本主要作用是為服務器的回環接口設定虛擬IP,並屏蔽該IP的arp請求和應答。
5 總體測驗
5.1 網絡架構圖
客戶機IP:192.168.10.1
負載機VIP:192.168.10.253
主mycat和mysql1在同一個服務器上,IP為:192.168.10.3
從mycat和mysql2在同一個服務器上,IP為:192.168.10.4
mysql1上創建兩個數據庫db351353(主),db352354(備),mysql2上創建兩個數據庫db352354(主),db351353(備);mysql2上db351353是mysql1上db351353的備用庫,mysql1上的db352354是mysql2上db352354的備用庫。
5.2 客戶機測試環境
安裝navicat for mysql,創建5個數據連接:
- 直連mysql1數據庫 連接名:mysql1 ip:168.10.3 端口:3306
- 直連mysql2數據庫 連接名:mysql2 ip:168.10.4 端口:3306
- 直連主mycat 連接名:mycat1 ip:168.10.3 端口:8066
- 直連從myca2 連接名:mycat2 ip:168.10.4 端口:8066
- 連接lvs 連接名:keepalived ip:168.10.253 端口:8066
5.3 MYSQL主備同步測試
在mysql1上的db351353 添加數據:
DROP TABLE IF EXISTS `so`;
CREATE TABLE `so` (
`so_nbr` int(8) NOT NULL DEFAULT ‘0’,
`local_net_id` int(8) DEFAULT NULL,
`proc_inst_id` int(8) DEFAULT NULL,
`prod_id` varchar(8) DEFAULT NULL,
PRIMARY KEY (`so_nbr`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `so` VALUES (‘1’, ‘351’, null, null);
在mysql2上的db352354添加數據:
DROP TABLE IF EXISTS `so`;
CREATE TABLE `so` (
`so_nbr` int(8) NOT NULL DEFAULT ‘0’,
`local_net_id` int(8) DEFAULT NULL,
`proc_inst_id` int(8) DEFAULT NULL,
`prod_id` varchar(8) DEFAULT NULL,
PRIMARY KEY (`so_nbr`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `so` VALUES (‘2’, ‘352’, null, null);
在各自的備份庫上能查到對應的數據,可參考1.9
5.4 MYCAT測試
5.4.1 配置mycat主從策略和分片策略
按so表本地網水平分片,351和353放到節點dn1,352和354放到節點dn2。
5.4.1.1 schema.xml內容:
紅色字體為注釋,實際文件里沒有,注意dn2節點的主從連接庫順序,按說明應該配在前面的寫入數據庫為主數據庫,后面的寫入數據庫為從數據庫,但dn2節點卻正好相反,原因待查。
<?xml version=”1.0″?>
<!DOCTYPE mycat:schema SYSTEM “schema.dtd”>
<mycat:schema xmlns:mycat=”http://org.opencloudb/”>
<schema name=”TESTDB” checkSQLschema=”false” sqlMaxLimit=”100″>
<table name=”prod” primaryKey=”prod_id” type=”global” dataNode=”dn1,dn2″ />
<table name=”so” primaryKey=”so_nbr” dataNode=”dn1,dn2″
rule=”sharding-by-intfile”>
</table>
</schema>
<dataNode name=”dn1″ dataHost=”hostdn1″ database=”db351353″ />
<dataNode name=”dn2″ dataHost=”hostdn2″ database=”db352354″ />
<dataHost name=”hostdn1″ maxCon=”1000″ minCon=”10″ balance=”1″
writeType=”0″ dbType=”mysql” dbDriver=”native”>
<heartbeat>select user()</heartbeat>
<!– can have multi write hosts –>
<writeHost host=”hostM1″ url=”192.168.10.3:3306″ user=”iom”–dn1節點主連接庫
password=”xf4851213″>
<!– <readHost host=”hostS1″ url=”192.168.10.4:3306″ user=”iom” password=”123″ /> –>
</writeHost>
<writeHost host=”hostM2″ url=”192.168.10.4:3306″ user=”iom”–dn1節點從連接庫
password=”123″/>
</dataHost>
<dataHost name=”hostdn2″ maxCon=”1000″ minCon=”10″ balance=”1″
writeType=”0″ dbType=”mysql” dbDriver=”native”>
<heartbeat>select user()</heartbeat>
<writeHost host=”host2M1″ url=”192.168.10.3:3306″ user=”iom” –dn2節點從連接庫
password=”xf4851213″>
<!– <readHost host=”hostS1″ url=”192.168.0.3:3306″ user=”iom” password=”xf4851213″ />–>
</writeHost>
<writeHost host=”host2M2″ url=”192.168.10.4:3306″ user=”iom”–dn2節點主連接庫
password=”123″/>
</dataHost>
</mycat:schema>
5.4.1.2 rule.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:rule SYSTEM “rule.dtd”>
<mycat:rule xmlns:mycat=”http://org.opencloudb/”>
<tableRule name=”rule1″>
<rule>
<columns>id</columns>
<algorithm>func1</algorithm>
</rule>
</tableRule>
<tableRule name=”rule2″>
<rule>
<columns>user_id</columns>
<algorithm>func1</algorithm>
</rule>
</tableRule>
<tableRule name=”sharding-by-intfile”>
<rule>
<columns>local_net_id</columns> –按本地網分片
<algorithm>hash-int</algorithm>
</rule>
</tableRule>
<tableRule name=”auto-sharding-long”>
<rule>
<columns>id</columns>
<algorithm>rang-long</algorithm>
</rule>
</tableRule>
<tableRule name=”mod-long”>
<rule>
<columns>id</columns>
<algorithm>mod-long</algorithm>
</rule>
</tableRule>
<tableRule name=”sharding-by-murmur”>
<rule>
<columns>id</columns>
<algorithm>murmur</algorithm>
</rule>
</tableRule>
<function name=”murmur” class=”org.opencloudb.route.function.PartitionByMurmurHash”>
<property name=”seed”>0</property><!– 默認是0–>
<property name=”count”>2</property><!– 要分片的數據庫節點數量,必須指定,否則沒法分片–>
<property name=”virtualBucketTimes”>160</property><!– 一個實際的數據庫節點被映射為這么多虛擬節點,默認是160倍,也就是虛擬節點數是物理節點數的160倍–>
<!–
<property name=”weightMapFile”>weightMapFile</property>
節點的權重,沒有指定權重的節點默認是1。以properties文件的格式填寫,以從0開始到count-1的整數值也就是節點索引為key,以節點權重值為值。所有權重值必須是正整數,否則以1代替 –>
<!–
<property name=”bucketMapPath”>/etc/mycat/bucketMapPath</property>
用於測試時觀察各物理節點與虛擬節點的分布情況,如果指定了這個屬性,會把虛擬節點的murmur hash值與物理節點的映射按行輸出到這個文件,沒有默認值,如果不指定,就不會輸出任何東西 –>
</function>
<function name=”hash-int” class=”org.opencloudb.route.function.PartitionByFileMap”>
<property name=”mapFile”>partition-hash-int.txt</property>
</function>
<function name=”rang-long” class=”org.opencloudb.route.function.AutoPartitionByLong”>
<property name=”mapFile”>autopartition-long.txt</property>
</function>
<function name=”mod-long” class=”org.opencloudb.route.function.PartitionByMod”>
<!– how many data nodes –>
<property name=”count”>3</property>
</function>
<function name=”func1″ class=”org.opencloudb.route.function.PartitionByLong”>
<property name=”partitionCount”>8</property>
<property name=”partitionLength”>128</property>
</function>
</mycat:rule>
5.4.1.3 partition-hash-int內容:
紅色字體為注釋,實際文件里沒有。
351=0 –分配到dn1節點
352=1 –分配到dn2節點
353=0
354=1
5.4.2 測試mycat連接
客戶機navicat打開mycat1連接,能看到一個數據庫TESTDB,數據庫中能查到db351353和db352354兩個數據庫的所有數據。mycat2連接亦同。
5.4.3 測試mycat讀寫分離
測試目的:由4.4.1.1可知,dn1連接的主數據庫是mysql1的db351353,從數據庫是mysql2的db351353,balance值為1,此模式下從數據庫也為讀數據庫。mycat增刪改操作應通過mysql1的db351353進行,讀操作應通過mysql2的db351353進行。
測試方法:客戶機通過navicat的mysql2連接更改db351353的so表記錄,這樣db351353在mysql1和mysql2上有兩份不同的數據,在客戶機navicat的mycat1連接上查看so表本地網為351的數據是否與mysql2相同,如相同則測試通過。測試過后要恢復mysql2上db351353的數據,以免影響剩余的測試。
5.4.4 測試mycat數據節點容錯
測試目的:由4.4.1.1可知,dn1連接的主數據庫是mysql1的db351353,從數據庫是mysql2的db351353,如果mysql1服務掛掉,dn1節點的增刪改操作應自動切換到mysql2的db351353。
測試方法:在mysql1主機上執行 #service mysql.server stop; 在客戶機navicat的mycat1連接上看是否能正常查詢so表數據,如果查詢正常,修改so表本地網為351的數據,在客戶機navicat的mysql2連接上查看db351353的so表數據是否和修改的一樣,如果一樣則測試通過。
注意:如果mysql1服務重新啟動,則mysql1的db351353為從數據庫,不會重新變為主數據庫。
5.4.5 測試mycat節點容錯
測試目的:mycat1和mycat2單個節點宕掉,不影響客戶機使用數據庫。
測試方法:客戶機navicat使用keepalived連接,能正常查詢和增刪改數據。在mycat1上執行#mycat stop;客戶機keepalived連接仍能正常使用。mycat1上執行#mycat console,mycat2上執行#mycat stop,客戶機keepalived連接能正常使用。mycat2上執行#mycat console,客戶機keepalived連接能正常使用,且數據請求路由和keepalived所配lb_algo策略相同。