1. 程式人生 > >【實戰】Amoeba 代理 MySQL 主從復制 + 讀寫分離 【提供源碼包】

【實戰】Amoeba 代理 MySQL 主從復制 + 讀寫分離 【提供源碼包】

system 導數據 ant 代理服 數據庫實例 切分 creat 生效 啟動服務

目錄簡介:

1· Amoeba 的介紹
2· MySQL 主從復制原理
3· MySQL 讀寫分離原理
4· 實戰案例
5· 總結歸納


Amoeba 的介紹


1)Amoeba 是什麽:

1·Amoeba 的中文名是:變形蟲。它是一個以MySQL為底層數據存儲,並對應用提供MySQL協議接口的proxy。它集中地響應應用的請求,依據用戶事先設置的規則,將SQL請求發送到特定的數據庫上執行。基於此可以實現負載均衡、讀寫分離、高可用性等需求。


2·Amoeba相當於一個SQL請求的路由器,目的是為負載均衡、讀寫分離、高可用性提供機制,而不是完全實現它們


3·Amoeba 由陳思儒開發,曾經就職阿裏巴巴!該程序由 Java 程序開發。


2)Amoeba 的不足之處:

a)、目前還不支持事務
b)、暫時不支持存儲過程(近期會支持)
c)、不適合從amoeba導數據的場景或者對大數據量查詢的query並不合適(比如一次請求返回10w以上甚至更多數據的場合)
d)、暫時不支持分庫分表,amoeba目前只做到分數據庫實例,每個被切分的節點需要保持庫表結構一致


3)Amoeba 的優勢之處:

Amoeba主要解決以下問題:
a). 數據切分後復雜數據源整合
b). 提供數據切分規則並降低數據切分規則給數據庫帶來的影響
c). 降低數據庫與客戶端連接
d). 讀寫分離路由


MySQL 主從復制原理

1·MySQL 主從復制和MySQL 的讀寫分離有著緊密的聯系,只有主從復制完成,才能在此基礎上完成數據的讀寫分離。


2·下圖是MySQL主從復制的過程圖
技術分享圖片


3·工作過程解讀:
MySQL 主服務器開始寫入數據,就會記錄在二進制日誌文件中。從服務器有兩個線程,分別是 I/o線程 與 SQL 線程。這時從服務器就會讓 I / O 線程在 主服務器上打開一個口,這時會讀取二進制日誌文件寫入中繼日誌中,SQL 線程就會讀取中繼日誌,並重放日誌中的事件,從服務器就會通過日誌來同步主服務器。


MySQL 讀寫分離原理

1·讀寫分離簡單來說就是在主服務器上進行寫入,在從服務器上進行讀取,這個中間就需要基於中間代理層Amoeba來實現,Amoeba 接收到請求後會判斷這個是什麽請求,它就會分別轉發到後端的數據庫。

2·以下是讀寫分離過程圖解:


技術分享圖片


實戰部署之案例環境

拓撲圖如上圖,案例環境表如下表:

主機 操作系統 IP地址
Master主服務器 CentOS 7.4 192.168.106.154
Slave 1 服務器 CentOS 7.4 192.168.106.156
Slave 2 服務器 CentOS 7.4 192.168.106.157
Amoeba 代理 CentOS 7.4 192.168.106.129

MySQL 主從復制+讀寫分離所需要的源碼包都在我的百度網盤 密碼:l23r 需要的請點擊下載


案例實施:

這裏主、從服務器都需要事先安裝好 MySQL ,這裏就不再演示MySQL的安裝,有興趣的朋友可以看看之前的文章 MySQL5.7版本安裝


1·如果是在實戰環境中,而已是在時間差異較大的地區,建議首先需要建立時間同步的環境。

一:主從復制搭建

1)在主服務器上安裝 NTP

[root@localhost ~]# yum install ntp -y


2)配置 NTP 時間同步源

[root@localhost ~]# vim /etc/ntp.conf -------------(加入如下兩行)
server 127.127.106.0 ---------(本地時間源)
fudge 127.127.106.0 stratum 8 ---------(設置時間層級為8)


3)關閉防火墻、啟動時間源服務

[root@localhost ~]# systemctl stop firewalld.service
[root@localhost ~]# setenforce 0
[root@localhost ~]# systemctl start ntpd


4)時間源配置好了之後可以在從服務器上進行時間同步了

[root@localhost ~]# yum install ntp ntpdate -y
[root@localhost ~]# systemctl stop firewalld.service
[root@localhost ~]# setenforce 0
[root@localhost ~]# systemctl start ntpd -------(啟動服務)
[root@localhost ~]# /usr/sbin/ntpdate 192.168.106.154 -------(開始時間同步)


