利用Amoeba實現MySQL主從複製和讀寫分離

在實際生產環境中,如果對數據庫的讀和寫都在同一個數據庫服務器中操作,無論是在安全性、高可用性,還是高併發等各個方面都是完全不能滿足實際需求的,因此,一般來說都是通過主從複製(Master-Slave)的方式來同步數據,再通過讀寫分離來提升數據庫的併發負載能力這樣的方案來進行部署和實施。

1、 MySQL主從複製原理

MySQL的主從複製和MySQL的讀寫分離兩者有着緊密聯繫,首先要部署主從複製,只有主從複製完成了,才能在此基礎上進行數據的讀寫分離。

(1) MySQL支持的複製類型

  • 1) 基於語句的複製。在主服務器上執行的SQL語句,在從服務器上執行同樣的語句。MySQL默認採用基於語句的複製,效率比較高。
  • 2) 基於行的複製。把改變的內容複製過去,而不是把命令在從服務器上執行以便。
  • 3) 混合類型的複製。默認採用基於語句的複製,一旦發現基於語句無法精確複製時,就會採用基於行的複製。

    (2) 複製的工作過程

  • 1) 在每個事務更新數據完成之前,Master在二進制日誌記錄這些改變。寫入二進制日誌完成後,Master通知存儲引擎提交事務。
  • 2) Slave將Master的Binary log複製到其中繼日誌。首先,Slave開始一個工作線程——I/O線程,I/O線程在Master上打開一個普通連接,然後開始Binlog dump process。Binlog dump process從Master的二進制日誌中讀取事件,如果已經跟上Master,它會睡眠並等待Master產生新的事件。I/O線程將這些時間寫入中繼日誌。
  • 3) SQL slave thread(SQL從線程)處理該過程的最後一步。SQL線程從中繼日誌讀取事件,並重放其中的事件而更新Slave的數據,使其與Master中的數據一致。只要該線程與I/O線程保持一致,中繼日誌通常會位於OS的緩存中,所以中繼日誌的開銷很小。
    複製過程有一個很重要的限制,即複製在Slave上是串行化的,也就是說Master上的並行更新操作不能在Slave上並行操作。

    2、 MySQL讀寫分離的原理

    簡單來說,讀寫分離就是隻在主服務器上寫,只在從服務器上讀。基本原理是讓主數據庫處理事務性查詢,而從數據庫處理select查詢。數據庫複製被用來把事務性查詢導致的變更同步到羣集中的從數據庫。
    基於中間代理層實現:代理一般位於客戶端和服務器之間,代理服務器接到客戶端請求通過判斷後轉發到後端數據庫,有兩個代表性程序。

  • (1)MySQL-Proxy。MySQL-Proxy爲MySQL開源項目,通過其自帶的lua腳本進行SQL判斷,雖然是MySQL官方產品,但是MySQL官方並不建議將MySQL用到生產環境。
  • (2)Amoeba。由陳思儒開發,作者曾就職於阿里巴巴。該程序由Java語言進行開發,阿里巴巴將其用於生產環境。它不支持事務和存儲過程。
    -經過上述簡單的比較,通過程序代碼實現MySQL讀寫分離自然是一個不錯的選擇,但是並不是所有的應用都適合在程序代碼中實現讀寫分離,像一些大型複雜的Java應用,如果在程序代碼中實現讀寫分離對代碼改動就較大。所以,像這種應用一般會考慮使用代理層來實現。

實驗拓撲圖

利用Amoeba實現MySQL主從複製和讀寫分離

實驗環境

主機 操作系統 IP地址 主要軟件
Master CentOS 7.3 192.168.100.137 mysql-5.5.24.tar.gz
Slave1 CentOS 7.3 192.168.100.132 mysql-5.5.24.tar.gz
Slave2 CentOS 7.3 192.168.100.149 mysql-5.5.24.tar.gz
Amoeba CentOS 7.3 192.168.100.150 amoeba-mysql-binary-2.2.0.tar.gz jdk-6u14-linux-x64.bin
客戶端 CentOS 7.3 192.168.100.148 mysql-5.5.24.tar.gz

實驗部署

一. 搭建MySQL主從複製

(1) 建立時間同步環境,在主節點上搭建時間同步服務器

1) 安裝NTP

#yum –y install ntp

2) 配置NTP

#vim /etc/ntp.conf
    server 127.127.100.0                    //本地是時鐘源
fudge 127.127.100.0 stratum 8          //設置時間層級爲8(限制在15內)

3)重啓服務並關閉防火牆和增強安全設置

#service ntpd restart
#systemctl stop firewalld.service
#setenforce 0

(2)在從節點上進行時間同步並關閉防火牆及增強安全功能

#yum install ntpd start
#systemctl stop firewalld.service
#setenforce 0
#/usr/sbin/ntpdate 192.168.100.137              //進行時間同步

(3)在Master、Slave1、Slave2上安裝MySQL數據庫,具體過程在這就不詳述了。

(4)配置MySQL主服務器

1)在/etc/my.cnf中修改或者增加以下內容並重啓服務

#vim /etc/my.cnf
server-id       = 11
log-bin=master-bin                         //主服務器日誌文件
log-slave-updates=true                     //從服務器更新二進制日誌
#systemctl restart mysqld.service

2)登錄MySQL,給從服務器授權

