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實現讀寫分離
環境搭建
如上圖所示
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架構即將推出,敬請期待!!!