MySQL 數據庫的主從復制與讀寫分離
在實際生產環境中,如果對數據庫的讀和寫都在同一個數據庫服務器中操作,無論是安全性、高可用性,還是高並發等各個方面都是完全不能滿足實際需求的,因此,一般來說都是通過主從復制(Master-Slave)的方式來同步數據,再通過讀寫分離來提升數據庫的並發負載能力這樣的方案來進行部署與實施。
MySQL 的主從復制和讀寫分離兩者有著緊密關聯,首先要部署主從復制,才能在此基礎上進行數據的讀寫分離。
-
MySQL 主從復制的復制類型
1) 基於語句的數據。在主服務器上執行的 SQL 語句,在從服務器上執行同樣的語句。 MySQL 默認采用基於語句的復制,效率比較高。
2) 基於行的復制。把改變的內容復制過去,而不是把命令從服務器上執行一遍。 - MySQL 讀寫分離原理
簡單來說,讀寫分離就是只在主服務器上寫,只在從服務器上讀。基本原理是讓主數據庫處理事務性查詢,而從數據庫處理 select 查詢。數據庫復制被用來把事務性查詢導致的變更同步到群集中的從服務器。
部署環境
主機 | 操作系統 | IP地址 | 主要軟件 |
---|---|---|---|
Master | CentOS 7.4 x86_64 | 192.168.100.200 | mysql-5.7.17.tar.gz 、ntp 、boost_1_59_0.tar.gz |
Slave1 | CentOS 7.4 x86_64 | 192.168.100.201 | mysql-5.7.17.tar.gz 、ntp 、boost_1_59_0.tar.gz |
Slave2 | CentOS 7.4 x86_64 | 192.168.200.202 | mysql-5.7.17.tar.gz 、ntp 、boost_1_59_0.tar.gz |
Amoeba | CentOS 7.4 x86_64 | 192.168.200.203 | mysql-5.7.17.tar.gz 、ntp 、boost_1_59_0.tar.gz 、amoeba-mysql-binary-2.2.0.tar.gz 、jdk-6u14-linux-x64.bin |
Client | CentOS 7.4 x86_64 | 192.168.200.204 | mysql-5.7.17.tar.gz |
搭建 MySQL 主從復制
-
建立時間同步環境,在主節點上搭建時間同步服務器
systemctl stop firewalld.service setenforce 0 yum -y install ntp #一般系統自帶,沒有的話yum安裝 vim /etc/ntp.conf #添加下面的行 server 127.127.100.0 #本地為時鐘源 fudge 127.127.100.0 stratum 8 #設置時間層級為8(一般限制15內) systemctl restart ntpd #重啟服務
-
在從服務器上進行時間同步
systemctl stop firewalld.service setenforce 0 yum -y install ntpdate /usr/sbin/ntpdate 192.168.100.200 #進行時間同步
-
在4臺主機上安裝 MySQL數據庫
這邊選擇的是5.7版本,直接進行簡單的編譯安裝即可。 -
配置 Master 主服務器
# vim /etc/my.cnf server-id = 11 #修改 log-bin=master-bin #主服務器日誌文件 log-slave-updates=true #從服務器更新二進制日誌 # systemctl restart mysqld.service # mysql -u root -p123456 #登錄Mysql 給從服務器授權 mysql> GRANT REPLICATION SLAVE ON *.* TO ‘myslave‘@‘192.168.100.%‘ IDENTIFIED BY ‘123456‘; mysql> FLUSH PRIVILEGES; mysql> show master status;
-
配置 Slave 從服務器(Slave1、Slave2配置相同)
# vim /etc/my.cnf server-id = 22 #另一臺從服務器也是22(不能和 Master 服務器相同) relay-log=relay-log-bin #從主服務器上同步日誌文件記錄到本地 relay-log-index=slave-relay-bin.index #定義relay-log的位置和名稱 # systemctl restart mysqld.service
-
登錄 Slave 服務器,按 Master 服務器結果更改下面命令中 master_log_file 和 master_log_pos 的參數
# mysql -u root -p123456 mysql> change master to master_host=‘192.168.100.200‘,master_user=‘myslave‘,master_password=‘123456‘,master_log_file=‘master-bin.000001‘,master_log_pos=604; mysql> start slave; #啟動同步 mysql> show slave status\G; #查看狀態
- 驗證主從復制效果
在 Master 服務器上創建一個 test 表,從服務器上查看。
搭建 MySQL 數據庫的讀寫分離
Amoeba(變形蟲)項目開源框架於2008年發布了一款 Amoeba for MySQL 軟件。這個軟件致力於 MySQL 的分布式數據庫前端代理層,它主要為應用層訪問 MySQL 時充當 SQL 路由,並具有負載均衡、高可用性、SQL 過濾、讀寫分離、可路由相關到目標數據庫、可並發請求多臺數據庫。通過 Amoeba 已在很多企業的生產線上使用,其版本可在官網下載。
-
在 Amoeba 服務器上安裝 Java 環境
systemctl stop firewalld.service setenforce 0 cp jdk-6u14-linux-x64.bin /usr/local/ cd /usr/local ./jdk-6u14-linux-x64.bin #回車,輸入"yes",回車 mv jdk1.6.0_14/ /usr/local/jdk1.6
-
修改環境變量
# vim /etc/profile #在文件末尾添加下面的行 export JAVA_HOME=/usr/local/jdk1.6 export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib export PATH=$JAVA_HOME/lib:$JAVA_HOME/jre/bin/:$PATH:$HOME/bin export AMOEBA_HOME=/usr/local/amoeba export PATH=$PATH:$AMOEBA_HOME/bin # source /etc/profile #刷新環境變量
-
安裝並配置 Amoeba 軟件
# mkdir /usr/local/amoeba # tar zxvf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/ # chmod -R 755 /usr/local/amoeba/ # /usr/local/amoeba/bin/amoeba amoeba start|stop #顯示此內容說明 Amoeba 安裝成功
-
在三臺主從 MySQL 服務器上開放權限給 Amoeba 訪問(三臺服務器都要添加)
grant all on *.* to test@‘192.168.100.%‘ identified by ‘123456‘;
-
在 Amoeba 服務器上編輯 amoeba.xml 配置文件
# vim /usr/local/amoeba/conf/amoeba.xml --30行-- <property name="user">amoeba</property> #用戶訪問amoeba服務器的身份驗證 --32行-- <property name="password">123456</property> --115行-- <property name="defaultPool">master</property> #默認權限 --117-去掉註釋- <property name="writePool">master</property> #賦予master寫權限 <property name="readPool">slaves</property> #賦予slaves讀權限
# vi conf/dbServers.xml -23行註釋掉 作用:默認進入test庫 以防mysql中沒有test庫時,會報錯 <!-- <property name="schema">test</property> --> --26--29--去掉註釋-- #賦予amoeba用戶權限 <property name="user">test</property> <property name="password">123456</property> -----42-主服務器地址--- <dbServer name="master" parent="abstractServer"> <property name="ipAddress">192.168.100.200</property> --52-從服務器主機名- <dbServer name="slave1" parent="abstractServer"> --55-從服務器1地址- <property name="ipAddress">192.168.100.201</property> --(這裏上面6行復制修改)從服務器2地址 <dbServer name="slave2" parent="abstractServer"> <property name="ipAddress">192.168.100.202</property> --64行-- <dbServer name="slaves" virtual="true"> --70行-- <property name="poolNames">slave1,slave2</property>
-
開啟服務
/usr/local/amoeba/bin/amoeba start& netstat -anpt | grep java
- 測試讀寫分離
-
客戶機
systemctl stop firewalld.service setenforce 0 mysql -u amoeba -p123456 -h 192.168.100.203 -P8066 #使用amoeba遠程登錄MySQL
-
Master 服務器
mysql -u root -p mysql> create database wang; mysql> use wzn; mysql> create table wzn (id int(10),name varchar(10),address varchar(20));
- Slave 服務器
mysql -u root -p mysql> stop slave; mysql> use wang; mysql> use wzn; # Slave1 服務器 mysql> insert into zang values(‘2‘,‘wzn‘,‘this_is_slave1‘); # Slave2 服務器 mysq> insert into zang values(‘3‘,‘wzn‘,‘this_is_slave2‘);
-
此時我們通過客戶機訪問,使用
select * from wzn;
可以看到在兩臺 Slave 服務器上分別創建的數據。 - 我們在客戶端上插入一條數據,此時查看表 wzn ,是看不到剛寫的數據的,因為數據是寫在 Master 服務器上,此時同步沒有開啟,但是我們登錄 Master數據庫可以看到數據寫入成功。嘗試開啟同步,我們可以看到,數據同步到 Slave 數據庫之後,我們可以看到新建的數據了。
由此可以證實:數據的寫入是在 Master 服務器上;數據的讀取是在 Slave 服務器上。
MySQL 數據庫的主從復制與讀寫分離