MySQL主從複製與讀寫分離

-----前言:我們前面搭建過LAMP和LNMP,做過了web服務器羣集和熱備,web服務器壞了我們是不怕了,但是我們要知道,網站的數據有很多是存儲在數據庫裏面的,例如註冊的會員,發的文章,購物的訂單等信息。當然我們可以給數據庫做備份,但是如果每天00:00做一次備份,那麼如果在23:59數據丟失了,那麼就會丟失一天的數據,有沒有一種方法能實現實時備份,就是說有數據產生就立即備份,答案當然是有,也就是今天我們要學習的mysql主從複製。有點類似於前面我們學習過的rsync,但是不同的是rsync是對磁盤文件做備份,而mysql主從複製是對數據庫中的數據,語句做備份。另外讀寫分離主要是爲了優化數據庫。

Mysql讀取分離案例概述

在實際的生產環境中,對數據庫的讀和寫都在同一個數據庫服務器中,是不能滿足實際需求的
解決方案:通過主從複製的方式來同步數據,再通過讀寫分離來提升數據庫的併發負載能力
MySQL主從複製與讀寫分離

案例分析:案例環境

MySQL主從複製與讀寫分離

Mysql主從複製的工作原理

1、mysq支持的複製類型
1)基於語句的複製。在服務器上執行sql語句,在從服務器上執行同樣的語句,mysql默認採用基於語句的複製,執行效率高。
2)基於行的複製。把改變的內容複製過去,而不是把命令在從服務器上執行一遍。
3)混合類型的複製。默認採用基於語句的複製,一旦發現基於語句無法精確複製時,就會採用基於行的複製。

2、複製的工作過程
MySQL主從複製與讀寫分離
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緩存中,所以中繼日誌的開銷很小。

Mysql讀寫分離原理

讀寫分離就是在主服務器上修改,數據會同步到從服務器,從服務器只能提供讀取數據,不能寫入,實現備份的同時也實現了數據庫性能的優化,以及提升了服務器安全。
MySQL主從複製與讀寫分離

目前較爲常見的Mysql讀寫分離分爲兩種

1)基於程序代碼內部實現
在代碼中根據select 、insert進行路由分類,這類方法也是目前生產環境下應用最廣泛的。優點是性能較好,因爲程序在代碼中實現,不需要增加額外的硬件開支,缺點是需要開發人員來實現,運維人員無從下手。

2)基於中間代理層實現
代理一般介於應用服務器和數據庫服務器之間,代理數據庫服務器接收到應用服務器的請求後根據判斷後轉發到,後端數據庫,有以下代表性的程序。
(1)mysql_proxy。mysql_proxy是Mysql的一個開源項目,通過其自帶的lua腳本進行sql判斷。
(2)Atlas。是由 Qihoo 360, Web平臺部基礎架構團隊開發維護的一個基於MySQL協議的數據中間層項目。它是在mysql-proxy 0.8.2版本的基礎上,對其進行了優化,增加了一些新的功能特性。360內部使用Atlas運行的mysql業務,每天承載的讀寫請求數達幾十億條。支持事物以及存儲過程。
(3)Amoeba。由阿里巴巴集團在職員工陳思儒使用序java語言進行開發,阿里巴巴集團將其用戶生產環境下,但是他並不支持事物以及存數過程。

不是所有的應用都能夠在基於程序代碼中實現讀寫分離,像一些大型的java應用,如果在程序代碼中實現讀寫分離對代碼的改動就較大,所以,像這種應用一般會考慮使用代理層來實現,那麼今天就使用Amoeba爲例,完成主從複製和讀寫分離。

實驗案例:mysql主從複製和讀寫分離

1、實驗拓撲
MySQL主從複製與讀寫分離
2、實驗環境
MySQL主從複製與讀寫分離

在amoeba上安裝amoeba和jdk,在其它的機器上安裝mysql,ip地址如上圖所示

實驗步驟:主從複製的實驗步驟

1、搭建時間NTP服務器,同步時間
1)建立時間同步環境,在主節點上搭建時間同步服務器
MySQL主從複製與讀寫分離
2)配置NTP時間服務器
Vim /etc/ntp.conf
MySQL主從複製與讀寫分離
3)重啓ntpd服務
MySQL主從複製與讀寫分離

4)在防火牆上開啓例外
MySQL主從複製與讀寫分離

5)在從節點上進行時間同步
MySQL主從複製與讀寫分離
MySQL主從複製與讀寫分離
在另一臺從服務器上執行相同操作
MySQL主從複製與讀寫分離