5)配置 MySQL Master 主服務器,因為主從復制的原理就是根據二進制日誌來同步的,所以這裏需要開啟二進制日誌文件,和允許 Slave 從服務器同步數據

[root@localhost ~]# vim /etc/my.cnf -----(進入主服務器配置文件,添加如下)
[mysqld]
server-id = 11 ------(修改,這裏的 id 不允許和從服務器一樣)
log-bin=master-bin ------(有則修改,無則添加,master-bin只是為了容易識別)
log-slave-updates=true -------(添加,允許從服務器來同步)


6)修改完成後重啟 MySQL 主服務器,並且登陸 MySQL 給從服務器授權,允許從服務器以什麽身份、什麽主機登陸並且可以擁有復制的權限!

[root@localhost ~]# systemctl restart mysqld.service -----(重啟服務器)
[root@localhost ~]# mysql -u root -p -----(登陸主服務器MySQL)
mysql> GRANT REPLICATION SLAVE ON . TO ‘myslave‘@‘192.168.106.%‘ IDENTIFIED BY ‘123456‘;
mysql> flush privileges;
mysql> show master status;
+-------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| master-bin.000001 | 604 | | | |
+-------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)


對上面的表格做一個說明:File 列顯示的是日誌名字,我們在配置文件中修改的名字,Position 列顯示偏移量,這兩個值在後面配置從服務器的時候會用到


技術分享圖片


7)主服務器上的配置完成後,現在可以做從服務器上的配置,修改主配置文件

[root@localhost ~]# vim /etc/my.cnf -----(進入從服務器配置文件,添加如下)
[mysqld] ----(在此模塊下添加如下內容)
server-id = 22 ------(修改 ID ,註意不能與主服務器 ID 相同)
relay-log=relay-log-bin ----(從主服務器上同步日誌文件記錄到本地)
relay-log-index=slave-relay-bin.index -----(定義relay-log的位置和名稱)


[root@localhost ~]# systemctl restart mysqld.service ----(修改完畢,重啟服務)


8)配置文件修改完成,登陸 MySQL ,配置同步,指定主服務器各種參數

[root@localhost ~]# mysql -uroot -p ----(登陸MySQL,開始配置同步)
mysql> change master to master_host=‘192.168.106.154‘,master_user=‘myslave‘,master_password=‘123456‘,masterr_log_file=‘master-bin.000001‘,master_log_pos=604;


這裏需要說明兩個參數:masterr_log_file ,master_log_pos 必須按主服務器 show master status 的結果給值


技術分享圖片


9)啟動同步,查看 Slave 狀態,確保 以下兩個值為 YES
mysql> start slave; ----(啟動同步)
mysql> show slave status; ------(查看 Slave 狀態 確保以下兩個值為 YES)
1. row
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.106.154
Master_User: myslave
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: master-bin.000002
Read_Master_Log_Pos: 150
Relay_Log_File: relay-log-bin.000002
Relay_Log_Pos: 270
Relay_Master_Log_File: master-bin.000002
Slave_IO_Running: Yes ------(確保這裏的值為 YES)
Slave_SQL_Running: Yes
------(確保這裏的值為 YES)


技術分享圖片


10)驗證主從同步效果,在主服務器上創建一個數據庫 school ,查看從服務器上是否也有。

mysql> create database school4; -------(主服務器創建庫school4)
Query OK, 1 row affected (0.00 sec)


mysql> show databases; -----(在從服務器上查看是否同步過來school4)

| Database |
+--------------------+
| information_schema |
| #mysql50#.mozilla |
| bbs |
| mysql |
| performance_schema |
| school4 | ------------(同步成功)
| test |
+--------------------+
7 rows in set (0.00 sec)


二:MySQL 讀寫分離搭建:

1)在主機 Amoeba 上安裝 Java 環境

在之前介紹了 Amoeba 是由 Java 程序所開發,所以這搭建 Amoeba 需要用到 jdk 。
[root@localhost ~]# cp jdk-6u14-linux-x64.bin /usr/local (把它移動到這個目錄下)
[root@localhost local]# chmod +x /usr/local/jdk-6u14-linux-x64.bin --(給執行權限)
[root@localhost local]# ./jdk-6u14-linux-x64.bin ---(根據提示按Enter就好,最後輸入YES)
[root@localhost local]# mv jdk1.6.0_14/ /usr/local/jdk1.6 ---(重命名,方便後面操作)


2)增加如下配置:

[root@localhost local]# 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


[root@localhost local]# source /etc/profile ----(刷新一下,使其生效)
[root@localhost local]# systemctl stop firewalld.service ----(關閉防火墻)
[root@localhost local]# setenforce 0


3)現在 Java 環境配置成功,可以開始配置 Amoeba 軟件

