天天看點

mycat讀寫分離與主從切換

什麼是mycat,以及mycat的優點和特性本文不做贅述,本文繼續本着實戰的态度,來分享一些個人對mycat的基礎功能實踐。本文mycat的讀寫分離和主從切換的環境為mysql主從環境。

本文的環境資訊:

192.168.1.248 slave

192.168.1.250 master

主從配置完成後,Slave_IO_Running和Slave_SQL_Running狀态都為yes

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

<code>mysql&gt; start slave;</code>

<code>Query OK, 0 </code><code>rows</code> <code>affected (0.02 sec)</code>

<code>mysql&gt; show slave status\G</code>

<code>*************************** 1. row ***************************</code>

<code>               </code><code>Slave_IO_State: Waiting </code><code>for</code> <code>master </code><code>to</code> <code>send event</code>

<code>                  </code><code>Master_Host: 192.168.1.250</code>

<code>                  </code><code>Master_User: mysync</code>

<code>                  </code><code>Master_Port: 3306</code>

<code>                </code><code>Connect_Retry: 60</code>

<code>              </code><code>Master_Log_File: mysql-bin.000004</code>

<code>          </code><code>Read_Master_Log_Pos: 429</code>

<code>               </code><code>Relay_Log_File: HE1-relay-bin.000002</code>

<code>                </code><code>Relay_Log_Pos: 592</code>

<code>        </code><code>Relay_Master_Log_File: mysql-bin.000004</code>

<code>             </code><code>Slave_IO_Running: Yes</code>

<code>            </code><code>Slave_SQL_Running: Yes</code>

建立mycat用到的dataNode對應的資料庫及mycat用到的資料庫使用者

<code>mysql&gt; </code><code>grant</code> <code>all</code> <code>privileges</code> <code>on</code> <code>*.* </code><code>to</code> <code>'mycat'</code><code>@</code><code>'%'</code> <code>identified </code><code>by</code> <code>'MANAGER'</code><code>;</code>

<code>Query OK,0 </code><code>rows</code> <code>affected (0.01 sec)</code>

<code> </code> 

<code>mysql&gt; flush </code><code>privileges</code><code>;</code>

<code>Query OK,0 </code><code>rows</code> <code>affected (0.00 sec)</code>

<code>mysql&gt; </code><code>create</code> <code>database</code> <code>db1;</code>

<code>Query OK,1 row affected (0.00 sec)</code>

<code>mysql&gt; </code><code>create</code> <code>database</code> <code>db2;</code>

<code>Query OK,1 row affected (0.01 sec)</code>

<code>mysql&gt; </code><code>create</code> <code>database</code> <code>db3;</code>

配置環境變量

[root@HE3 ~]# echo export PATH=$PATH:/usr/local/mycat/bin &gt;&gt;/etc/profile

[root@HE3 ~]# echo export MYCAT_HOME=/usr/local/mycat &gt;&gt; /etc/profile

[root@HE3 ~]# source /etc/profile

配置/etc/my.cnf中增加參數并重新開機資料庫服務

lower_case_table_names=1

安裝jdk7

[root@HE3 ~]# rpm -ivh jdk-7u79-linux-x64.rpm

Preparing...                ########################################### [100%]

   1:jdk                    ########################################### [100%]

Unpacking JAR files...

rt.jar...

jsse.jar...

charsets.jar...

tools.jar...

localedata.jar...

jfxrt.jar...

安裝mycat

[root@HE3 ~]# tar xvf Mycat-server-1.5.1-RELEASE-20160816173057-linux.tar.gz -C /usr/local

[root@HE3 ~]# groupadd mycat -g 910

[root@HE3 ~]# useradd  mycat -g 910

[root@HE3 ~]# chown -R mycat:mycat /usr/local/mycat

修改必要的配置并啟動

[root@HE3 ~]# cd  /usr/local/mycat/conf

[root@HE3 conf]# vim schema.xml

配置table,來決定table分片對應哪個dataNode還是global表,以及分片規則和片鍵

修改第43行的dataHost标簽中的writeHost的url  10.10.10.250及使用者名mycat和密碼MANAGER

<a href="http://s3.51cto.com/wyfs02/M02/87/6F/wKiom1ffj-KRq-rjAACwDD2_qEI607.png" target="_blank"></a>

啟動mycat

