mysql主從複製以及讀寫分離

以前咱們已經對LNMP平臺的Nginx作過了負載均衡以及高可用的部署,今天咱們就經過一些技術來提高數據的高可用以及數據庫性能的提高。java

1、mysql主從複製mysql

首先咱們先來看一下主從複製可以解決什麼問題。linux

1、數據庫簡介

在如今的世界發展的道路上,數據已是必不可缺的一部分了,對數據的安全性,也成爲了如今的一個值得探討的問題。那有什麼方法可以解決數據的安全性呢?web

咱們經過mysql自己的功能來實現數據的備份,以前咱們也對數據可的數據進行了一些備份,可是那些都不是很好的解決辦法,由於不管以前的導入導出也好,仍是直接對數據庫所在目錄直接進行拷貝,這些技術不能保證明時性,而咱們今天所介紹的就是可以對數據庫實現熱備份,從而提升數據庫的安全性——mysql主從複製算法

2、主從複製原理

1mysql支持的複製類型

1)基於語句的複製。在主服務器上執行的sql語句,在從服務器上執行一樣的語句。mysql默認使用基於語句的複製,效率比其餘方式較高。sql

2)基於行的複製,把改變的內容複製過去,而不是在從服務器上在執行一遍。數據庫

3)混合複製類型,默認採用基於語句的複製,一旦發現基於語句沒法精確複製時,就會採用基於行的複製。vim

2)複製的工做過程

mysql複製的工做過程以下所示:後端

 

1mysql複製的工做過程centos

1)在每一個事務跟新完成以前。master在二進制日誌記錄這些改變。寫入二進制日誌完成後,master通知存儲引擎提交事務。

2SlaveMasterBinary log複製到其中繼日誌。首先,slave打開一個工做線程——I/O線程,I/O線程在Master上打開一個網絡鏈接,而後開始Binlog dump processBinlog dump processMaster的二進制日誌中讀取事件,若是已經成功連接到Master,他會進行睡眠並等待Master產生新的事件。I/O線程將這些事件寫入中繼日誌

3SQL slave thread SQL 從線程)處理該過程的最後一步。SQL線程從中繼日誌讀取事件,並重放其中的事件而更新Slave的數據,使其與Master中的數據一致,只要該線程與I/O線程保持一致,中繼日誌一般會位於OS的緩存中,因此中繼日誌開銷很小。

以上就是mysql主從複製的原理,Slave能夠有多臺,主服務也能夠有多臺,可使用keepalivedHA的高可用性,建議mysql的數據不要只放在共享存儲上,而是每一個Slave都擁有一個單獨的存儲存放數據。

複製的過程當中有一個很重要的限制,即複製在Slave上是串行化的,也就是說Master上的並行更新操做不能在Slave上並行操做,也就是不能同時執行。

3mysql讀寫分離原理

簡單來講就是實現讀與寫的分離(圖2)就是讀在從服務器上讀取數據,在寫數據的時候是寫在主服務上的。基本原理就是讓主服務器處理一些簡單的事務性查詢,而從服務器處理select查詢、數據庫複製被用來把事務性查詢致使的變動同步到集羣的從數據庫中。

 

2

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

1)基於程序代碼內部實現

在代碼中根據select insert進行路由分類,這類方法也是目前生產環境下應用最普遍的。優勢是性能較好,由於程序在代碼中實現,不須要增長額外的硬件開支:缺點是須要開發人員來實現,運維人員無從下手。

2)基於中間代理層實現

代理通常介於應用服務器和數據庫服務器之間,代理數據庫服務器接收到應用服務器的請求後根據判斷後轉發到,後端數據庫,有如下表明性的程序。

1mysql_proxymysql_proxyMysql的一個開源項目,經過其自帶的lua腳本進行sql判斷,雖然是mysql的官方產品,可是mysql官方並不推薦將其部署在生產環境下。

2Atlas。是由 Qihoo 360, Web平臺部基礎架構團隊開發維護的一個基於MySQL協議的數據中間層項目。它是在mysql-proxy 0.8.2版本的基礎上,對其進行了優化,增長了一些新的功能特性。360內部使用Atlas運行的mysql業務,天天承載的讀寫請求數達幾十億條。支持事物以及存儲過程

3Moeeba。由阿里巴巴集團在職員工陳思儒使用序java語言進行開發,阿里巴巴集團將其用戶生產環境下,可是他並不支持事物以及存數過程。

咱們今天所演示的就是amoeba這款軟件。版本2.2.0

2、案例環境

本案例使用5臺服務器搭建,具體拓撲如圖3所示

 

3

 

主機 