#mysql -u root –p
mysql>GRANT REPLICATION SLAVE ON *.* TO 'myslave'@'192.168.100.%' IDENTIFIED BY '123456';
mysql>FLUSH PRIVILEGES;
mysql>show master status;
+-------------------+----------+--------------+------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+-------------------+----------+--------------+------------------+
| master-bin.000001 |      339 |              |                  |
+-------------------+----------+--------------+------------------+
1 row in set (0.00 sec)

(5)配置從服務器(Slave1,Slave2)

1)在/etc/my.cnf中修改或者增加以下內容

#vim /etc/my.cnf
server-id       =22                         //這裏注意server-id不能與主服務器相同
relay-log=relay-log-bin                         //從主服務器上同步日誌文件記錄到本地
relay-log-index=slave-relay-bin.index           //定義relay-log的位置和名稱

2)重啓MySQL服務

#systemctl restart mysqld.service

3)登錄MySQL,配置同步。按主服務器結果更改下面命令中master_log_file和master_log_pos的參數

#mysql –u root –p
mysql>change master to 
master_host='192.168.100.137',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=339;

4)啓動同步,查看Slave狀態,確保以下兩個值爲YES。

mysql>start slave;

利用Amoeba實現MySQL主從複製和讀寫分離

(6)測試主從複製效果

1)在主服務器上新建數據庫db_test。

mysql>create database db_test;

2)在主、從服務器上分別查看數據庫,顯示數據庫相同,則主從複製成功

利用Amoeba實現MySQL主從複製和讀寫分離

二、搭建MySQL讀寫分離

(1)關閉防火牆及增強安全功能

#systemctl stop firewalld.service
#setenforce 0

(2)複製jdk軟件包及安裝

#cp jdk-6u14-linux-x64.bin /usr/local/
#cd /usr/local
#./jdk-6u14-linux-x64.bin                   //yes之後enter

(3)修改jdk目錄名稱

#mv jdk1.6.0_14/ /usr/local/jdk1.6

(4)添加jdk、jre、amoeba環境變量

#vi /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

(5)刷新環境變量

#source /etc/profile

(6)創建amoeba工作目錄

#mkdir /usr/local/amoeba

(7)解壓amoeba軟件包至工作目錄下

#tar zxvf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/

(8)修改amoeba目錄權限

#chmod -R 755 /usr/local/amoeba/

(9)驗證amoeba是否安裝成功

#/usr/local/amoeba/bin/amoeba           //若顯示amoeba start|stop說明安裝成功

(10)在Master、Slave1、Slave2中開放權限給Amoeba訪問

mysql>grant all on *.* to test@'192.168.100.%' identified by '123.com';

(11)回到amoeba服務器,修改amoeba.xml配置文件

#cd /usr/local/amoeba
#vim conf/amoeba.xml
---30行--
<property name="user">amoeba</property>     //訪問amoeba的用戶名
----32行---------
<property name="password">123456</property>     //密碼
---117-去掉註釋-
<property name="defaultPool">master</property>  //默認爲主服務器
<property name="writePool">master</property>        //寫入爲主服務器
<property name="readPool">slaves</property>         //讀取爲slaves池,現有slave1、slave2服務器

(12)修改dbServers.xml配置文件

--26-29--去掉註釋--
 <property name="user">test</property>
 <property name="password">123.com</property>
-----42-主服務器地址---
<dbServer name="master"  parent="abstractServer">
 <property name="ipAddress">192.168.100.137</property>
--52-從服務器主機名-
<dbServer name="slave1"  parent="abstractServer">
--55-從服務器地址-
 <property name="ipAddress">192.168.100.132</property>

--57-從服務器主機名-
<dbServer name="slave2"  parent="abstractServer">
--60-從服務器地址-
 <property name="ipAddress">192.168.100.149</property>

 <dbServer name="slaves" virtual="true">
 <poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">
--末尾--
<property name="poolNames">slave1,slave2</property>
 </poolConfig>

(13)啓動amoeba服務

#/usr/local/amoeba/bin/amoeba start&

(14)查看java端口開啓情況,其默認端口爲tcp8066

# netstat -anpt | grep java

(15)在客戶端上安裝MySQL,並登陸amoeba服務器(關閉防火牆和增強安全設置)

#yum install -y mysql
#mysql -u amoeba -p123456 -h 192.168.100.100 -P8066
#systemctl stop firewalld.service
#setenforce 0

(16)測試讀寫分離

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

#mysql –u root –p
mysql>use db_test;
mysql>create table zang (id int(10),name varchar(10),address varchar(20));      //主服務器

mysql>stop slave;                   //從服務器

mysql>insert into zang values('1','zhang','this_is_master');        //主服務器上,內容不會同步

2) 從服務器上同步了表,手動插入其他內容

mysql>use db_test;          //從服務器1
mysql>insert into zang values('2','zhang','this_is_slave1');
mysql>use db_test;          //從服務器2
mysql>insert into zang values('3','zhang','this_is_slave2');

3)測試讀操作
利用Amoeba實現MySQL主從複製和讀寫分離

4)測試寫操作
在Client主機上插入一條語句:

mysql>insert into zang values('5','zhang','write_test');

但在Client查詢不到,最終只有在Master上才能查看到這條語句內容,說明寫操作在Master服務器上。

利用Amoeba實現MySQL主從複製和讀寫分離
利用Amoeba實現MySQL主從複製和讀寫分離

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章