[root@localhost ~]# mkdir /usr/local/amoeba
[root@localhost ~]# tar zxvf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/ -----(解壓 Amoeba 壓縮包)


[root@localhost ~]# chmod -R 755 /usr/local/amoeba/
[root@localhost ~]# /usr/local/amoeba/bin/amoeba
amoeba start|stop -----(顯示此內容,說明 Amoeba安裝成功)


4)在Master (主)、Slave1(從1)、Slave(從2)三臺MySQL服務器中開放權限給 Amoeba 訪問

mysql> grant all on . to test@‘192.168.106.%‘ identified by ‘123.com‘;
Query OK, 0 rows affected (0.00 sec)


5)編輯 amoeba.xml 配置文件

[root@localhost ~]# vim /usr/local/amoeba/conf/amoeba.xml ---(修改內容如下)


---30行--

<property name="user">amoeba</property> 客戶機訪問amoeba使用amoeba這個賬號
----32行---------
<property name="password">123456</property>訪問密碼

---117行-去掉註釋-
<property name="defaultPool">master</property> 默認權限給master
<property name="writePool">master</property> 寫入池為master
<property name="readPool">slaves</property> 讀取池為slaves,註意這裏要加上s


6)編輯 dbServers.xml 配置文件

[root@localhost ~]# vim /usr/local/amoeba/conf/dbServers.xml ---(如下內容)


--26-29--去掉註釋--
<property name="user">test</property> //用test身份訪問mysql

<property name="password">123.com</property>

-----42-主服務器地址---
<dbServer name="master" parent="abstractServer"> ---(主服務器名字)
<property name="ipAddress">192.168.106.154</property> ----(主服務器地址)
--52-從服務器主機名-
<dbServer name="slave1" parent="abstractServer"> --(從服務器名字)
--55-從服務器地址-
<property name="ipAddress">192.168.106.156</property> --(從服務器1地址)
<property name="ipAddress">192.168.106.157</property> --(從服務器2地址)
<dbServer name="slaves" virtual="true">
<poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">


技術分享圖片


7)配置完成後,啟動 Amoeba 軟件 默認端口是 8066

[root@localhost ~]# /usr/local/amoeba/bin/amoeba start&


測試

1)在打開一臺客戶端,通過用amoeba 賬戶遠程連接。

[root@localhost ~]# mysql -u amoeba -p123456 -h 192.168.106.129 -P8066
連接上了說明授權沒問題,客戶端能訪問amoeba


2)在 Master 上創建一個表,同步到各個從服務器上,然後關閉從服務器的 Slave 同步功能,再插入區別語句。

mysql> use school4;
Database changed
mysql> create table zang (id int(10),name varchar(10),address varchar(20));
Query OK, 0 rows affected (0.03 sec)


3)在從服務器上關閉 同步功能

mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)


4)在主服務器上插入一條數據

mysql> insert into zang values(‘1‘,‘zhang‘,‘this_is_master‘);
Query OK, 1 row affected (0.01 sec)


5)在從服務器分別插入一條能夠區別的數據 ‘2’ ‘3’

mysql> insert into zang values(‘2‘,‘zhang‘,‘this_is_slave1‘);
Query OK, 1 row affected (0.00 sec)


6)在客戶機上測試幾次讀取表中的數據
技術分享圖片


7)由以上圖得出結論:客戶端讀取數據只會讀取從服務器的數據。


8)在客戶端上寫入一條能夠區別的數據,分別在 三臺服務器上查詢結果。從服務器因為之前需要驗證讀取效果 已經 stop slave ;所以在客戶端上插入的數據不會同步到從服務器。

mysql> insert into zang values(‘4‘,‘zhang‘,‘this_is_slave2‘);
Query OK, 1 row affected (0.02 sec)


9)查詢主服務器的數據會不會由 ‘4’ 這條數據。如下圖:

mysql> select * from zang;
+------+-------+----------------+
| id | name | address |
+------+-------+----------------+
| 1 | zhang | this_is_master |
| 4 | zhang | this_is_slave2 | -------(主服務器上有在客戶端插入的數據)
+------+-------+----------------+
2 rows in set (0.00 sec)


技術分享圖片


結論:

1·因為需要驗證 讀 和 寫 的分離,所以必須在從服務器上關閉同步,這樣才能驗證。
2·根據以上信息得出,客戶端訪問 Amoeba 代理服務器能夠成功實現讀寫分離。
3.讀寫分離是建立在主從復制之上。
4·讀寫分離的最大作用就是為了減輕服務器的壓力
5·讀寫分離其次還有的作用是可以在備份的時候起到了作用,因為備份的時候,不管是什麽方式嗎,可能會鎖定表,或者行!

【實戰】Amoeba 代理 MySQL 主從復制 + 讀寫分離 【提供源碼包】