操做系統 

IP地址 

主要軟件

Master

CentOS 6.5 x86_64

192.168.1.2

cmake-2.8.6.tar.gz

mysql-5.5.22.tar.gz

Slave1

CentOS 6.5 x86_64

192.168.1.3

cmake-2.8.6.tar.gz

mysql-5.5.22.tar.gz

Slave2

CentOS 6.5 x86_64

192.168.1.4

cmake-2.8.6.tar.gz

mysql-5.5.22.tar.gz

Amoeba

CentOS 6.5 x86_64

192.168.1.1

amoeba-mysql-binary-2.2.0.tar.gz

jdk-6u14-linux-x64.bin

客戶端 

CentOS 6.5 x86_64

192.168.1.5

 

 

以上就是今天的圖撲環境,若是須要解決單點故障的話,可使用前面所講的keepalived實現,只不過多加了幾臺計算機而已。Master也可使用keepalived去避免單點故障,以前已經講過了,這裏就不在過多的進行講解了。

1、配置時間同步

因爲主從複製的時候時間必需要保持一致,這是咱們能夠再master做爲時間同步服務器爲salve提供時間同步。咱們使用rpm方式安裝的ntp軟件包,採用yum的方式安裝

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

[root@centos2 ~]# vim /etc/ntp.conf

server 127.127.1.0

fudge 127.127.1.0 stratum 8   //這兩行在任意地方添加

[root@centos2 ~]# iptables  -I  INPUT - p udp  --dport  123  -j ACCEPT    //ntp  默認使用 udp 123號端口

[root@centos2 ~]# service ntpd start  //啓動ntp服務

客戶端同步時間

 若是沒有ntpdate命令可使用yum安裝ntpdate軟件包

slave1

[root@centos3 ~]# ntpdate  192.168.1.2  以後的服務器同樣。

2、安裝部署mysql服務器

這裏我以slave2服務器爲例演示安裝mysql服務器,master slave1 slave2安裝同樣。

slave2

1)安裝mysql並建立程序用戶

[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

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]#

[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/mysql

5)初始化數據庫

[root@centos4 mysql-5.5.38]# /usr/local/mysql/scripts/mysql_install_db  --user=mysql  --basedir=/usr/local/mysql/  --datadir=/usr/local/mysql/

[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 -p123.abc

3、配置master服務器

1)修改/etc/my.cnf 主配置文件

[root@centos2 ~]# vim /etc/my.cnf

server-id       = 1 //mysql數據的惟一標示(不能重複)

log-slave-updates=true //容許連級複製   (增長)

log-bin=master-bin   //二進制文件名(修改)

2)重啓mysql服務

[root@centos2 ~]# service mysqld restart

3)登陸mysql數據庫

[root@centos2 ~]# mysql -u root -p123.abc

4)創建受權用戶

賦予對全部庫和全部表的replicationslave權限,用戶爲myslave來源爲這個網段的任意IP密碼123.abc  //這個用戶是從數據庫用來複制二進制文件的用戶

mysql> grant  replication  slave  on *.*  to  myslave@'192.168.1.%' identified by '123.abc'; 

5)查看數據庫的二進制文件名和段偏移量的值

 

4

6)退出mysql數據庫

mysql> exit

Bye

7)創建防火牆規則

root@centos2 ~]# iptables  -I  INPUT  -p  tcp  --dport  3306  -j ACCEPT  //容許目標端口爲3306的入站

4、配置從服務器(slave1

1)修改/etc/my.cnf

[root@centos3 ~]# vim /etc/my.cnf

server-id       = 2 //不能與其餘實例重複

log-bin=mysql-bin //二進制日誌文件名

relay-log=relay-log-bin //複製過來的二進制文件名

relay-log-index=slave-relay-bin.index //中繼日誌存放的文件名稱

2)從新啓動mysqld服務

[root@centos3 ~]# service mysqld restart

3)登陸mysql數據庫

[root@centos3 ~]# mysql -u root -p123.abc

4)配置mysql數據同步

mysql> change master  to  master_host='192.168.1.2'  ,  master_user='myslave'  ,  master_password='123.abc'  ,  master_log_file='master-bin.000001'  ,  master_log_pos=261;

ps:最後兩個配置項必定要與圖4的同樣不然不能同步

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

5)啓動同步

mysql> start slave;

6)查看同步信息

 

5

\G  這個選項是讓結果格式化輸出

驗證的結果必定是這兩個值必須都是yes若是通常狀況下出現Slasve_IO_Running: connect  有多是防火牆問題,再不就是上面命令的紅色部分與圖3所顯示的值不一致致使,建議重啓mastermysqld服務以後在顯示值,以後在salve上進行修改。在修改以前請先stop slave; 以後在進行修改,改完以後在啓動複製,在進行驗證

