zoukankan      html  css  js  c++  java
  • mysql proxy讀寫分流(二)-加入RW splitting

    上一篇中提到 安裝LUA及MySQL Proxy後,接下來就是RW splitting(讀寫分流)的部份了

    整體的概念圖跟上一篇MySQL Proxy安裝方式相同,丫忠再補上一個對應port的圖表:

    針對上圖的架構,首先需要了解幾點基本的觀念:

    • 所有寫入(ADD、UPDATE、DELETE)的動作都是針對MySQL Master
    • 所有讀取(SELECT)的動作都是大部分都是在MySQL Slave(部份在MySQL Master,因為涉及到是否同步完成的關係,請見下面 MySQL Proxy如何解決同步延遲問題 的說明)
    • MySQL Master與MySQL Slave已經建立起 同步(Replication)的機制
    • MySQL Proxy也一個MySQL 的客戶端(Client),也是一個MySQL的伺服器端(Server)

    如果你對於上面的觀念都已經清楚後,對於上圖的流程我想應該很容易了解。丫忠就流程架構做個簡單說明:

    1. 以往 所有應用程式(PHP)存取MySQL都是直接對應至MySQL Master,有了 MySQL Proxy當代理後,現在所有應用程式的連線都是連接至MySQL Proxy
    2. 當MySQL Proxy接收到應用程式的SQL語法後,會自動判斷SQL語法是讀取還是寫入,再分別將寫入的SQL語法對應至MySQL Master、將讀取的SQL語法對應至MySQL Slave
    3. 寫入MySQL Master的資料會透過Replication機制(binlog)同步至所有的MySQL Slave

    看到這裡好像一切都很順利也沒有任何問題,如果你有意識到【當應用程式透過MySQL Proxy寫入資料到MySQL Master後, 此時應用程式又立即讀取剛寫入的資料;但是,MySQL Master還沒有同步至MySQL Slave,那麼應用程式讀取的資料不就是舊的資料嗎?】沒錯,當你有這樣的疑問時,表示你已經深入了解這個架構了,底下先針對MySQl Proxy如何解決同步延遲問題做說明

    MySQL Proxy如何解決同步延遲問題

    解決方式是在MySQL Master上新增一個自增表(count table),當MySQL Master接收到更新資料的動作時便會觸發這個觸發器,這個觸發器會更新自增表(count table)中的記錄,如下圖所示:

    (圖片來源:http://hi.baidu.com)

    因為自增表(count table)也會一起同步(replication)至MySQL Slave,當應用程式透過MySQL Proxy讀取資料時,MySQL Proxy會先向MySQL Master和MySQL Slave的自增表(count table)發送查詢請求,當MySQL Master和MySQL Slave的資料相同時,MySQL Proxy就可以認定MySQL Master和MySQL Slave的資料是一致的,接著把應用程式的請求對應至MySQL Slave主機上,否則就將請求發送至MySQL Master上,如下圖所示:

    (圖片來源:http://hi.baidu.com)

    透過自增表(count table)的方式就可以解決同步延遲的問題,ok~了解整個架構及克服同步延遲的問題後,再來就是實做的部份啦,底下將說明如何啟動MySQL Proxy及設定相關參數

    本章應用一個範例架構來說明RW splitting的應用,架構中架設了一台MySQL Porxy、一台MySQL Master以及二台MySQL Slave,詳細訊息如下:

    MySQL Proxy:192.168.10.250
    MySQL Master:192.168.10.2
    MySQL Slave1:192.168.10.3
    MySQL Slave2:192.168.10.4

    MySQL Proxy開啟後,預設會有2個port(4040及4041),port 4040為接受應用程式的port,port 4041為MySQL Proxy本身的管理port,詳細help的說明可以執行【/usr/local/mysql-proxy/bin/mysql-proxy –help-all】查看

    如何啟動MySQL Proxy

    $ /usr/local/mysql-proxy/bin/mysql-proxy
    > –daemon
    > –keepalive
    > –admin-username=root
    > –admin-password=123456
    > –proxy-backend-addresses=192.168.10.2:3306
    > –proxy-read-only-backend=192.168.10.3:3306
    > –proxy-read-only-backend=192.168.10.4:3306
    > –log-file=/var/log/mysql-proxy.log
    > –log-level=debug
    > –max-open-files=1024
    > –proxy-lua-script=/usr/local/mysql-proxy/lua/rw-splitting.lua

    要啟動MySQL Proxy就加了那麼多參數,代表的又是什麼意思呢?

    • –daemon:指定mysql-proxy為一個daemon(@@)
    • –keepalive丫忠在測試時會有mysql-proxy自動停止服務的情況,加上此參數後就解決這個問題
    • –admin-username:指定MySQL Proxy管理者端(port:4041)的登入帳號
    • –admin-password:指定MySQL Proxy管理者端(port:4041)的登入密碼
    • –proxy-backend-addresses:指定MySQL Master主機的位置及埠號(port)
    • –proxy-read-only-backend:指定MySQL Slave主機的位置及埠號(port),有多台Slave時, 一個 –proxy–read-only-backend 表示一台Slave
    • –log-file:指定儲存MySQL Proxy log的檔案位置
    • –log-level:指定要記錄log的等級
    • –max-open-files:指定最大檔案開啟數為1024,否則為有【could not raise RLIMIT_NOFILE to 8192, Invalid argument (22). Current limit still 1024.】的log訊息出現
    • –proxy-lua-script:指定MySQL Proxy要套用那一個script

    上面的啟動方式,你可以用手動方式輸入啟動;另外,官網也提供了一個init script的shell下載,詳細下載請至 MySQL Proxy init script下載

    再來,啟動MySQL Proxy的參數中有一個 –proxy-lua-script用來指定lua的檔案位置,這個 rw-splitting.lua檔案是 MySQL Proxy重點中的重點,至於要怎麼產生此 rw-splitting.lua呢?rw-splitting.lua檔案在MySQL Proxy原始安裝檔中就已經包含在裡面了,詳細rw-splitting.lua檔案位置在【mysql-proxy-0.8.0/lib/rw-splitting.lua】,請將此檔案拷貝至–proxy-lua-script找的到的位置

    rw-splitting.lua目前尚未有一個穩定的版本,至目前0.8.0為止還在持續修正中,詳細的 Bug或修正內容,有興趣的可以至作者的網站查看( rw-splitting.lua作者),另外也有一個 bug修正的網址 以及針對 MySQL Proxy Lua Script 的主題

    完成MySQL Proxy的啟動後,再來是測試是否MySQL Proxy可以真的達到讀寫分流的功能了,在測試前丫忠建議將 rw-splitting.lua的Debug功能打開,這樣才能清楚了解到 MySQL Proxy的流程及讀寫流程,請直接修改 rw-splitting.lua,將 is_debug = false 改成 is_debug = true,debug的log 會在應用程式執行時顯示出來,詳細修改後,如下圖所示:

    MySQL Proxy測試寫入動作是否同步

    這裡可以寫一個簡單的PHP程式,針對MySQL Proxy做寫入的動作,再至MySQL Master、MySQL Slave1及MySQL Slave2是否有同步更新即可驗證

    $link = mysql_connect(‘192.168.10.250:4040′, ‘root’, ‘root_password’);
    mysql_select_db(‘mytest’);
    $sql=’UPDATE t1 SET t_name=’12345′ WHERE id=1;
    $result = mysql_query( $sql);

    MySQL Proxy測試讀取動作

    丫忠剛開始的測試方式為直接在command下指令 做SELECT的動作;但是,這樣的方式是測試不出來的,錯誤的測試方式如下:

    $ mysql -u root -p -P 4040 -h 192.168.10.250
    mysql>SELECT * FROM t1;

    丫忠再次強調,這樣的方式無法明顯測試出是否有從MySQL Slave讀取資料;而且,debug的記錄不會顯示出來

    丫忠建議寫個簡單的PHP程式,跑個小迴圈,在debug log中就會顯示出 SELECT的資料是從那一台機器提供

    $link = mysql_connect(‘192.168.10.250:4040′, ‘root’, ‘root_password’);
    mysql_select_db(‘mytest’);
    for($i=0;$i<20;$i++){
    $sql=’SELECT * FROM t1′;
    $result = mysql_query( $sql);
    }

    詳細 debug log的訊息就要請網友查看 rw-splitting debug訊息

    另外,rw-splitting.lua 跟讀取較直接相關的參數有2個(min_idle_connections 及 max_idle_connections),可以直接修改這2個參數的值,看看有什麼變化,此部份及詳細分流的部份就要查看 rw-splittinglua 這隻lua程式了

    MySQL Proxy 讀取出來的資料是亂碼

    丫忠在測試過程式有遇到此問題,最後是修改 /etc/my.cnf 設定檔中,加入底下設定,即可解決亂碼問題(當然您要依據您的環境做修改)

    default-character-set = utf8
    skip-character-set-client-handshake
    character-set-server = utf8
    collation-server = utf8_general_ci
    init-connect = SET NAMES utf8

    本文相關的文章

      1. mysql proxy讀寫分流(一)-mysql proxy的安裝方式
      2. MySQL Slave_SQL_Running NO的解決方式
      3. MySQL Replication(Master Slave負載平衡)
      4. mysql 臨時表temporary table
      5. mysql(my.cnf)設定檔說明(二)
      6. mysql(my.cnf)設定檔說明
  • 相关阅读:
    MySql 有用的函数
    mysql 触发器
    java之switch语句
    MaxAlertView 强大的弹框试图
    AVMoviePlayer 视频播放器
    Mac下不能安装第三方下载软件
    HTTPS链式编程——AFNetworking 3.0
    iOS推送证书生成pem文件(详细步骤)
    iOS成长之路-使用系统默认声音、震动
    iOS 怎么自定制推送声音呢?(APP运行时和APP进入后台时)
  • 原文地址:https://www.cnblogs.com/seasonzone/p/3454854.html
Copyright © 2011-2022 走看看