【實驗環境】
服務器名稱 | IP |
mysql proxy | 192.168.240.134 |
mysql master | 192.168.240.135 |
mysql slave01 | 192.168.240.136 |
mysql slave02 | 192.168.240.137 |
client | 192.168.240.128 |
【拓撲】
一、安裝mysql proxy
前提:
·libevent 1.x 或更高
·glib2 2.6.0 或更高
·lua 5.1.x 或更高
·pkg-config
·libtool 1.5 或更高
·MySQL 5.0.x 或更高的開發庫
1.爲了加速安裝進度,可以先用yum安裝必須的庫,同時解決pkg-config、libtool和MySQL開發庫,由於mysql-proxy並不需要在本機上運行mysql實例,所以這裏用yum安裝:
[root@proxy local]# yum install -y gccgcc-c++ autoconf mysql-devel libtool pkgconfig ncurses ncurses-devel wget make gettext
2.安裝libevent-2.0.20版本
[root@proxy src]# wget https://github.com/downloads/libevent/libevent/libevent-2.0.20-stable.tar.gz
[root@proxy src]# tar -xflibevent-2.0.21-stable.tar.gz -C /usr/local/
[root@proxy libevent-2.0.21-stable]#./configure
[root@proxy libevent-2.0.21-stable]# make&& make install
3.安裝glib2
[root@proxy src]# wget ftp://ftp.gnome.org/pub/gnome/sources/glib/2.18/glib-2.18.4.tar.gz
[root@proxy src]# tar -xf glib-2.18.4.tar.gz
[root@proxy glib-2.18.4]# ./configure
[root@proxy glib-2.18.4]# make &&make install
4.安裝lua-5.1.4版本,安裝之前需要先安裝readline-6.1,不然會報錯缺少頭文件.
[root@proxy src]# wget ftp://ftp.cwru.edu/pub/bash/readline-6.1.tar.gz
[root@proxy readline-6.1]# tar -xfreadline-6.1.tar.gz
[root@proxy readline-6.1]# ./configure
……
install: you may need to run ldconfig
make[1]: Leaving directory`/usr/local/src/readline-6.1/shlib'
爲了動態鏈接庫爲系統所共享,運行ldconfig命令:
[root@proxy readline-6.1]# ldconfig -v
用此選項時,ldconfig將顯示正在掃描的目錄及搜索到的動態鏈接庫,還有它所創建的連接的名字。
安裝lua-5.1.4
[root@proxy src]# wget http://www.lua.org/ftp/lua-5.1.4.tar.gz
[root@proxy src]# tar -xf lua-5.1.4.tar.gz
#64位系統需要在CFLAGS里加上 -fPIC,我們用vim編輯src/Makefile文件,修改代碼如下:
CFLAGS= -O2 -Wall -fPIC $(MYCFLAGS)
安裝:
[root@proxy lua-5.1.4]# make linux
[root@proxy lua-5.1.4]# make install
5.配置pkg-config環境變量:
[root@proxy lua-5.1.4]# cp etc/lua.pc /usr/local/lib/pkgconfig/
[root@proxy lua-5.1.4]# exportPKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig
6.以上操作完成了基礎文件的安裝,接下來是MySQL Proxy 0.8.4安裝:
[root@proxy src]# wget http://dev.mysql.com/get/Downloads/MySQL-Proxy/mysql-proxy-0.8.4.tar.gz
[root@proxy mysql-proxy-0.8.4]#./configure --prefix=/usr/local/mysql-proxy
[root@proxy mysql-proxy-0.8.4]# make&& make install
確保存在以下腳本:
[root@proxy mysql-proxy-0.8.4]# cplib/rw-splitting.lua /usr/local/lib/
[root@proxy mysql-proxy-0.8.4]# cplib/admin.lua /usr/local/lib/
7.測試mysql-proxy
[root@proxy mysql-proxy-0.8.4]#/usr/local/mysql-proxy/bin/mysql-proxy --help-all
Usage:
mysql-proxy [OPTION...] - MySQL Proxy
Help Options:
-?, --help Show help options
--help-all Show all help options
--help-proxy Show options for the proxy-module
proxy-module
-P, --proxy-address=<host:port> listening address:portof the proxy-server (default: :4040)
-r, --proxy-read-only-backend-addresses=<host:port> address:port of the remote slave-server(default: not set)
-b, --proxy-backend-addresses=<host:port> address:port of the remote backend-servers(default: 127.0.0.1:3306)
--proxy-skip-profiling disablesprofiling of queries (default: enabled)
--proxy-fix-bug-25371 fix bug#25371 (mysqld > 5.1.12) for older libmysql versions
-s, --proxy-lua-script=<file> filename of the luascript (default: not set)
--no-proxy don't start the proxy-module (default: enabled)
--proxy-pool-no-change-user don't useCHANGE_USER to reset the connection coming from the pool (default: enabled)
--proxy-connect-timeout connecttimeout in seconds (default: 2.0 seconds)
--proxy-read-timeout readtimeout in seconds (default: 8 hours)
--proxy-write-timeout writetimeout in seconds (default: 8 hours)
Application Options:
-V, --version Show version
--defaults-file=<file> configurationfile
--verbose-shutdown Alwayslog the exit code when shutting down
--daemon Start in daemon-mode
--user=<user> Runmysql-proxy as user
--basedir=<absolute path> Base directoryto prepend to relative paths in the config
--pid-file=<file> PID file in casewe are started as daemon
--plugin-dir=<path> path tothe plugins
--plugins=<name> pluginsto load
--log-level=(error|warning|info|message|debug) log all messages of level ... orhigher
--log-file=<file> log allmessages in a file
--log-use-syslog log allmessages to syslog
--log-backtrace-on-crash try to invokedebugger on crash
--keepalive try to restart the proxy if it crashed
--max-open-files maximumnumber of open files (ulimit -n)
--event-threads numberof event-handling threads (default: 1)
--lua-path=<...> set theLUA_PATH
--lua-cpath=<...> set theLUA_CPATH
爲了方便使用,可以修改/etc/profile文件:
二、配置mysql主從
1.給用戶授權
在master/slave 建立一個測試用戶,因爲以後客戶端發送的SQL都是通過mysql-proxy服務器來轉發,所以要確保可以從mysql-proxy服務器上登錄mysql主從庫,分別在主和從mysql機器上進行授權:
(需要先創建用戶)
mysql>grant all privileges on *.* to 'proxy'@'192.168.240.134' identified '123456';
mysql>flush privileges;
2.進行測試
做完上面的步驟就可以在mysql proxy上進行測試:
[root@proxy~]# mysql-proxy --proxy-backend-addresses=192.168.240.135:3306--proxy-read-only-backend-addresses=192.168.240.136:3306--proxy-read-only-backend-addresses=192.168.240.137:3306--proxy-lua-script=/usr/local/lib/rw-splitting.lua &
[1] 1299
[root@proxy~]# 2014-03-27 18:56:03: (critical) plugin proxy 0.8.4 started
建議使用配置文件的形式啓動,注意配置文件必須是660權限,否則無法啓動.如果有多個slave的話,proxy-read-only-backend-addresses參數可以配置多個以都好分割的IP:PORT 從庫列表.
[root@proxy~]# netstat -nutpl |grep mysql
tcp 0 0 0.0.0.0:4040 0.0.0.0:* LISTEN 1263/mysql-proxy
可以看到,mysql-proxy是以4040端口運行的。
在mysql主從服務器上,分別測試連接mysql-proxy(前提要設置防火牆允許4040端口訪問,或者關閉iptables)
[root@mysql_master~]# mysql -uproxy -p123456 -P4040 -h192.168.240.134
[root@mysql_slave~]# mysql -uproxy -p123456 -P4040 -h192.168.240.134
3.mysql主從複製配置
然後根據上面拓撲,搭建mysql主從(可以參考上一篇博客)
不過爲了更好的驗證讀寫分離的效果,我們暫時關閉mysql主從複製
mysql>stop slave;
Query OK, 0rows affected (0.05 sec)
三、測試
1.測試讀寫分離,前提要保證主從數據一致。
mysql>select * from rep.test1;
+-------+------+---------+
| name | num | class |
+-------+------+---------+
| zhang| 24 | network |
+-------+------+---------+
1 row in set(0.31 sec)
找一臺client機器
mysql>grant all on *.* to 'proxy'@'192.168.240.134' identified by '123456';
Query OK, 0rows affected (0.07 sec)
mysql>flush privileges;
Query OK, 0rows affected (0.03 sec)
[root@Nginx~]# mysql -uproxy -p123456 -P4040 -h192.168.240.134
mysql>show databases;
+--------------------+
|Database |
+--------------------+
|information_schema |
| mysql |
|performance_schema |
| rep |
| test |
+--------------------+
5 rows in set(0.16 sec)
mysql>select * from rep.test1;
+-------+------+---------+
| name | num | class |
+-------+------+---------+
| zhang| 24 | network |
+-------+------+---------+
1 row in set(0.00 sec)
可見,使用客戶端訪問數據庫的時候,數據是一致的。
現在我們嘗試插入數據:
mysql>insert into rep.test1 values('min',20,'net');
Query OK, 1row affected (0.10 sec)
客戶端顯示:
mysql>select * from rep.test1;
+-------+------+---------+
| name | num | class |
+-------+------+---------+
| zhang| 24 | network |
| min | 20| net |
+-------+------+---------+
2 rows in set(0.00 sec)
主服務器顯示:
mysql>select * from rep.test1;
+-------+------+---------+
| name | num | class |
+-------+------+---------+
| zhang| 24 | network |
| min | 20| net |
+-------+------+---------+
2 rows in set(0.00 sec)
兩個從服務器顯示:
slave01
mysql>select * from rep.test1;
+-------+------+---------+
| name | num | class |
+-------+------+---------+
| zhang| 24 | network |
+-------+------+---------+
1 row in set(0.24 sec)
slave02
mysql> select* from rep.test1;
+-------+------+---------+
| name | num | class |
+-------+------+---------+
| zhang| 24 | network |
+-------+------+---------+
1 row in set(0.11 sec)
現在把數據庫還原,然後開啓主從複製,測試:
在主數據庫上創建了一個表:
mysql>create table test2( id int, num int);
Query OK, 0rows affected (0.55 sec)
mysql>show tables;
+---------------+
|Tables_in_rep |
+---------------+
| test1 |
| test2 |
+---------------+
2 rows in set(0.00 sec)
來看從數據庫:
slave01
mysql>show tables;
+---------------+
|Tables_in_rep |
+---------------+
| test1 |
| test2 |
+---------------+
2 rows in set(0.00 sec)
slave02
mysql>show tables;
+---------------+
|Tables_in_rep |
+---------------+
| test1 |
| test2 |
+---------------+
2 rows in set(0.00 sec)
在client端,插入數據:
mysql>insert into rep.test2 values(1,20);
Query OK, 1row affected (0.31 sec)
mysql>select * from rep.test2;
+------+------+
| id | num |
+------+------+
| 1 | 20 |
+------+------+
1 row in set(2.11 sec)
master:
mysql>select * from rep.test2;
+------+------+
| id | num |
+------+------+
| 1 | 20 |
+------+------+
1 row in set(0.00 sec)
slave01:
mysql>select * from rep.test2;
+------+------+
| id | num |
+------+------+
| 1 | 20 |
+------+------+
1 row in set(0.66 sec)
slave02:
mysql>select * from rep.test2;
+------+------+
| id | num |
+------+------+
| 1 | 20 |
+------+------+
1 row in set(0.04 sec)
至此,mysql讀寫分離和主從複製的配置就到此結束了。
小結:
1.如果主從複製需要重新配置,那麼關掉slave,然後重新配置
change masterto
master_host='192.168.240.135',
master_user='username',
master_password='123456',
master_log_file='mysql-bin.000005',
master_log_pos=***;
然後在啓動slave,查看狀態Slave_IO_Running、Slave_SQL_Running是否兩個都爲yes,就行了。
2.無論做讀寫分離還是主從複製,都要保證數據庫的一致性。
3.MySQL-Proxy實際上非常不穩定,在高併發或有錯誤連接的情況下,進程很容易自動關閉,因此打開–keepalive參數讓進程自動恢復是個比較好的辦法,但還是不能從根本上解決問題,因此通常最穩妥的做法是在每個從服務器上安裝一個MySQL-Proxy供自身使用,雖然比較低效但卻能保證穩定性;