Mysql-proxy實現MariaDB讀寫分離

Mysql Proxy 簡介mysql


 MySQL Proxy是一個處於你的client端和MySQL server端之間的簡單程序,它能夠監測、分析、或改變它們的通訊。它使用靈活,沒有限制,常見的用途包括:負載平衡,故障、查詢分析,查詢過濾或修改等等。
linux

 MySQL Proxy就是這麼一箇中間層代理,簡單的說,MySQL Proxy就是一個鏈接池,負責前臺應用的鏈接請求轉發給後臺的數據庫,而且經過使用lua腳本,能夠實現複雜的鏈接控制和過濾,從而實現讀寫分離和負載平衡。對於應用來講,MySQL Proxy是徹底透明的,應用則只須要鏈接到MySQL Proxy的監聽端口便可。固然,這樣proxy機器可能成爲單點故障,但徹底可使用多個proxy機器作冗餘,在應用服務器和鏈接池配置中配置多個proxy的鏈接參數便可。redis


 MySQL Proxy更強大的一項功能就是實現"讀寫分離",基本原理就是讓主數據庫處理事務性查詢,讓從服務器進行SELECT查詢。數據庫複製被用來把事務性查詢致使的變動同步到集羣的從庫中。sql



MySQL Proxy安裝方式數據庫


 1、源碼安裝vim

  一、源碼安裝時,MySQL proxy的依賴關係:後端

     libevent 1.x or higher bash

     lua 5.1x or higher服務器

     glib2 2.6.0 or higher架構

     pkg-config.

     libtool 1.5 or higher

     MySQL 5.0.x or higher developer files

     

    二、安裝

     # tar xf mysql-proxy-0.8.2.tar.gz

     # cd mysql-proxy-0.8.2

     # ./configure

     # make

     # make check

     若是管理員有密碼,上面的步驟則須要使用以下格式進行:

     #MYSQL_PASSWORD=root_pwd make check

     

     # make install

     默認狀況下,mysql-proxy安裝在/usr/local/sbin/mysql-proxy,而Lua示例腳本安裝在/usr/local/share目錄中


  二 、通用二進制格式安裝

   

     一、下載,當前系統架構爲 Centos6.5 64位系統

http://mirrors.sohu.com/mysql/MySQL-Proxy/mysql-proxy-0.8.4-linux-el6-x86-64bit.tar.gz    

     二、解壓

      #tar  xf mysql-proxy-0.8.4-linux-e16-x86-64bit.tar.gz

      #mv mysql-proxy-0.8.4-linux-e16-x86-64bit /usr/local/mysql-proxy

     三、添加代理用戶

      # useradd mysql-proxy

     四、爲mysql-proxy提供SysV服務腳本

     

     五、爲mysql-proxy腳本提供配置文件




MySQL Proxy實現讀寫分離


    環境搭建

        wKioL1NzYoHhEAEjAAEOHQfKrzE087.jpg

       

 如上圖所示

 

MySQL Master 主服務器 172.16.13.13 MariaDB-5.5.36
MySQL Slave  從服務器 172.16.13.14 MariaDB-5.5.36
MySQL  Proxy 代理服務器 172.16.13.2 mysql-proxy-0.8.4-linux-el6-x86-64bit.tar.gz

     


1、MySQL主從複製架構的實現


    關於MySQL主從複製的實現詳情請參考個人博客:

   http://jungege.blog.51cto.com/4102814/1396276



2、MySQL Proxy服務器配置


   一、下載所須要的版本,這裏的系統平臺爲CentOS6.5 64系統

   

#wget http://mirrors.sohu.com/mysql/MySQL-Proxy/mysql-proxy-0.8.4-linux-el6-x86-64bit.tar.gz
# tar xf mysql-proxy-0.8.4-linux-el6-x86-64bit.tar.gz
# mv mysql-proxy-0.8.4-linux-el6-x86-64bit /usr/local/mysql-proxy


   二、添加代理用戶

   

# useradd mysql-proxy


   三、爲mysql-proxy提供SysV服務腳本

   

# vim /etc/rc.d/init.d/mysql-proxy
內容以下
#!/bin/bash
#
# mysql-proxy This script starts and stops the mysql-proxy daemon
#
# chkconfig: - 78 30
# processname: mysql-proxy
# description: mysql-proxy is a proxy daemon for mysql
# Source function library.
. /etc/rc.d/init.d/functions
prog="/usr/local/mysql-proxy/bin/mysql-proxy"
# Source networking configuration.
if [ -f /etc/sysconfig/network ]; then
    . /etc/sysconfig/network