2、在mysql主和兩臺從服務器上安裝mysql,這三臺的安裝方法完全一樣,我就以一臺爲例。
(1)安裝mysql並創建程序用戶
[root@centos4 ~]# tar zxf cmake-2.8.6.tar.gz
[root@centos4 ~]# cd cmake-2.8.6
[root@centos4 cmake-2.8.12]# ./configure && gmake && gmake install
[root@centos4 ~]# tar zxf mysql-5.5.38.tar.gz
[root@centos4 ~]# cd mysql-5.5.38
[root@centos4 mysql-5.5.38]# cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DSYSCONFDIR=/etc/ -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DWITH_EXTRA_CHARSETS=all && make && make install
[root@centos4 mysql-5.5.38]# useradd -M -s /sbin/nologin mysql -g mysql

(2)優化程序執行路徑
[root@centos4 mysql-5.5.38]# echo "PATH=$PATH:/usr/local/mysql/bin" >> /etc/profile
(3)創建主配置文件
[root@centos4 mysql-5.5.38]# cp support-files/my-medium.cnf.sh /etc/my.cnf
cp:是否覆蓋"/etc/my.cnf"? y
[root@centos4 mysql-5.5.38]#

(4)創建服務腳本並添加爲系統服務
[root@centos4 mysql-5.5.38]# cp support-files/mysql.server /etc/init.d/mysqld
[root@centos4 mysql-5.5.38]# chkconfig --add mysqld
[root@centos4 mysql-5.5.38]# chkconfig mysqld on
[root@centos4 mysql-5.5.38]# chmod +x /etc/init.d/mysqld

(5)初始化數據庫
[root@centos4 mysql-5.5.38]# /usr/local/mysql/scripts/mysql_install_db --user=mysql --basedir=/usr/local/mysql/ --datadir=/usr/local/mysql/data
[root@centos4 mysql-5.5.38]#

(6)修改安裝目錄權限
[root@centos4 mysql-5.5.38]# chown -R mysql:mysql /usr/local/mysql/

(7)啓動服務
[root@centos4 mysql-5.5.38]# service mysqld start

(8)爲用戶root設置密碼
[root@centos4 mysql-5.5.38]# mysqladmin -u root -p password '123-abc’
默認沒有密碼,直接在確認舊密碼處回車即可。

(9)登錄mysql數據庫
[root@centos4 mysql-5.5.38]# mysql -u root -p

3、配置mysql主服務器(MASTER)
1)修改/etc/my.cnf配置文件
server-id = 11 //mysql數據的唯一標示(不能重複)
log-slave-updates=true //允許連級複製 (增加)
log-bin=master-bin //二進制文件名(修改)

MySQL主從複製與讀寫分離

2)重啓MySQL服務

MySQL主從複製與讀寫分離
3)登錄mysql程序,給從服務器授權
Mysql -u root -p
MySQL主從複製與讀寫分離
4、配置從服務器
1)在/etc/my.cnf中修改以下內容
[root@centos3 ~]# vim /etc/my.cnf
server-id = 22 //不能與其他實例重複
log-bin=mysql-bin //二進制日誌文件名 修改
relay-log=relay-log-bin //複製過來的二進制文件名,增加
relay-log-index=slave-relay-bin.index //中繼日誌存放的文件名稱,增加
MySQL主從複製與讀寫分離

注意server-id不能與主服務器相同,但是從服務器要相同

2)重啓mysql服務
MySQL主從複製與讀寫分離
3)登錄mysql,配置同步
MySQL主從複製與讀寫分離
MySQL主從複製與讀寫分離

IP地址、用戶、密碼都master的數據庫信息

4)啓動同步
MySQL主從複製與讀寫分離
5)查看slave狀態,確保以下兩個值爲YES
MySQL主從複製與讀寫分離
5、驗證主從複製效果
1)在主服務器上新建數據庫“IT”
MySQL主從複製與讀寫分離
2)在從服務器上查看數據庫,如果和主服務器相同,說明成功。
MySQL主從複製與讀寫分離
MySQL主從複製與讀寫分離
注意從服務器的配置和主服務器完全一樣,注意Id也要完全一樣

讀寫分離的實驗步驟

1、安裝java環境(amoeba軟件基於java平臺運行)
1)運行jdk
MySQL主從複製與讀寫分離
MySQL主從複製與讀寫分離
export JAVA_HOME=/usr/local/jdk1.6 //設置jdk的根目錄
export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jir
e/lib //將jdk的程序文件賦予CLASSPATH變量
export PATH=$JAVA_HOME/lib:$JAVA_HOME/jre/bin:$PATH:$HOME
/bin //將jdk的程序文件賦予PATH變量
export AMOEBA_HOME=/usr/local/amoeba //定義AMOEBA的根目錄
export PATH=$PATH:$AMOEBA_HOME/bin 將amoeba的程序文件複製給PATH變量
3)執行腳本
MySQL主從複製與讀寫分離