[root@HE3 bin]# cd /usr/local/mycat/bin

[root@HE3 bin]# mycat start

Starting Mycat-server...

觀察wrapper.log檔案中提示啟動成功即可

[root@HE3 bin]# cd /usr/local/mycat/log

<a href="http://s4.51cto.com/wyfs02/M02/87/6C/wKioL1ffkUzCVPSuAABpI9njY4E418.png" target="_blank"></a>

配置mycat

[root@HE3 conf]# vi /usr/local/mycat/conf/schema.xml

因為要涉及到實驗主節點失敗,write節點指向原從節點,是以要把主從節點都設定成writeHost

有關讀寫分離分發規則的相關dataHost标簽屬性balance值:

負載均衡類型,目前取值有3種:

(1) balance="0", 不開啟讀寫分離機制,所有讀操作都發送到目前可用的writeHost上。

(2) balance="1",全部的readHost與stand by writeHost 參與select語句負載均衡,簡單的說,當雙主雙從模式(M1-&gt;S1,M2-&gt;S2,并且M1與M2互為主備),正常情冴下,M2,S1,S2 都參與select語句的負載

均衡。(類似于balance=3,讀操作隻分發到除了真正的主節點之外的所有節點)

(3) balance="2",所有讀操作都随機的在 writeHost、 readhost 上分發。(常用些,在所有主從節點上分發讀請求)

(4) balance="3",所有讀請求随機的分發到 writeHost 對應的readhost執行,writeHost不負擔讀壓

力,注意 balance=3 叧在 1.4 及其以後版本有,1.3 沒有。(常用些,隻在從節點上分發讀請求)

注:事務内的sql,預設走寫節點,以注釋/*balance*/開頭,則會根據balance值決定

在本例中balance值設定為1,但是這個場景設定成3效果應該是一樣的

有關主從(讀寫角色)切換設定屬性規則的相關dataHost标簽屬性switchType值:

(1)-1表示不自動切換

(2)1預設值,自動切換

(3)2基于mysql主從同步的狀态決定是否切換

(4)3基于cluster的切換,心跳語句要改成show status like 'wsrep%',這個裡面配置的都是writehost

在本例中switchType值設定為1,表示自動切換,某些對主從資料一緻要求較高的場景,建議使用2判斷主從狀态後再切換,或者使用galera cluster保證各節點資料一緻然後将此值設定為3

切換的觸發條件為主節點mysql服務崩潰或停止(暫時是這麼了解的,希望批改的同學能給我解答一下)。

slaveThreshold 主從的延遲在多少秒以内,則把讀請求分發到這個從節點,否則不往這個節點分發,假設生産環境能容忍的主從延時為60秒,則設定此值為60,此例中設定值為100

有關寫請求是否分發到多個寫節點規則的相關dataHost标簽屬性writeType值:

(1) 值0表示隻分發到目前的主節點

(2) 值1表示分發到所有設定為writeHost的節點,不推薦使用,好像現在版本已經廢除

此例中writeType值使用預設值0,寫請求隻分發到主節點,不會分發到其他的writeHost上

這裡我們變更45行的心跳檢測為show slave status,來友善之後我們的讀寫分離校驗

<a href="http://s2.51cto.com/wyfs02/M01/87/6D/wKioL1ffmzqDXCsOAABjNYo2wyM603.png" target="_blank"></a>

驗證讀寫分離效果

寫操作

主節點上:

<code>mysql&gt; show </code><code>global</code> <code>status </code><code>like</code> <code>'%Com_in%'</code><code>;</code>

<code>+</code><code>--------------------+-------+</code>

<code>| Variable_name      | Value |</code>

<code>| Com_insert         | 13    |</code>

<code>| Com_insert_select  | 0     |</code>

<code>| Com_install_plugin | 0     |</code>

<code>3 </code><code>rows</code> <code>in</code> <code>set</code> <code>(0.00 sec)</code>

從節點上:

寫入insert:

<code>mysql&gt; </code><code>insert</code> <code>into</code> <code>travelrecord(id,</code><code>name</code><code>)</code><code>values</code><code>(10000005,</code><code>'ddd'</code><code>);</code>

<code>Query OK, 1 row affected (0.00 sec)</code>

可以看到幾次插入的結果都落到了節點192.168.1.250也就是master上