fi
# Check that networking is up.
[ ${NETWORKING} = "no" ] && exit 0
# Set default mysql-proxy configuration.
ADMIN_USER="admin"
ADMIN_PASSWD="admin"
ADMIN_LUA_SCRIPT="/usr/local/mysql-proxy/share/doc/mysql-proxy/admin.lua"
PROXY_OPTIONS="--daemon"
PROXY_PID=/var/run/mysql-proxy.pid
PROXY_USER="mysql-proxy"
# Source mysql-proxy configuration.
if [ -f /etc/sysconfig/mysql-proxy ]; then
    . /etc/sysconfig/mysql-proxy
fi
RETVAL=0
start() {
    echo -n $"Starting $prog: "
    daemon $prog $PROXY_OPTIONS --pid-file=$PROXY_PID --proxy-address="$PROXY_ADDRESS" --user=$PROXY_USER --admin-username="$ADMIN_USER" --admin-lua-script="$ADMIN_LUA_SCRIPT" --admin-password="$ADMIN_PASSWORD"
    RETVAL=$?
    echo
    if [ $RETVAL -eq 0 ]; then
        touch /var/lock/subsys/mysql-proxy
    fi
}
stop() {
    echo -n $"Stopping $prog: "
    killproc -p $PROXY_PID -d 3 $prog
    RETVAL=$?
    echo
    if [ $RETVAL -eq 0 ]; then
        rm -f /var/lock/subsys/mysql-proxy
        rm -f $PROXY_PID
    fi
}
# See how we were called.
case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart)
        stop
        start
        ;;
    condrestart|try-restart)
        if status -p $PROXY_PIDFILE $prog >&/dev/null; then
            stop
            start
        fi
        ;;
    status)
        status -p $PROXY_PID $prog
        ;;
    *)
        echo "Usage: $0 {start|stop|restart|reload|status|condrestart|try-restart}"
        RETVAL=1
        ;;
esac
exit $RETVAL

   

#chmod +x /etc/rc.d/init.d/mysql-proxy  賦予執行權限
#chkconfig --add mysql-proxy           添加到系統服務列表中
#chkconfig mysql-proxy on          開機啓動


   四、爲mysql-proxy服務腳本提供配置文件

     #vim  /etc/sysconfig/mysql-proxy  內容以下

   

# Options for mysql-proxy
ADMIN_USER="admin"
ADMIN_PASSWORD="admin"
ADMIN_ADDRESS=""
ADMIN_LUA_SCRIPT="/usr/local/mysql-proxy/share/doc/mysql-proxy/admin.lua"
PROXY_ADDRESS=""
PROXY_USER="mysql-proxy"
PROXY_OPTIONS="--daemon --log-level=info --log-use-syslog"
PROXY_OPTIONS="--daemon --log-level=info --log-use-syslog --plugins=proxy --plugins=admin --proxy-backend-addresses=172.16.13.13:3306 --proxy-read-only-backend-addresses=172.16.13.14:3306 --proxy-lua-script=/usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua"
其中的proxy-backend-addresses選項和proxy-read-only-backend-addresses選項都可重複使用屢次,以實現指定多個讀寫服務器或只讀服務器。

   

      mysql-proxy的配置選項

      mysql-proxy的配置選項大體可分爲幫助選項、管理選項、代理選項及應用程序選項幾類,下面一塊兒去介紹他們

     --help

     --help-admin

     --help-proxy

     --help-all ——以上四個選項均用於獲取幫助信息;


     --proxy-address=host:port   ——代理服務監聽的地址和端口

     --admin-address=host:port   ——管理模塊監聽的地址和端口

     --proxy-backend-address=host:port ——後端mysql服務器的地址和端口

     --proxy-read-only-backend-addresses=host:port ——後端只讀mysql服務器的地址和端口

     --proxy-lua-script=file_name ——完成mysql代理功能的Lua腳本

     --daemon   ——以守護進程模式啓動mysql-proxy

     --keepalive ——在mysql-proxy崩潰時嘗試重啓之

     --log-file=/path/to/log_file_name  ——日誌文件名稱

     --log-level=level  ——日誌級別

     --log-use-syslog   ——基於syslog記錄日誌

     --plugins=plugin,..——在mysql-proxy啓動時加載的插件

     --user=user_name   ——運行mysql-proxy進程的用戶

     --defaults-file=/path/to/confi_file_name ——默認使用的配置文件路徑;其配置段使用[mysql-proxy]標識

     --proxy-skip-profiling ——禁用profile

     --pid-file=/path/to/pid_file_name  ——進程文件名


    五、複製一下內容創建admin.lua文件,將其保存至/user/local/mysql-proxy/share/doc/mysql-proxy

     

#vim  /usr/local/mysql-proxy/share/doc/mysql-proxy/admin.lua
內容以下
--[[ $%BEGINLICENSE%$
 Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License as
 published by the Free Software Foundation; version 2 of the
 License.
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 GNU General Public License for more details.
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 02110-1301  USA
 $%ENDLICENSE%$ --]]
function set_error(errmsg)
    proxy.response = {
        type = proxy.MYSQLD_PACKET_ERR,
        errmsg = errmsg or "error"
    }