slave2的配置與slave1的配置徹底同樣,建議修改的地方直接複製slave1的配置,在數據庫中操做時注意書寫不要錯誤。

5、安裝amoeba

1)部署jdk環境

[root@centos1 ~]# chmod  +x jdk-6u14-linux-x64.bin

[root@centos1 ~]# ./jdk-6u14-linux-x64.bin

在以後出現的閱讀許可協議的時候直切按q退出就能夠了

最後會出現如下信心

Do you agree to the above license terms? [yes or no] 是否贊成以上許可,這裏咱們直接yes  輸入no則退出安裝

以後會進入一個安裝過程

Press Enter to continue.....  //直接回車完成安裝

安裝完成以後會在當前目錄下產生如下目錄

[root@centos1 ~]# ls  jdk1.6.0_14/  -ld 

drwxr-xr-x. 10 root root 4096 Nov 11 00:54 jdk1.6.0_14/

因爲amoeba是基於jdk1.5所開發的,因此不建議使用高於1.6jdk環境

2)移動安裝目錄

[root@centos1 ~]# mv jdk1.6.0_14/ /usr/local/jdk1.6 

3)修改profile文件

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變量

[root@centos1 ~]# . /etc/profile   //刷新profile文件

4)建立amoeba的解壓目錄

[root@centos1 ~]# mkdir -p /usr/local/amoeba

[root@centos1 ~]# chmod -R 755 /usr/local/amoeba/

5)解壓amoeba軟件包

[root@centos1 ~]# tar zxf amoeba-mysql-binary-2.2.0.tar.gz  -C /usr/local/amoeba/

6)驗證環境變量部署是否正確

[root@centos1 ~]# /usr/local/amoeba/bin/amoeba

amoeba start|stop

出現以上提示則代表環境變量設置正確,jdk已經開始工做了,咱們能夠查看一下jdk的版本

[root@centos1 ~]# javac -version

javac 1.6.0_28

6、配置amoeba實現讀寫分離

聲明:全部配置文件註釋都是以 <!-- 內容 -->,再刪除註釋時請將內容也一併刪除,最好是刪除正行,可是有些時候只須要刪除頭和尾便可,裏面的配置項是能夠直接使用的。

1)修改amoeba安裝目錄下的conf目錄下的amoeba.xml主配置文件

這個配置文件須要定義兩個配置,第一是應用程序使用什麼用戶鏈接amoeba訪問到後端的mysql數據庫,第二個是定義默認寫池以及讀池。

由於配置文件較多,只列出修改的部分

[root@centos1 ~]# vim /usr/local/amoeba/conf/amoeba.xml

<property name="authenticator">

<bean      class="com.meidusa.amoeba.mysql.server.MysqlClientAuthenticator">

<property name="user">amoeba</property>

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

<property name="filter">

<bean class="com.meidusa.amoeba.server.IPAccessController">                                                      <property name="ipFile">${amoeba.home}/conf/access_list.

conf</property>

         </bean>

    </property>

</bean>

</property>

粗體部分是須要修改的部分

<queryRouter class="com.meidusa.amoeba.mysql.parser.MysqlQueryRouter">

 <property name="ruleLoader">

 <bean class="com.meidusa.amoeba.route.TableRuleFileLoader">

<property name="ruleFile">${amoeba.home}/conf/rule.xml</property>

<property name="functionFile">${amoeba.home}/conf/ruleFunctionMap.xml </property>

     </bean>

    </property>

<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>

以上字體加粗部分就是這個配置文件須要修改的內容

2)修改dbServer.xml配置文件,定義寫的服務器以及讀的服務器而且指定算法。

[root@centos1 ~]# vim  /usr/local/amoeba/conf/dbServers.xml

<property name="user">test</property> //26

<property name="password">123.abc</property> // 27

以上兩行爲使用什麼身份訪問後臺數據庫  這個用戶須要在全部數據庫進行授全,權限爲對全部庫的全部表擁有全部權限,而且容許amoeba這臺主機的IP訪問 用戶名不是固定的,根據實際狀況創建。

<dbServer name="master"  parent="abstractServer">

   <factoryConfig>  //定義寫的服務器 這個名字必須與前面定義的寫池保持一致

 <!-- mysql ip -->

 <property name="ipAddress">192.168.1.2</property> //寫服務器的IP

  </factoryConfig>

 </dbServer>

 <dbServer name="slave1"  parent="abstractServer"> //這個名字隨便

 <factoryConfig>

 <!-- mysql ip -->

