天天看點

MySQL 5.6通過MMM實作讀寫分離的高可用架構

上一篇博文我們使用keepalived+主從同步搭建了一個簡單的MySQL高可用架構(詳見http://blog.51cto.com/jiangjianlong/1981994),今天再分享下通過MMM搭建的實作MySQL讀寫分離的高可用群集。MMM (Master-Master Replication Manager for MySQL)是使用perl開發的MySQL主主複制管理器,可實作讀寫分離的高可用架構,對主庫實作寫請求的高可用,對從庫實作讀請求的負載均衡。本文的架構示意圖如下:

一、部署環境

二、環境準備

1、配置好IP位址、主機名,關閉防火牆和selinux

3、為5台伺服器配置好hosts解析:

192.168.10.81 mysql-master01

192.168.10.82 mysql-master02

192.168.10.83 mysql-slave01

192.168.10.84 mysql-slave02

192.168.10.85 mysql-monitor

4、将RedHat 6.5的媒體配置成本地yum源

三、配置兩台master互為主從

1、編輯mysql-master01和mysql-master02的/etc/my.cnf檔案并重新開機mysql服務:

mysql-master01:

1

2

3

4

5

6

7

8

9

10

11

<code>[mysqld] </code>

<code>server-</code><code>id</code><code>=1              </code><code>#每台設定不同</code>

<code>log-bin=mysql-bin</code>

<code>[mysqld_safe]</code>

<code>auto_increment_increment=2  </code><code>#字段一次遞增多少 </code>

<code>auto_increment_offset=1    </code><code>#自增字段的起始值,master02需設定為2 </code>

<code>replicate-</code><code>do</code><code>-db=all        </code><code>#同步的資料庫,多個用逗号隔開 </code>

<code>log-slave_updates        </code><code>#當一個主故障,另一個立即接管 </code>

<code>sync</code><code>-binlog=1            </code><code>#每條自動更新,安全性高,預設是0 </code>

<code>log-error = </code><code>/var/log/mysqld</code><code>.log</code>

<code>read_only = 1</code>

mysql-master02:

<code>server-</code><code>id</code><code>=2              </code><code>#每台設定不同 </code>

<code>log-bin=mysql-bin </code>

<code>auto_increment_increment=2  </code><code>#字段一次遞增多少</code>

<code>auto_increment_offset=2    </code><code>#自增字段的起始值,master02需設定為2</code>

<code>replicate-</code><code>do</code><code>-db=all        </code><code>#同步的資料庫,多個用逗号隔開</code>

<code>log-slave_updates       </code><code>#當一個主故障,另一個立即接管</code>

<code>sync</code><code>-binlog=1            </code><code>#每條自動更新,安全性高,預設是0</code>

2、在mysql-master01上建立用于同步的賬戶repl,密碼為123456,并查詢master狀态,記下file名稱和posttion數值

mysql&gt; GRANT REPLICATION SLAVE ON *.* to 'repl'@'%' identified by '123456';

mysql&gt; show master status;

3、在mysql-master02上登入mysql,執行以下語句開啟從伺服器

mysql&gt; change master to master_host='192.168.10.81',master_user='repl',master_password='123456',master_log_file='mysql-bin.000003',master_log_pos=318;

mysql&gt; start slave;

mysql&gt; show slave status\G

4、然後在mysql-master02上也建立用于同步的賬戶repl,密碼為123456,并查詢master狀态,記下file名稱和posttion數值

5、在mysql-master01上登入mysql執行以下語句開啟從伺服器,注意這裡master_host要填寫mysql-master02的IP

mysql&gt; change master to master_host='192.168.10.82',master_user='repl',master_password='123456',master_log_file='mysql-bin.000006',master_log_pos=318;  

6、這樣兩台master的互為主從就配置好了,下面我們來測試一下,先做mysql-master01上執行以下語句建立一個資料庫、一個表并插入一行資料

mysql&gt; create database names_test;

mysql&gt; use names_test;

mysql&gt; create table names(id int(5),name char(15));

mysql&gt; insert into names values (01,'jiangjianlong');

mysql&gt; select * from names;

7、然後到mysql-master02上查詢一下,發現已經同步完成了,說明mysql-master02作為mysql-master01的從庫複制正常

8、在mysql-master02上也建立一個資料庫、一個表并插入一行資料

mysql&gt; create database blogs_test;

mysql&gt; use blogs_test;

mysql&gt; create table blogs(id int(5),name char(35));

mysql&gt; insert into blogs values (01,'jiangjianlong.blog.51cto.com');

9、在mysql-master01上查詢一下,發現資料也已經同步過來,說明mysql-master01作為mysql-master02的從庫也是複制正常

四、配置兩台slave作為master01的從庫

1、mysql-slave01和mysql-slave02分别使用以下my.cnf

mysql-slave01:

<code>[mysqld]</code>

<code>server-</code><code>id</code><code>=3              </code><code>#每台設定不同</code>

<code> </code> 

<code>replicate-</code><code>do</code><code>-db=all         </code>

mysql-slave02:

<code>server-</code><code>id</code><code>=4             </code><code>#每台設定不同</code>

2、根據在mysql-master01上執行show master status查出來的結果,在mysql-slave01和mysql-slave02上分别執行以下sql語句,開啟從伺服器:

mysql&gt; change master to master_host='192.168.10.81',master_user='repl',master_password='123456',master_log_file='mysql-bin.000004',master_log_pos=120;

五、安裝MMM要求的Perl子產品

1、MMM對所有MySQL節點所要求的Perl子產品如下:

2、以下以mysql-master01為例進行perl子產品的安裝,另外3台MySQL伺服器同理。首先檢視一下這些perl子產品還有哪些沒裝:

perldoc -l Algorithm::Diff  DBI  DBD::mysql File::Basename File::stat Log::Dispatch Log::Log4perl Mail::Send Net::ARP Proc::Daemon Time::HiRes

3、部分缺失的perl子產品在Redhat6.5的媒體中有,可以通過本地yum源的方式安裝

[root@mysql-master01 ~]# yum install perl-DBI perl-DBD-mysql perl-MailTools perl-Time-HiRes perl-CPAN -y

4、使用以下指令再檢視一下安裝結果

5、剩下的幾個perl子產品安裝起來稍微麻煩一點,可以使用源碼包編譯安裝,也可以使用cpan線上自動下載下傳安裝,并能處理各子產品間的依賴關系。我一開始是嘗試去下載下傳源碼包後手動進行編譯安裝,然而我在編譯到Log::Dispatch時我直接放棄這種方式了,因為它依賴于很多個其它的perl子產品,而這些子產品可能又依賴于别的多個子產品!如下圖:

6、是以我決定使用cpan線上自動安裝的方式,但需要伺服器能連外網。由于使用cpan安裝Algorithm::Diff時會告警提示YAML沒有安裝,是以我先使用cpan安裝YAML,而安裝YAML時會把它所依賴的Algorithm::Diff給裝上

7、接着執行cpan Log::Dispatch安裝Log::Dispatch,沒想到在自動下載下傳安裝了50多個依賴子產品後還是報錯提示有多個依賴的子產品缺失,如下圖:

8、解決辦法:依次使用cpan安裝上圖所示的缺少的子產品,然後再執行cpan Log::Dispatch就能成功安裝上,如果cpan安裝Params::ValidationCompiler時報錯,就單獨下載下傳這個子產品的源碼包進行編譯安裝

9、執行cpan Log::Log4perl安裝Log::Log4perl子產品、執行cpan Net::ARP安裝Net::ARP子產品、執行cpan Proc::Daemon安裝Proc::Daemon子產品

10、再來檢視下所需perl子產品的安裝結果,這下已經全部都裝好了

11、monitor伺服器也對perl子產品有要求,如下圖:

12、同樣是使用cpan安裝這些子產品,在此不再贅述。4台mysql伺服器和monitor伺服器的perl子產品都安裝完成後,我們就可以來安裝配置MMM了

六、MySQL-MMM安裝配置

1、MMM對MySQL使用者的要求如下:

2、由于本文未使用到MMM tools,是以隻需建立前3個使用者,由于前面已經做好了主從同步,是以隻需要在mysql-master01上建立即可同步到另外3台MySQL伺服器

GRANT REPLICATION CLIENT ON *.* TO 'mmm_monitor'@'192.168.10.%' IDENTIFIED BY 'monitor'; 

GRANT SUPER,REPLICATION CLIENT,PROCESS ON *.* TO 'mmm_agent'@'192.168.10.%' IDENTIFIED BY'agent';

GRANT REPLICATION SLAVE ON *.* TO 'mmm_repl'@'192.168.10.%' IDENTIFIED BY'repl';

注:其實使用者mmm_repl可以不用建,因為前面我們配置主從同步時已經建了一個repl使用者可供使用

3、使用以下語句檢查另外3台MySQL伺服器是否已同步了這3個使用者,可以看到都已經有了

select user,host from mysql.user where user in ('mmm_monitor','mmm_agent','mmm_repl');

4、在4台MySQL伺服器和monitor伺服器上編譯安裝MMM,下面以mysql-master01為例

[root@mysql-master01 ~]# tar -zxf mysql-mmm-2.2.1.tar.gz -C /usr/

[root@mysql-master01 ~]# cd /usr/mysql-mmm-2.2.1/

[root@mysql-master01 mysql-mmm-2.2.1]# make install

5、安裝完成後,所有的配置檔案都放到了/etc/mysql-mmm/下面。monitor伺服器和MySQL伺服器上都要包含一個共同的檔案mmm_common.conf,内容如下:

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

<code>[root@mysql-master01 mysql-mmm-2.2.1]</code><code># cat /etc/mysql-mmm/mmm_common.conf</code>

<code>active_master_role        writer</code>

<code>  </code> 

<code>&lt;host default&gt;</code>

<code>cluster_interface                eth0</code>

<code>pid_path                                </code><code>/var/run/mmm_agentd</code><code>.pid</code>

<code>bin_path                                </code><code>/usr/lib/mysql-mmm/</code>

<code>    </code><code>replication_user        mmm_repl</code>

<code>    </code><code>replication_password    repl</code>

<code>agent_user                            mmm_agent</code>

<code>agent_password                        agent</code>

<code>&lt;</code><code>/host</code><code>&gt;</code>

<code>&lt;host mysql-master01&gt;</code>

<code>ip                                          192.168.10.81</code>

<code>mode                                        master</code>

<code>peer                                        mysql-master02</code>

<code>&lt;host mysql-master02&gt;</code>

<code>ip                                          192.168.10.82</code>

<code>peer                                        mysql-master01</code>

<code>&lt;host mysql-slave01&gt;</code>

<code>ip                                          192.168.10.83</code>

<code>mode                                        slave</code>

<code>&lt;host mysql-slave02&gt;</code>

<code>        </code><code>ip                                   192.168.10.84</code>

<code>        </code><code>mode                                 slave</code>

<code>&lt;role writer&gt;</code>

<code>hosts                                        mysql-master01, mysql-master02</code>

<code>ips                                          192.168.10.91</code>

<code>mode                                        exclusive</code>

<code>&lt;</code><code>/role</code><code>&gt;</code>

<code>&lt;role reader&gt;</code>

<code>hosts                                        mysql-slave01, mysql-slave02</code>

<code>ips                                          192.168.10.93, 192.168.10.94</code>

<code>mode                                        balanced</code>

<code>[root@mysql-master01 mysql-mmm-2.2.1]</code><code>#</code>

6、在mysql-master01上編輯好該檔案後,通過scp傳輸到另外4台伺服器

7、4台MySQL伺服器還有一個mmm_agent.conf檔案需要修改主機名

8、在4台MySQL伺服器的 /etc/init.d/mysql-mmm-agent的腳本檔案的#!/bin/sh下面,加入如下内容 

source /root/.bash_profile,下面以mysql-master01為例

9、分别将4台MySQL伺服器的mmm_agent啟動腳本添加成系統服務并設定為自啟動,下面以mysql-master01為例

#chkconfig --add mysql-mmm-agent

#chkconfig mysql-mmm-agent on

10、分别将4台MySQL伺服器的mmm_agent啟動,如果前面的Perl子產品沒有裝好,可能會報錯啟動不了

/etc/init.d/mysql-mmm-agent start或service mysql-mmm-agent start

11、配置monitor伺服器上的mmm_mon.conf檔案

<code>[root@mysql-monitor mysql-mmm]</code><code># cat/etc/mysql-mmm/mmm_mon.conf </code>

<code>include</code>

<code>mmm_common.conf</code>

<code>&lt;monitor&gt;</code>

<code>        </code><code>ip                  127.0.0.1</code>

<code>        </code><code>pid_path               </code><code>/var/run/mmm_mond</code><code>.pid</code>

<code>        </code><code>bin_path               </code><code>/usr/lib/mysql-mmm/</code>

<code>        </code><code>status_path              </code><code>/var/lib/misc/mmm_mond</code><code>.status</code>

<code>        </code><code>ping_ips               192.168.10.81,192.168.10.82,192.168.10.83,192.168.10.84</code>

<code>&lt;</code><code>/monitor</code><code>&gt;</code>

<code>        </code><code>monitor_user                  mmm_monitor</code>

<code>        </code><code>monitor_password                monitor</code>

<code>&lt;check default&gt;</code>

<code>       </code><code>check_period   5</code>

<code>       </code><code>trap_period   10</code>

<code>       </code><code>timeout       3</code>

<code>       </code><code>max_backlog   86400</code>

<code>&lt;</code><code>/check</code><code>&gt;</code>

<code>debug 0</code>

12、在monitor伺服器的 /etc/init.d/mysql-mmm-monitor的腳本檔案的#!/bin/sh下面,加入如下内容 

source /root/.bash_profile

13、将mysql-mmm-monitor添加成系統服務并設定為自啟動

#chkconfig --add mysql-mmm-monitor

#chkconfigmysql-mmm-monitor on

14、啟動monitor伺服器的mysql-mmm-monitor服務

15、在monitor伺服器執行指令列出用戶端狀态,發現都是AWAITING狀态

16、在monitor伺服器執行指令mmm_control set_online mysql-master01,将mysql-master01上線,過一會再看它就變成online狀态了

17、這時觀察mysql-master01的IP發現已經成功添加了Write VIP

18、依次将mysql-master02和mysql-slave01以及mysql-slave02設定為online,檢視slave的IP也發現Read VIP也加上了。MMM到此已配置完成,下面将進行高可用測試

七、MySQL-MMM主庫高可用測試

1、将mysql-master01的mysql服務停止,模拟主庫當機,再檢視IP會發現Write VIP已被自動移除

2、觀察monitor伺服器上的日志可以發現MMM檢測到mysql-maste01故障并将Write VIP切換到了mysql-master02上

3、檢視mysql-master02的IP,發現Write VIP确實已添加上了

4、這時兩台slave之前配置的主庫已經當機并且主庫已切換,那它們是否會自動将Master Host也切換為mysql-master02呢?檢視下它們的slave狀态,發現已自動切換

5、在monitor伺服器上檢視下用戶端的狀态,mysql-master01确實已離線,并且是能Ping通而mysql連接配接失敗

6、再次啟動master01的mysql服務,并設定為online,可以看到Write VIP并不會回切(除非目前的主庫再次當機)

7、觀察到monitor伺服器的日志如下:

8、再檢查下用戶端,已恢複正常

八、MySQL-MMM從庫高可用測試

1、将mysql-slave01的mysql服務停止,模拟從庫當機,再檢視IP會發現其上的Read VIP已被自動移除

2、觀察到monitor伺服器上的日志發現mysql-slave01的Read VIP已被切換到mysql-slave02上:

3、在monitor伺服器上檢視用戶端狀态,發現mysql-slave02确實綁定了2個Read VIP

4、檢查mysql-slave02的IP,确實如此

5、将mysql-slave01的mysql服務恢複啟動,并在monitor伺服器将其設定為online,可以看到切換回去的Read VIP并不是最開始的那個VIP,Read VIP并非固定不變

6、觀察monitor伺服器的日志内容如下:

7、兩個slave的IP資訊現在如下:

至此,MySQL-MMM讀寫分離的高可用架構經簡單測試均OK!以下是小結:

1、若master01主節點當機,由master02備選主節點接管寫角色,slave1,slave2指向新master2主庫進行複制,slave01,slave02會自動change master到master02。

2、若master01主節點當機,而master02同步又落後于master01時就變成了主可寫狀态,則這時的資料主無法保證一緻性。

3、若master02,slave01,slave02延遲于master01主,而這個時master01當機,slave01,slave02将會等待資料追上master01後,再重新指向新的主master02進行複制操作,這時的資料也無法保證同步的一緻性。

4、對外提供讀寫的虛拟IP是由monitor程式控制。如果monitor沒有啟動那麼db伺服器不會被配置設定虛拟ip,但是如果已經配置設定好了虛拟ip,當monitor程式關閉了,則原先配置設定的虛拟ip不會關閉,隻要不重新開機網絡,外部程式還可以連接配接通路,這樣能對monitor的可靠性要求降低一些,但是如果這時其中的某一個db伺服器故障了就無法處理切換。因為agent程式受monitor程式的控制,處理主庫切換、從庫切換等操作。如果monitor程序關閉了那麼agent程序就起不到什麼作用,它本身不能處理故障。

5、monitor程式負責監控db伺服器的狀态,包括Mysql資料庫、伺服器是否運作、複制線程是否正常、主從延時等,以及控制agent程式處理故障。是以monitor是這個高可用架構中的核心角色,同時也是單點故障的風險點,應該能通過keepalived等方式将monitor也做成高可用,等以後有時間我再進行測試。

6、monitor監控端的配置檔案參數“auto_set_online”可以讓從故障中恢複的節點自動online,待有空測試下。群集中節點伺服器的狀态有三種分别是:HARD_OFFLINE→AWAITING_RECOVERY→online

7、預設monitor會控制mmm_agent會将writer db伺服器read_only修改為OFF,其它的db伺服器read_only修改為ON,是以為了嚴謹可以在所有的伺服器的my.cnf檔案中加入read_only=1,由monitor控制writer和read,root使用者和複制使用者不受read_only參數的影響。

本文出自江健龍的技術部落格,轉載請注明出處 http://blog.51cto.com/jiangjianlong/2073744

本文轉自Mr大表哥jianlong1990 部落格,原文連結:  http://blog.51cto.com/jiangjianlong/2073744     如需轉載請自行聯系原作者