end
function read_query(packet)
    if packet:byte() ~= proxy.COM_QUERY then
        set_error("[admin] we only handle text-based queries (COM_QUERY)")
        return proxy.PROXY_SEND_RESULT
    end
    local query = packet:sub(2)
    local rows = { }
    local fields = { }
    if query:lower() == "select * from backends" then
        fields = {
            { name = "backend_ndx",
              type = proxy.MYSQL_TYPE_LONG },
            { name = "address",
              type = proxy.MYSQL_TYPE_STRING },
            { name = "state",
              type = proxy.MYSQL_TYPE_STRING },
            { name = "type",
              type = proxy.MYSQL_TYPE_STRING },
            { name = "uuid",
              type = proxy.MYSQL_TYPE_STRING },
            { name = "connected_clients",
              type = proxy.MYSQL_TYPE_LONG },
        }
        for i = 1, #proxy.global.backends do
            local states = {
                "unknown",
                "up",
                "down"
            }
            local types = {
                "unknown",
                "rw",
                "ro"
            }
            local b = proxy.global.backends[i]
            rows[#rows + 1] = {
                i,
                b.dst.name,          -- configured backend address
                states[b.state + 1], -- the C-id is pushed down starting at 0
                types[b.type + 1],   -- the C-id is pushed down starting at 0
                b.uuid,              -- the MySQL Server's UUID if it is managed
                b.connected_clients  -- currently connected clients
            }
        end
    elseif query:lower() == "select * from help" then
        fields = {
            { name = "command",
              type = proxy.MYSQL_TYPE_STRING },
            { name = "description",
              type = proxy.MYSQL_TYPE_STRING },
        }
        rows[#rows + 1] = { "SELECT * FROM help", "shows this help" }
        rows[#rows + 1] = { "SELECT * FROM backends", "lists the backends and their state" }
    else
        set_error("use 'SELECT * FROM help' to see the supported commands")
        return proxy.PROXY_SEND_RESULT
    end
    proxy.response = {
        type = proxy.MYSQLD_PACKET_OK,
        resultset = {
            fields = fields,
            rows = rows
        }
    }
    return proxy.PROXY_SEND_RESULT
end

 

    六、測試

      6.1 管理功能測試

     #service mysql-proxy start

     #ss  -ntl

     管理端口:4041

     讀寫分離端口:3306

       

[root@www ~]# mysql -uadmin -padmin -h172.16.13.2 --port=4041
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.0.99-agent-admin
Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>


     

     6.2 讀寫分離測試

       

     

在MySQL 主服務器上受權一個用戶
MariaDB [(none)]> grant all on *.* to 'root'@'172.16.13.2' identified by '123';


     6.2.1接下來咱們在MySQL Proxy服務器(172.16.13.2)上測試

          ###########屢次讀寫操做,這樣效果才能明顯以下所示:

   

[root@www mysql-proxy]# mysql -uroot -h172.16.13.2 -p123 --port=3306 -e "select user from mysql.user"
[root@www mysql-proxy]# mysql -uroot -h172.16.13.2 -p123 --port=3306 -e "select user from mysql.user"
[root@www mysql-proxy]# mysql -uroot -h172.16.13.2 -p123 --port=3306 -e "create database testdb"
注意:--port=3306不須要帶,默認偵聽的讀寫分離鏈接端口就是3306.
若是將mysql-proxy安裝在了一臺mysql服務器上,那麼MySQL偵聽的端口要改成其餘端口,不然會衝突(直接在my.cnf配置文件改就行)

   

     6.2.2 屢次讀寫操做後,咱們去管理端口查看讀寫分離狀況

   

[root@www ~]# mysql -uadmin -h172.16.13.2 -padmin --port=4041
mysql> select * from backends;
+-------------+-------------------+-------+------+------+-------------------+
| backend_ndx | address           | state | type | uuid | connected_clients |
+-------------+-------------------+-------+------+------+-------------------+
|           1 | 172.16.13.13:3306 | up    | rw   | NULL |                 0 |
|           2 | 172.16.13.14:3306 | up    | ro   | NULL |                 0 |
+-------------+-------------------+-------+------+------+-------------------+
2 rows in set (0.00 sec)


   基於mysql-proxy實現了MariaDB主從複製架構中讀寫分離!




  總結:整個實例中不難發現,若是架構爲LAMP的架構,那麼PHP程序代碼直接與MySQL Proxy地址相連便可,MySQL Proxy會將讀寫代理至後端的MySQL主從複製架構中,MySQL主服務器負責讀寫,從服務器只負責讀,從而實現讀寫分離架構,若是擔憂Mysql proxy單點故障,能夠創建冗餘,多創建幾個

     



PS:水平有限,若有不妥請指出,MariaDB的MMM架構即將推出,敬請期待!!!

相關文章
相關標籤/搜索