文章目錄
前言
一:MySQL讀寫分離原理
1.1:原理
- 讀寫分離就是隻在主服務器上寫,只在從服務器上讀
- 主數據庫處理事務性査詢,而從數據庫處理 select査詢
- 數據庫複製被用來把事務性査詢導致的變更同步到集羣中的從數據庫
1.2:爲什麼會形成讀寫分離?
- 在企業應用中,在大量的數據請求下,單臺數據庫將無法承擔所有的讀寫操作
- 配置多臺數據庫服務器以實現讀寫分離
- 讀寫分離建立在主從複製的基礎上
二:讀寫分離的基礎:主從複製
2.1:主從複製是如何形成的?
- 在企業網站中,後端MySQL數據庫只有一臺時,會有以下問題:
- 遇到單點故障,服務不可用
- 無法處理大量的併發數據請求
- 數據丟失將會造成很大損失
2.2:主從複製的解決方案
2.2.1:解決辦法
- 增加MySQL數據庫服務器,對數據進行備份,形成主備
- 確保主備MySQL數據庫服務器數據是一樣的
- 主服務器宕機了,備份服務器繼續工作,數據有保障
- MySQL主從複製與讀寫分離是密切相關的
2.2.2:更高級的解決辦法
-
通過主從複製的方式來同步數據,再通過讀寫分離來提升數據庫的併發負載能力
-
Amoeba:是一個以MySQL爲底層數據存儲,並對應用提供MySQL協議接口的proxy,外號變形蟲
讀取請求發送給從服務器時,採用輪詢調度算法
-
主服務器掛掉,我們會採用MHA解決(此實驗用不到)
-
此實驗涉及到的賬號權限
- 主從同步賬號
- 節點服務器開放調度賬號
- Amoeba代理賬號
三:主從讀寫分離實驗
3.1:環境
-
VMware軟件
-
環境依賴上一篇博客做的主從複製的結果
-
主從複製的搭建詳情可以看我的博客:
https://blog.csdn.net/CN_TangZheng/article/details/103897251
-
一臺centos7服務器當做client
-
一臺centos7服務器作爲Amoeba服務器
-
三臺centos7服務器作爲mysql數據庫服務器,一主二從
3.2:拓撲圖
3.3:實驗目的
- 通過向mysql主服務器和從服務器寫東西,驗證:
- 客戶機通過amoeba服務器寫入是寫入mysql主服務器
- 客戶機通過amoeba服務器讀取數據是從兩個slave從服務器上輪詢讀取數據的
3.4:實驗過程
3.4.1:防火牆設置
-
和主從同步一樣,確定都關閉
systemctl stop firewalld.service setenforce 0
3.4.2:搭建mysql主從複製環境
3.4.3:Amoeba服務器環境安裝
-
安裝jdk(因爲amoeba是Java寫的,所以我們需要安裝jdk)
-
我已經下載好了,直接掛在宿主機複製到服務器就行
[root@amoeba ~]# mount.cifs //192.168.100.3/ccc /mnt Password for root@//192.168.100.3/ccc: [root@amoeba ~]# cd /mnt [root@amoeba mnt]# cp jdk-6u14-linux-x64.bin /usr/local/ [root@amoeba mnt]# cd /usr/local [root@amoeba local]# ./jdk-6u14-linux-x64.bin ...期間一直空格,直到要輸入yes Do you agree to the above license terms? [yes or no] yes '//輸入yes' '//遇到它,按回車' Press Enter to continue..... Done. [root@amoeba local]# mv jdk1.6.0_14/ jdk1.6 '//重命名一下' [root@amoeba local]# echo '//設置環境變量' > 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' >> /etc/profile [root@amoeba local]# source /etc/profile [root@amoeba mnt]# cd /mnt [root@amoeba mnt]# mkdir /usr/local/amoeba [root@amoeba mnt]# tar zxvf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/ [root@amoeba mnt]# chmod -R 755 /usr/local/amoeba '//設置權限' [root@amoeba mnt]# /usr/local/amoeba/bin/amoeba '//查看是否安裝成功' amoeba start|stop
3.4.4:配置Amoeba讀寫分離,兩個slave讀負載均衡
-
三臺mysql服務器添加權限和用戶開放給amoeba訪問
mysql> grant all on *.* to test@'192.168.79.%' identified by '123.com'; Query OK, 0 rows affected, 1 warning (0.00 sec) '//通過192.168.79.0段的test用戶擁有所有權限對於所有的庫和表都可以使用123.com來訪問' '//三臺mysql服務器都要設置'
-
配置amoeba服務器
[root@amoeba mnt]# cd /usr/local/amoeba/conf/ [root@amoeba conf]# vim amoeba.xml '//編輯amoeba主配置文件' '//此段設置的是客戶端通過amoeba用戶和123456密碼訪問amoeba服務器' <property name="user">amoeba</property> '//第30行開始修改用戶名' <property name="password">123456</property> '//使用123456密碼訪問amoeba服務器' '//移動到117行,開啓讀寫功能池設定' <property name="defaultPool">master</property> '//115行修改' <!-- --> '//117行取消註釋' <property name="writePool">master</property> '//118行修改' <property name="readPool">slaves</property> '//119行修改' '//120行刪除-->註釋符號' [root@amoeba conf]# vim dbServers.xml '//編輯數據庫配置文件' <property name="schema">mysql</property> '//23行test修改爲mysql' '//設置amoeba訪問mysql數據庫的用戶和密碼' <property name="user">test</property> '//26行修改用戶名' <!-- mysql password--> '//28行-30行取消註釋' <property name="password">123.com</property> '//29行修改密碼' <dbServer name="master" parent="abstractServer"> '//45行主mysql服務器名稱修改爲master' <property name="ipAddress">192.168.79.135</property> '48行//修改主服務器IP' <dbServer name="slave1" parent="abstractServer"> '//52行修改從服務器名稱' <property name="ipAddress">192.168.79.135</property> '//55行修改從服務器IP' '//第一個從服務器段後插入第二個從服務器配置' <dbServer name="slave2" parent="abstractServer"> <factoryConfig> <!-- mysql ip --> <propertyname="ipAddress">192.168.79.136</property> </factoryConfig> </dbServer> '//修改數據庫從服務器池' <dbServer name="slaves" virtual="true"> '//66行修改服務器吃名稱爲slaves' <property name="poolNames">slave1,slave2</property> '//72行添加兩個從服務器名稱slave1,slave2'
3.4.5:啓動Amoeba軟件
-
開啓amoeba軟件,放到後臺運行
[root@amoeba conf]# /usr/local/amoeba/bin/amoeba start & [1] 63847 [root@amoeba conf]# log4j:WARN log4j config load completed from file:/usr/local/amoeba/conf/log4j.xml 2020-01-08 23:38:40,817 INFO context.MysqlRuntimeContext - Amoeba for Mysql current versoin=5.1.45-mysql-amoeba-proxy-2.2.0 log4j:WARN ip access config load completed from file:/usr/local/amoeba/conf/access_list.conf 2020-01-08 23:38:41,113 INFO net.ServerableConnectionManager - Amoeba for Mysql listening on 0.0.0.0/0.0.0.0:8066. 2020-01-08 23:38:41,122 INFO net.ServerableConnectionManager - Amoeba Monitor Server listening on /127.0.0.1:23097. '//此時處於持續監控狀態,無法輸入命令'
3.5:實驗驗證
3.5.1:客戶端安裝mysql
-
由於是用來驗證,所以可以直接用yum安裝
'//先關閉防火牆,且確認所有服務器的防火牆都已關閉' [root@client ~]# systemctl stop firewalld.service [root@client ~]# setenforce 0 [root@client ~]# yum install mysql -y [root@client ~]# mysql -u amoeba -p123456 -h 192.168.79.100 -P8066 MySQL [(none)]> create database sanku; '//創建一個庫' '//進入主從服務器查看,發現mysql主從服務器都已經自動同步'
-
測試讀寫分離,關閉主從複製功能
兩臺從服務器關閉slave功能 mysql> stop slave; Query OK, 0 rows affected (0.00 sec) mysql> show slave status\G; ...省略內容 Slave_IO_Running: No '//發現功能已被關閉' Slave_SQL_Running: No ...省略內容
-
從服務器配置數據,驗證讀寫分離
MySQL [(none)]> create database siku; '//客戶端創建庫' '//會發現主服務器有,但是從服務器沒有,說明主從複製功能已經關閉' '//slave1從服務器設置:都有erku的庫,所以各自在erku創建yibiao並插入不同數據' mysql> use erku; Database changed mysql> create table yibiao (id int not null,name char(10)); Query OK, 0 rows affected (0.01 sec) mysql> insert into yibiao values(1,'zhangsan'); '//添加zhangsan記錄' Query OK, 1 row affected (0.02 sec) mysql> select * from yibiao; +----+----------+ | id | name | +----+----------+ | 1 | zhangsan | +----+----------+ 1 row in set (0.00 sec) '//slave1從服務器設置:' mysql> use erku; Database changed mysql> create table yibiao(id int not null,name char(10)); Query OK, 0 rows affected (0.01 sec) mysql> insert into yibiao values(2,'lisi'); '//添加lisi記錄' Query OK, 1 row affected (0.02 sec) mysql> select * from yibiao; +----+------+ | id | name | +----+------+ | 2 | lisi | +----+------+ 1 row in set (0.00 sec)
-
驗證
'//進入客戶端測試' MySQL [(none)]> use erku; '//進入庫' Database changed MySQL [erku]> select * from yibiao; +----+------+ | id | name | +----+------+ | 2 | lisi | +----+------+ 1 row in set (0.01 sec) MySQL [erku]> select * from yibiao; +----+----------+ | id | name | +----+----------+ | 1 | zhangsan | +----+----------+ 1 row in set (0.01 sec) '//發現每一次查詢都會輪詢在slave1和slave2上查詢數據,如果開啓主從複製,則數據都會相同' '//讀寫分離試驗成功'