<property name="ipAddress">192.168.1.3</property>//讀服務器IP

   </factoryConfig>

</dbServer>

 <dbServer name="slave2"  parent="abstractServer">//這個名字隨便

 <factoryConfig>

 <!-- mysql ip -->

 <property name="ipAddress">192.168.1.4</property>//讀服務器的IP

 </factoryConfig>

 </dbServer>

以上部分都是須要修改的,slave2所在的部分是複製slave1的配置

<dbServer name="slaves" virtual="true">//調用主配置文件定義的讀池

 <poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">

<!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA-->

<property name="loadbalance">1</property>

 <!-- Separated by commas,such as: server1,server2,server1 -->

 <property name="poolNames">slave1,slave2</property>//定義讀服務器所在的配置型

    </poolConfig>

</dbServer>

這部份內容是定義讀池負載均衡算法,1表示輪詢、2表示加權輪詢

以上就是全部配置文件的修改以及解釋

3、在masterslave1slave2上創建test用戶,這個用戶須要根據配置文件創建

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

好了,如今能夠將amoeba的服務啓動並驗證

[root@centos1 ~]# amoeba start&  //默認amoeba啓動以後須要佔用一個終端,爲了防止這種狀況發生,咱們能夠直接將其放到後臺運行,在啓動過程當中,若是發現出現很長的提示信息而且都是以java結束,那麼表名服務沒有啓動成功,amoeba默認監聽8066端口,咱們能夠進行驗證

[root@centos1 ~]# netstat -anpt | grep 8066

tcp        0      0 :::8066       :::*                        LISTEN      3405/java  

7、創建防火牆規則

[root@centos1 ~]# iptables -I INPUT -p tcp --dport 8066 -j ACCEPT

8masterslave1slave2都須要開放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

9、測試

1)在應用服務器上

[root@web ~]# yum -y install mysql

經過代理訪問mysql

[root@web ~]# mysql -u amoeba -p123.abc -h 192.168.1.1 -P8066

-P 指定amoeba的默認端口  這樣默認設置須要指定端口,咱們能夠修改amoebaamoeba.xml配置文件的第一個8066改成3306以後創建一條防火牆規則爲容許3306端口入站而且從新啓動amoeba服務

amoeba stop

amoeba start&

<property name="port">3306</property> //11

[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 -p123.abc -h 192.168.1.1

2)在master上建立banji庫,在benji庫中新建class表,看是否同步到其餘服務器上,而後關掉各個服務器上的lave功能,再插入區別語句

Master操做

mysql> create database banji;

mysql> create table banji.class(id int);

slave1操做

 

6

mysql> stop slave;

slave2操做

 

7

mysql> stop slave;

Master操做

mysql> insert into banji.class values(1);

Slave1操做

mysql> insert into banji.class values(2);

Slvae2操做

mysql> insert into banji.class values(3);

client操做

 

8

從上圖能夠看出執行了兩次查詢分別從slave1slave2各自的數據庫中讀取,內容是各自的值,由於沒有同步,因此值只有一個

mysql> insert into banji.class values(4);

 

9

看不到剛插入的4,也就證實了,寫操做在Master咱們能夠去Master上看一下

Master操做

 

10

Master能夠看見剛插入的值,咱們將各個slave的功能開啓

Slave1slave2操做

mysql> start slave;

client操做

 

11

開啓以後咱們看到的數據已經同步了,沒有3,這是由於數據不一致致使的,若是數據一致就不會出現這種狀況了。mysql主從複製以及讀寫分離就OK

總結一下:

①配置主從複製時注意用戶權限、防火牆以及server-id(不能重複)

②配置主從複製時,必定要根據Master的狀態信息填寫change 後面的值

③配置amoeba時注意環境變量不要有書寫錯誤,修改完成以後注意刷新profile文件使其修改生效,可使用echo驗證,也能夠直接啓動amoeba進行驗證,或者驗證jdk版本均可以。

④修改amoeba配置文件時,注意默認讀寫池以及dbServer文件調用時名稱必定要與主配置文件同樣

⑤注意開啓相對應對防火牆端口,若是在登陸的時候麻煩能夠選擇性的修改amoeba的端口使其改成3306這樣在登陸的時候就無需指定端口登錄了。

⑥驗證時必定安裝上面的步驟進行驗證,在測試環境中須要注意不要出現混亂。

mysql服務必定要保證開機自啓動。

若是要解決掉amoebaMaster的單點問題,請使用keepalived工具實現。

相關文章
相關標籤/搜索