也可以使用show global status like ‘Com_insert’;檢視主從mysql上的insert請求,如果兩者都增加,說明請求分發到了主上,并複制到了從上,如果請求分發到了從上,那麼就不會複制到主上,結果就是主上的這個狀态變量不會增加,隻有從上的這個狀态變量會增加。

讀操作

執行select之前

主節點:

<code>mysql&gt; show </code><code>global</code> <code>status </code><code>like</code> <code>'Com_select'</code><code>;</code>

<code>+</code><code>---------------+-------+</code>

<code>| Variable_name | Value |</code>

<code>| Com_select    | 1334  |</code>

<code>1 row </code><code>in</code> <code>set</code> <code>(0.00 sec)</code>

從節點:

<code>| Com_select    | 385   |</code>

執行select語句:

<code>mysql&gt; </code><code>select</code> <code>* </code><code>from</code> <code>travelrecord </code><code>where</code> <code>id=1;</code>

<code>+</code><code>----+------+------+</code>

<code>| id | </code><code>name</code> <code>| age  |</code>

<code>|  1 | aaa  | </code><code>NULL</code> <code>|</code>

<code>mysql&gt; show global status like </code><code>'Com_select'</code><code>;</code>

<code>+---------------+-------+</code>

<code>| Com_select    | 386   |</code>

都落在了hostS1也就是slave上

多測幾次也是以上的效果,說明符合了balance=1的效果,讀請求分發到了除主節點以外的節點(即從節點)。

驗證自動切換

停止目前主節點mysql服務

<code>[root@HE3 conf]</code><code># cat dnindex.properties </code>

<code>#update</code>

<code>#Mon Sep 12 00:28:33 PDT 2016</code>

<code>localhost1=0</code>

<code>[root@HE3 conf]</code><code># /etc/init.d/mysqld stop</code>

<code>Shutting down MySQL............ SUCCESS!</code>

觀察dnindex.properties檔案内容是否變化

<code>#Mon Sep 12 18:32:28 PDT 2016</code>

<code>localhost1=1</code>

目前可用節點隻剩下原從節點,期望結果是之後的寫入操作全部落到原從節點,驗證:

<code>mysql&gt; </code><code>insert</code> <code>into</code> <code>travelrecord </code><code>values</code><code>(3,</code><code>'helei'</code><code>,25);</code>

<code>ERROR 1064 (HY000): partition </code><code>table</code><code>, </code><code>insert</code> <code>must provide ColumnList</code>

<code>mysql&gt; </code><code>insert</code> <code>into</code> <code>travelrecord(id,</code><code>name</code><code>,age) </code><code>values</code><code>(3,</code><code>'helei'</code><code>,25);</code>

<code>Query OK, 1 row affected (0.37 sec)</code>

登入原從節點,觀察資料變化:

17

18

19

20

21

<code>mysql&gt; use db1;</code>

<code>Reading </code><code>table</code> <code>information </code><code>for</code> <code>completion </code><code>of</code> <code>table</code> <code>and</code> <code>column</code> <code>names</code>

<code>You can turn </code><code>off</code> <code>this feature </code><code>to</code> <code>get a quicker startup </code><code>with</code> <code>-A</code>

<code>Database</code> <code>changed</code>

<code>mysql&gt; show tables;</code>

<code>+</code><code>---------------+</code>

<code>| Tables_in_db1 |</code>

<code>| travelrecord  |</code>

<code>mysql&gt; </code><code>select</code> <code>* </code><code>from</code> <code>travelrecord;</code>

<code>+</code><code>---------+-------+------+</code>

<code>| id      | </code><code>name</code>  <code>| age  |</code>

<code>|       1 | aaa   | </code><code>NULL</code> <code>|</code>

<code>|       2 | asd   | </code><code>NULL</code> <code>|</code>

<code>|       3 | helei |   25 |</code>

<code>| 5000000 | bbb   |   11 |</code>

<code>4 </code><code>rows</code> <code>in</code> <code>set</code> <code>(0.00 sec)</code>

說明此時寫入節點已經切換為配置好的第二個writeHost,也就是原從節點,此時如果想要将原失敗節點重新加入叢集,需要重做主從,将原主節點作為從節點加入到叢集中,mycat無需重新開機,對前端應用是透明的。

 本文轉自 dbapower 51CTO部落格,原文連結:http://blog.51cto.com/suifu/1854298,如需轉載請自行聯系原作者