2、安裝並配置Amoeba軟件
1)安裝
MySQL主從複製與讀寫分離
2)出現以下內容說明安裝成功了

MySQL主從複製與讀寫分離

3、配置amoeba讀寫分離,兩個slave讀負載均衡
1)在主從服務器上開放權限給amoeba(三臺服務器上都做相同設置,這裏我就以其中一臺爲例)

MySQL主從複製與讀寫分離

2)修改amoeba.xml文件
注意:所有配置文件註釋都是以 <!-- 內容 -->,再刪除註釋時請將內容也一併刪除,最好是刪除正行,但是有些時候只需要刪除頭和尾即可,裏面的配置項是可以直接使用的。這個配置文件需要定義兩個配置,第一是應用程序使用什麼用戶連接amoeba訪問到後端的mysql數據庫,第二個是定義默認寫池以及讀池。

Vi /usr/local/conf/amoeba.xml
MySQL主從複製與讀寫分離

接下來修改
<property name="sqlFunctionFile">${amoeba.home}/conf/functionMap.xml
</property>
<property name="LRUMapSize">1500</property>
<property name="defaultPool">master</property> //定義默認的寫池
<property name="writePool">master</property> //定義寫池
<property name="readPool">slaves</property> //定義讀池,以上名字隨便 <property name="needParse">true</property>
</queryRouter>
如下圖所示:
MySQL主從複製與讀寫分離

注意

3)編輯dbServers.xml文件
MySQL主從複製與讀寫分離
MySQL主從複製與讀寫分離

MySQL主從複製與讀寫分離
4)啓動amoeba軟件
MySQL主從複製與讀寫分離
4、測試讀寫分離
1)打開一臺客戶端192.168.1.10,也需要安裝mysql,作爲測試機,可以使用yum -y install mysql安裝。

2)建立防火牆規則
[root@centos1 ~]# iptables -I INPUT -p tcp --dport 8066 -j ACCEPT
master、slave1、slave2都需要開放3306端口入站
[root@centos2 ~]# iptables -I INPUT -p tcp --dport 3306 -j ACCEPT
[root@centos2 ~]# service iptables save
iptables:將防火牆規則保存到 /etc/sysconfig/iptables: [確定]
[root@centos2 ~]#
另外兩臺從服務器也是一樣的配置,或者直接將iptables stop掉

3)修改amoeba的amoeba.xml配置文件的第一個8066改爲3306之後建立一條防火牆規則爲允許3306端口入站並且重新啓動amoeba服務
<property name="port">3306</property> //在11行
MySQL主從複製與讀寫分離

[root@centos1 ~]# amoeba stop
[root@centos1 ~]# amoeba start&
[root@centos1 ~]# iptables -I INPUT -p tcp --dport 3306 -j ACCEPT
在進行登錄amoeba
[root@web ~]# mysql -u amoeba -p 123.abc -h 192.168.1.1
MySQL主從複製與讀寫分離

4)在主服務器master上創建一個數據庫WLZS,同步到各從服務器上,然後關掉從服務器的slave功能,再插入數據。
MySQL主從複製與讀寫分離
5)查看在從服務器已經同步
MySQL主從複製與讀寫分離
6)然後在主服務器上寫入數據
MySQL主從複製與讀寫分離
7)從服務器上也同步了表
MySQL主從複製與讀寫分離
8)在兩臺從服務器上執行stop slave

9)分別在從服務器上寫入不同的數據
MySQL主從複製與讀寫分離
MySQL主從複製與讀寫分離
10)在客戶端上查詢

MySQL主從複製與讀寫分離

11)在客戶機上寫入一條語句
MySQL主從複製與讀寫分離

12)在客戶端上查不到剛寫入的數據,最終只有在master主服務器上才能看到,因爲寫操作只有master有,另外兩臺負責讀取數據。
MySQL主從複製與讀寫分離
MySQL主從複製與讀寫分離
-------總結:到此爲止主從複製和讀寫分離都已完成,寫操作都在主服務器上,實現數據的統一更新,從服務器只負責讀取,負載均衡分擔了數據庫壓力。其實在我們生活中有很多主從複製的應用,例如有很多連鎖超市,總部負責產品的名稱和價格等信息的錄入,而所有的超市都會同步更新,做到了統一價格。而像淘寶的服務器,主要是爲了分擔負載,提升查詢的性能,又快到雙11了,當天那麼多人同時購物,如果只有一臺mysql定是不夠的,恰好今天使用的軟件amoeba也是阿里巴巴自己員工開發出來的,經過淘寶這麼多用戶的驗證,效果不用懷疑。最後補充一句,Mysql主從複製與我們以前學習的sqlserver複製是一樣的作用。
--------如有不懂的留言評論

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