mysql (主從複製)(proxy , Amoeba)

原址以下:

http://heylinux.com/archives/1004.htmlhtml

 

Mysql做爲目前世界上使用最普遍的免費數據庫,相信全部從事系統運維的工程師都必定接觸過。但在實際的生產環境中,由單臺Mysql做爲獨立的數據庫是徹底不能知足實際需求的,不管是在安全性,高可用性以及高併發等各個方面。前端

所以,通常來講都是經過 主從複製(Master-Slave)的方式來同步數據,再經過讀寫分離(MySQL-Proxy)來提高數據庫的併發負載能力 這樣的方案來進行部署與實施的。java

以下圖所示:
mysql

下面是我在實際工做過程當中所整理的筆記,在此分享出來,以供你們參考。linux

1、MySQL的安裝與配置
具體的安裝過程,建議參考個人這一篇文章:http://heylinux.com/archives/993.html
值得一提的是,個人安裝過程都是源碼包編譯安裝的,而且全部的配置與數據等都統一規劃到了/opt/mysql目錄中,所以在一臺服務器上安裝完成之後,能夠將整個mysql目錄打包,而後傳到其它服務器上解包,即可當即使用。c++

2、MySQL主從複製
場景描述:
主數據庫服務器:192.168.10.130,MySQL已經安裝,而且無應用數據。
從數據庫服務器:192.168.10.131,MySQL已經安裝,而且無應用數據。sql

2.1 主服務器上進行的操做
啓動mysql服務
/opt/mysql/init.d/mysql start數據庫

經過命令行登陸管理MySQL服務器
/opt/mysql/bin/mysql -uroot -p'new-password'編程

受權給從數據庫服務器192.168.10.131
mysql> GRANT REPLICATION SLAVE ON *.* to 'rep1'@'192.168.10.131' identified by ‘password’;vim

查詢主數據庫狀態
Mysql> show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000005 | 261 | | |
+------------------+----------+--------------+------------------+

記錄下 FILE 及 Position 的值,在後面進行從服務器操做的時候須要用到。

2.2 配置從服務器
修改從服務器的配置文件/opt/mysql/etc/my.cnf
將 server-id = 1修改成 server-id = 10,並確保這個ID沒有被別的MySQL服務所使用。

啓動mysql服務
/opt/mysql/init.d/mysql start

經過命令行登陸管理MySQL服務器
/opt/mysql/bin/mysql -uroot -p'new-password'

執行同步SQL語句
mysql> change master to
master_host=’192.168.10.130’,
master_user=’rep1’,
master_password=’password’,
master_log_file=’mysql-bin.000005’,
master_log_pos=261;

正確執行後啓動Slave同步進程
mysql> start slave;

主從同步檢查
mysql> show slave status\G
==============================================
**************** 1. row *******************
Slave_IO_State:
Master_Host: 192.168.10.130
Master_User: rep1
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000005
Read_Master_Log_Pos: 415
Relay_Log_File: localhost-relay-bin.000008
Relay_Log_Pos: 561
Relay_Master_Log_File: mysql-bin.000005
Slave_IO_Running: YES
Slave_SQL_Running: YES
Replicate_Do_DB:
……………省略若干……………
Master_Server_Id: 1
1 row in set (0.01 sec)
==============================================

其中Slave_IO_Running 與 Slave_SQL_Running 的值都必須爲YES,才代表狀態正常。

若是主服務器已經存在應用數據,則在進行主從複製時,須要作如下處理:
(1)主數據庫進行鎖表操做,不讓數據再進行寫入動做
mysql> FLUSH TABLES WITH READ LOCK;

(2)查看主數據庫狀態
mysql> show master status;

(3)記錄下 FILE 及 Position 的值。
將主服務器的數據文件(整個/opt/mysql/data目錄)複製到從服務器,建議經過tar歸檔壓縮後再傳到從服務器解壓。

(4)取消主數據庫鎖定
mysql> UNLOCK TABLES;

2.3 驗證主從複製效果

主服務器上的操做
在主服務器上建立數據庫first_db
mysql> create database first_db;
Query Ok, 1 row affected (0.01 sec)

在主服務器上建立表first_tb
mysql> create table first_tb(id int(3),name char(10));
Query Ok, 1 row affected (0.00 sec)

在主服務器上的表first_tb中插入記錄
mysql> insert into first_tb values (001,’myself’);
Query Ok, 1 row affected (0.00 sec)

在從服務器上查看
mysql> show databases;
=============================
+--------------------+
| Database |
+--------------------+
| information_schema |
| first_db |
| mysql |
| performance_schema |
| test |
+--------------------+
5 rows in set (0.01 sec)
=============================
數據庫first_db已經自動生成

mysql> use first_db
Database chaged

mysql> show tables;
=============================
+--------------------+
| Tables_in_first_db |
+--------------------+
| first_tb |
+--------------------+
1 row in set (0.02 sec)
=============================
數據庫表first_tb也已經自動建立

mysql> select * from first_tb;
=============================
+------+------+
| id | name |
+------+------+
| 1 | myself |
+------+------+
1 rows in set (0.00 sec)
=============================
記錄也已經存在

由此,整個MySQL主從複製的過程就完成了,接下來,咱們進行MySQL讀寫分離的安裝與配置。

3、MySQL讀寫分離
場景描述:
數據庫Master主服務器:192.168.10.130
數據庫Slave從服務器:192.168.10.131
MySQL-Proxy調度服務器:192.168.10.132

如下操做,均是在192.168.10.132即MySQL-Proxy調度服務器 上進行的。

3.1 MySQL的安裝與配置
具體的安裝過程與上文相同。

3.2 檢查系統所需軟件包
經過 rpm -qa | grep name 的方式驗證如下軟件包是否已所有安裝。
gcc* gcc-c++* autoconf* automake* zlib* libxml* ncurses-devel* libmcrypt* libtool* flex* pkgconfig*
libevent* glib*

若缺乏相關的軟件包,可經過yum -y install方式在線安裝,或直接從系統安裝光盤中找到並經過rpm -ivh方式安裝。

3.3 編譯安裝lua
MySQL-Proxy的讀寫分離主要是經過rw-splitting.lua腳本實現的,所以須要安裝lua。

lua可經過如下方式得到
從http://www.lua.org/download.html下載源碼包

從rpm.pbone.NET搜索相關的rpm包
download.fedora.redhat.com/pub/fedora/epel/5/i386/lua-5.1.4-4.el5.i386.rpm
download.fedora.redhat.com/pub/fedora/epel/5/x86_64/lua-5.1.4-4.el5.x86_64.rpm

這裏咱們建議採用源碼包進行安裝
cd /opt/install
wget http://www.lua.org/ftp/lua-5.1.4.tar.gz
tar zvfx lua-5.1.4.tar.gz
cd lua-5.1.4

vi src/Makefile
在 CFLAGS= -O2 -Wall $(MYCFLAGS) 這一行記錄里加上-fPIC,更改成 CFLAGS= -O2 -Wall -fPIC $(MYCFLAGS) 來避免編譯過程當中出現錯誤。

make Linux
make install

cp etc/lua.pc /usr/lib/pkgconfig/
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/lib/pkgconfig

3.4 安裝配置MySQL-Proxy
MySQL-Proxy可經過如下網址得到:
http://mysql.cdpa.nsysu.edu.tw/Downloads/MySQL-Proxy/

推薦採用已經編譯好的二進制版本,由於採用源碼包進行編譯時,最新版的MySQL-Proxy對automake,glib以及libevent的版本都有很高的要求,而這些軟件包都是系統的基礎套件,不建議強行進行更新。
而且這些已經編譯好的二進制版本在解壓後都在統一的目錄內,所以建議選擇如下版本:
32位RHEL5平臺:
http://mysql.cdpa.nsysu.edu.tw/Downloads/MySQL-Proxy/mysql-proxy-0.8.1-linux-rhel5-x86-32bit.tar.gz
64位RHEL5平臺:
http://mysql.cdpa.nsysu.edu.tw/Downloads/MySQL-Proxy/mysql-proxy-0.8.1-linux-rhel5-x86-64bit.tar.gz

測試平臺爲RHEL5 32位,所以選擇32位的軟件包
wget http://mysql.cdpa.nsysu.edu.tw/Downloads/MySQL-Proxy/mysql-proxy-0.8.1-linux-rhel5-x86-32bit.tar.gz

tar xzvf mysql-proxy-0.8.1-linux-rhel5-x86-32bit.tar.gz
mv mysql-proxy-0.8.1-linux-rhel5-x86-32bit /opt/mysql-proxy

建立mysql-proxy服務管理腳本
mkdir /opt/mysql-proxy/init.d/

vim mysql-proxy

01 #!/bin/sh
02 #
03 # mysql-proxy This script starts and stops the mysql-proxy daemon
04 #
05 # chkconfig: - 78 30
06 # processname: mysql-proxy
07 # description: mysql-proxy is a proxy daemon to mysql
08  
09 # Source function library.
10 . /etc/rc.d/init.d/functions
11  
12 #PROXY_PATH=/usr/local/bin
13 PROXY_PATH=/opt/mysql-proxy/bin
14  
15 prog="mysql-proxy"
16  
17 # Source networking configuration.
18 . /etc/sysconfig/network
19  
20 # Check that networking is up.
21 [ ${NETWORKING} = "no" ] && exit 0
22  
23 # Set default mysql-proxy configuration.
24 #PROXY_OPTIONS="--daemon"
25 PROXY_OPTIONS="--admin-username=root --admin-password=password --proxy-read-only-backend-addresses=192.168.10.131:3306 --proxy-backend-addresses=192.168.10.130:3306  --admin-lua-script=/opt/mysql-proxy/lib/mysql-proxy/lua/admin.lua --proxy-lua-script=/opt/mysql-proxy/scripts/rw-splitting.lua"
26 PROXY_PID=/opt/mysql-proxy/run/mysql-proxy.pid
27  
28 # Source mysql-proxy configuration.
29 if [ -f /etc/sysconfig/mysql-proxy ]; then
30         . /etc/sysconfig/mysql-proxy
31 fi
32  
33 PATH=$PATH:/usr/bin:/usr/local/bin:$PROXY_PATH
34  
35 # By default it's all good
36 RETVAL=0
37  
38 # See how we were called.
39 case "$1" in
40   start)
41         # Start daemon.
42         echo -n $"Starting $prog: "
43         $NICELEVEL $PROXY_PATH/mysql-proxy $PROXY_OPTIONS --daemon --pid-file=$PROXY_PID --user=mysql --log-level=warning --log-file=/opt/mysql-proxy/log/mysql-proxy.log
44         RETVAL=$?
45         echo
46         if [ $RETVAL = 0 ]; then
47                 touch /var/lock/subsys/mysql-proxy
48         fi
49        ;;
50   stop)
51         # Stop daemons.
52         echo -n $"Stopping $prog: "
53         killproc $prog
54         RETVAL=$?
55         echo
56         if [ $RETVAL = 0 ]; then
57                 rm -f /var/lock/subsys/mysql-proxy
58                 rm -f $PROXY_PID
59         fi
60        ;;
61   restart)
62         $0 stop
63         sleep 3
64         $0 start
65        ;;
66   condrestart)
67        [ -e /var/lock/subsys/mysql-proxy ] && $0 restart
68       ;;
69   status)
70         status mysql-proxy
71         RETVAL=$?
72        ;;
73   *)
74         echo "Usage: $0 {start|stop|restart|status|condrestart}"
75         RETVAL=1
76        ;;
77 esac
78  
79 exit $RETVAL

腳本參數詳解:
==============================================
PROXY_PATH=/opt/mysql-proxy/bin //定義mysql-proxy服務二進制文件路徑

PROXY_OPTIONS="--admin-username=root \ //定義內部管理服務器帳號
--admin-password=password \ //定義內部管理服務器密碼
--proxy-read-only-backend-addresses=192.168.10.131:3306 \ //定義後端只讀從服務器地址
--proxy-backend-addresses=192.168.10.130:3306 \ //定義後端主服務器地址
--admin-lua-script=/opt/mysql-proxy/lib/mysql-proxy/lua/admin.lua \ //定義lua管理腳本路徑
--proxy-lua-script=/opt/mysql-proxy/scripts/rw-splitting.lua" \ //定義lua讀寫分離腳本路徑

PROXY_PID=/opt/mysql-proxy/run/mysql-proxy.pid //定義mysql-proxy PID文件路徑

$NICELEVEL $PROXY_PATH/mysql-proxy $PROXY_OPTIONS \
--daemon \ //定義以守護進程模式啓動
--keepalive \ //使進程在異常關閉後可以自動恢復
--pid-file=$PROXY_PID \ //定義mysql-proxy PID文件路徑
--user=mysql \ //以mysql用戶身份啓動服務
--log-level=warning \ //定義log日誌級別,由高到低分別有(error|warning|info|message|debug)
--log-file=/opt/mysql-proxy/log/mysql-proxy.log //定義log日誌文件路徑
==============================================

cp mysql-proxy /opt/mysql-proxy/init.d/
chmod +x /opt/mysql-proxy/init.d/mysql-proxy

mkdir /opt/mysql-proxy/run
mkdir /opt/mysql-proxy/log

mkdir /opt/mysql-proxy/scripts

配置並使用rw-splitting.lua讀寫分離腳本
最新的腳本咱們能夠從最新的mysql-proxy源碼包中獲取
cd /opt/install

wget http://mysql.cdpa.nsysu.edu.tw/Downloads/MySQL-Proxy/mysql-proxy-0.8.1.tar.gz

tar xzvf mysql-proxy-0.8.1.tar.gz
cd mysql-proxy-0.8.1
cp lib/rw-splitting.lua /opt/mysql-proxy/scripts

修改讀寫分離腳本rw-splitting.lua
修改默認鏈接,進行快速測試,不修改的話要達到鏈接數爲4時才啓用讀寫分離
vim /opt/mysql-proxy/scripts/rw-splitting.lua
=============================
-- connection pool
if not proxy.global.config.rwsplit then
proxy.global.config.rwsplit = {
min_idle_connections = 1, //默認爲4
max_idle_connections = 1, //默認爲8
is_debug = false
}
end
=============================

修改完成後,啓動mysql-proxy
/opt/mysql-proxy/init.d/mysql-proxy start

3.5 測試讀寫分離效果
建立用於讀寫分離的數據庫鏈接用戶
登錄主數據庫服務器192.168.10.130,經過命令行登陸管理MySQL服務器
/opt/mysql/bin/mysql -uroot -p'new-password'
mysql> GRANT ALL ON *.* TO 'proxy1'@'192.168.10.132' IDENTIFIED BY 'password';
因爲咱們配置了主從複製功能,所以從數據庫服務器192.168.10.131上已經同步了此操做。

爲了清晰的看到讀寫分離的效果,須要暫時關閉MySQL主從複製功能
登錄從數據庫服務器192.168.10.131,經過命令行登陸管理MySQL服務器
/opt/mysql/bin/mysql -uroot -p'new-password'

關閉Slave同步進程
mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)

鏈接MySQL-Proxy
/opt/mysql/bin/mysql -uproxy1 -p'password' -P4040 -h192.168.10.132

登錄成功後,在first_db數據的first_tb表中插入兩條記錄
mysql> use first_db;
Database changed
mysql> insert into first_tb values (007,’first’);
Query Ok, 1 row affected (0.00 sec)
mysql> insert into first_tb values (110,’second’);
Query Ok, 1 row affected (0.00 sec)

查詢記錄
mysql> select * from first_tb;
=============================
+------+------+
| id | name |
+------+------+
| 1 | myself |
+------+------+
1 rows in set (0.00 sec)
=============================
經過讀操做並無看到新記錄

mysql> quit
退出MySQL-Proxy

下面,分別登錄到主從數據庫服務器,對比記錄信息
首先,檢查主數據庫服務器
mysql> select * from first_tb;
=============================
+------+------+
| id | name |
+------+------+
| 1 | myself |
+------+------+
| 007 | first |
+------+------+
| 110 | second |
+------+------+
3 rows in set (0.00 sec)
=============================
兩條新記錄都已經存在

而後,檢查從數據庫服務器
mysql> select * from first_tb;
=============================
+------+------+
| id | name |
+------+------+
| 1 | myself |
+------+------+
1 rows in set (0.00 sec)
=============================
沒有新記錄存在

由此驗證,咱們已經實現了MySQL讀寫分離,目前全部的寫操做都所有在Master主服務器上,用來避免數據的不一樣步;
另外,全部的讀操做都分攤給了其它各個Slave從服務器上,用來分擔數據庫壓力。

經驗分享:
1.當MySQL主從複製在 show slave status\G 時出現Slave_IO_Running或Slave_SQL_Running 的值不爲YES時,須要首先經過 stop slave 來中止從服務器,而後再執行一次本文 2.1與2.2 章節中的步驟便可恢復,但若是想盡量的同步更多的數據,能夠在Slave上將master_log_pos節點的值在以前同步失效的值的基礎上增大一些,而後反覆測試,直到同步OK。由於MySQL主從複製的原理其實就是從服務器讀取主服務器的binlog,而後根據binlog的記錄來更新數據庫。

2.MySQL-Proxy的rw-splitting.lua腳本在網上有不少版本,可是最準確無誤的版本仍然是源碼包中所附帶的lib/rw-splitting.lua腳本,若是有lua腳本編程基礎的話,能夠在這個腳本的基礎上再進行優化;

3.MySQL-Proxy實際上很是不穩定,在高併發或有錯誤鏈接的狀況下,進程很容易自動關閉,所以打開--keepalive參數讓進程自動恢復是個比較好的辦法,但仍是不能從根本上解決問題,所以一般最穩妥的作法是在每一個從服務器上安裝一個MySQL-Proxy供自身使用,雖然比較低效但卻能保證穩定性;

4.一主多從的架構並非最好的架構,一般比較優的作法是經過程序代碼和中間件等方面,來規劃,好比設置對錶數據的自增id值差別增加等方式來實現兩個或多個主服務器,但必定要注意保證好這些主服務器數據的完整性,不然效果會比多個一主多從的架構還要差;

5.MySQL-Cluster 的穩定性也不是太好;

6.Amoeba for MySQL 是一款優秀的中間件軟件,一樣能夠實現讀寫分離,負載均衡等功能,而且穩定性要大大超過MySQL-Proxy,建議你們用來替代MySQL-Proxy,甚至MySQL-Cluster。

 

詳解Mysql Proxy Lua讀寫分離設置

 

原址以下:

http://mobile.51cto.com/iphone-287937.htm

Mysql Proxy Lua讀寫分離設置是本文要介紹的內容,主要是來了解Mysql ProxyMysql 分離設置,爲了將來MySQL讀寫分離的須要, 先行對MySQL官方的Mysql Proxy產品進行了初步測試. 如下是測試過程,二進制版Mysql Proxy能夠去下載。

一、設置說明

  1. Master服務器: 192.168.41.196  
  2. Slave服務器: 192.168.41.197  
  3. Proxy服務器: 192.168.41.203 

二、安裝Mysql Proxy

在Proxy服務器上安裝便可. 若是源碼方式安裝, 需提早安裝pkg-config,libevent,glibc,lua等依賴包, 很是麻煩, 建議直接使用二進制版.

  1. # cd /u01/software/mysql  
  2. # tar -zxvf Mysql Proxy-0.8.1-linux-rhel5-x86-32bit.tar.gz -C /usr/local  
  3. # cd /usr/local  
  4. # ln -s Mysql Proxy-0.8.1-linux-rhel5-x86-32bit Mysql Proxy  
  5. # vi + ~/.bash_profile  
  6. export PATH=$PATH:/usr/local/Mysql Proxy/bin/  
  7. # . ~/.bash_profile 

三、Mysql Proxy選項說明

  1. # Mysql Proxy help-all 

管理功能選項:

  1. admin-address=host:port 指定一個mysqo-proxy的管理端口, 缺省是4041;  
  2. admin-username=<string> username to allow to log in  
  3. admin-password=<string> password to allow to log in  
  4. admin-lua-script=<filename> script to execute by the admin plugin 

代理功能選項:

  1. -P, proxy-address=<host:port> 是Mysql Proxy 服務器端的監聽端口, 缺省是4040;  
  2. -r, proxy-read-only-backend-addresses=<host:port> 只讀Slave的地址和端口, 缺省爲不設置;  
  3. -b, proxy-backend-addresses=<host:port> 遠程Master地址和端口, 可設置多個作failover和load balance, 缺省是127.0.0.1:3306;  
  4. proxy-skip-profiling 關閉查詢分析功能, 缺省是打開的;  
  5. proxy-fix-bug-25371 修正 mysql的libmysql版本大於5.1.12的一個#25371號bug;  
  6. -s, proxy-lua-script=<file> 指定一個Lua腳原本控制Mysql Proxy的運行和設置, 這個腳本在每次新建鏈接和腳本發生修改的的時候將從新調用; 

其餘選項:

  1. defaults-file=<file>配置文件, 能夠把Mysql Proxy的參數信息置入一個配置文件裏;  
  2. daemon Mysql Proxy以守護進程方式運行  
  3. pid-file=file 設置Mysql Proxy的存儲PID文件的路徑  
  4. keepalive try to restart the proxy if it crashed, 保持鏈接啓動進程會有2個, 一號進程用來監視二號進程, 若是二號進程死掉自動重啓proxy. 

四、數據庫準備工做

(1)安裝半同步補丁(建議)

讀寫分離不能迴避的問題之一就是延遲, 能夠考慮Google提供的SemiSyncReplication補丁.

(2)給用戶受權

在Master/Slave創建一個測試用戶, 由於之後客戶端發送的SQL都是經過Mysql Proxy服務器來轉發, 因此要確保能夠從Mysql Proxy服務器上登陸MySQL主從庫.

  1. mysql> grant all privileges on *.* to 'u_test'@'192.168.41.203' identified by 'xxx' with grant option; 

(3)在Master創建測試表

  1. mysql> create table db_test.t_test (col varchar(10));  
  2. mysql> insert into db_test.t_test values ('testA');  
  3. mysql> select * from db_test.t_test;  
  4. +-+  
  5. | col   |  
  6. +-+  
  7. | testA |  
  8. +-+ 

五、Mysql Proxy啓動

(1)修改讀寫分離lua腳本

默認最小4個最大8個以上的客戶端鏈接纔會實現讀寫分離, 現改成最小1個最大2個:

  1. # vi +40 /usr/local/Mysql Proxy/share/doc/Mysql Proxy/rw-splitting.lua  
  2.  connection pool  
  3. if not proxy.global.config.rwsplit then  
  4.         proxy.global.config.rwsplit = {  
  5.                 min_idle_connections = 1,  
  6.                 max_idle_connections = 2,  
  7.                 is_debug = true   
  8.         }         
  9. end 

這是由於Mysql Proxy會檢測客戶端鏈接, 當鏈接沒有超過min_idle_connections預設值時, 不會進行讀寫分離, 即查詢操做會發生到Master上.

(2)啓動Mysql Proxy

建議使用配置文件的形式啓動, 注意配置文件必須是660權限, 不然沒法啓動. 若是有多個Slave的話, proxy-read-only-backend-addresses參數能夠配置多個以逗號分隔的IP:Port從庫列表.

  1. # killall Mysql Proxy   
  2. # vi /etc/Mysql Proxy.cnf  
  3. [Mysql Proxy]  
  4. admin-username=wangnc 
  5. admin-password=iamwangnc 
  6. admin-lua-script=/usr/local/Mysql Proxy/lib/Mysql Proxy/lua/admin.lua  
  7. proxy-backend-addresses=192.168.41.196:3351  
  8. proxy-read-only-backend-addresses=192.168.41.197:3351  
  9. proxy-lua-script=/usr/local/Mysql Proxy/share/doc/Mysql Proxy/rw-splitting.lua  
  10. log-file=/var/tmp/Mysql Proxy.log  
  11. log-level=debug 
  12. daemon=true 
  13. keepalive=true 
  14. # chmod 660 /etc/Mysql Proxy.cnf  
  15. # Mysql Proxy defaults-file=/etc/Mysql Proxy.cnf  
  16. # ps -ef | grep Mysql Proxy | grep -v grep  
  17. root      1869     1  0 18:16 ?        00:00:00 /usr/local/Mysql Proxy/libexec/Mysql Proxy defaults-file=/etc/Mysql Proxy.cnf  
  18. root      1870  1869  0 18:16 ?        00:00:00 /usr/local/Mysql Proxy/libexec/Mysql Proxy defaults-file=/etc/Mysql Proxy.cnf  
  19. # tail -50f /var/tmp/Mysql Proxy.log 

六、客戶端鏈接測試

(1)先中止Slave的複製進程

  1. mysql> stop slave; 

(2)鏈接Proxy端口, 插入數據

  1. # mysql -uu_test -pxxx -h192.168.41.203 -P4040 -Ddb_test  
  2. mysql> insert into db_test.t_test values ('testB');  
  3. mysql> select * from db_test.t_test;  
  4. +-+  
  5. | col   |  
  6. +-+  
  7. | testA |  
  8. | testB |  
  9. +-+ 

(3)多開幾個客戶端, 鏈接Proxy端口, 查詢數據

  1. # mysql -uu_test -pxxx -h192.168.41.203 -P4040 -Ddb_test  
  2. mysql> select * from db_test.t_test;  
  3. +-+  
  4. | col   |  
  5. +-+  
  6. | testA |  
  7. +-+ 

若是查詢不到上步新插入的數據, 說明鏈接到了Slave, 讀寫分離成功. 在同一線程再插入數據並驗證:

  1. mysql> insert into db_test.t_test values ('testC');  
  2. mysql> select * from db_test.t_test;  
  3. +-+  
  4. | col   |  
  5. +-+  
  6. | testA |  
  7. +-+ 

發現insert操做成功, 可是select不出剛插入的數據, 說明同一線程也讀寫分離成功. 從日誌中能夠驗證:

  1. # tail -50f /var/tmp/Mysql Proxy.log  
  2. ...  
  3. [read_query] 192.168.41.203:45481  
  4.   current backend   = 
  5.   client default db = db_test 
  6.   client username   = u_test 
  7.   query             = select * from db_test.t_test  
  8.   sending to backend : 192.168.41.197:3351  
  9.     is_slave         : true  
  10.     server default db: db_test  
  11.     server username  : u_test  
  12.     in_trans        : false  
  13.     in_calc_found   : false  
  14.     COM_QUERY       : true  
  15. [read_query] 192.168.41.203:45481  
  16.   current backend   = 
  17.   client default db = db_test 
  18.   client username   = u_test 
  19.   query             = insert into db_test.t_test values ('testC')  
  20.   sending to backend : 192.168.41.196:3351  
  21.     is_slave         : false  
  22.     server default db: db_test  
  23.     server username  : u_test  
  24.     in_trans        : false  
  25.     in_calc_found   : false  
  26.     COM_QUERY       : true 

(4)測試完畢後, 啓動Slave的複製進程

  1. mysql> start slave; 

七、正式環境說明

一、Mysql Proxy當前還只是個測試版, MySQL官方還不建議用到生產環境中;

二、Mysql Proxy的rw-splitting.lua腳本在網上有不少版本, 可是最準確無誤的版本仍然是源碼包中所附帶的rw-splitting.lua腳本, 若是有lua腳本編程基礎的話, 能夠在這個腳本的基礎上再進行優化;

三、Mysql Proxy實際上很是不穩定, 在高併發或有錯誤鏈接的狀況下, 進程很容易自動關閉, 所以打開keepalive參數讓進程自動恢復是個比較好的辦法, 但仍是不能從根本上解決問題, 所以一般最穩妥的作法是在每一個從服務器上安裝一個Mysql Proxy供自身使用, 雖然比較低效但卻能保證穩定性;

四、Amoeba for MySQL是一款優秀的中間件軟件, 一樣能夠實現讀寫分離, 負載均衡等功能, 而且穩定性要大大超過Mysql Proxy, 建議你們用來替代Mysql Proxy, 甚至MySQL-Cluster.

 

mysql的讀寫分離amoeba

原址以下:

http://freeze.blog.51cto.com/1846439/860111

 

此文凝聚筆者很多心血請尊重筆者勞動,轉載請註明出處http://freeze.blog.51cto.com/ 

  1、關於讀寫分離

  1. 讀寫分離(Read/Write Splitting),基本的原理是讓主數據庫處理事務性增、改、刪操做(INSERT、UPDATE、DELETE),而從數據庫處理SELECT查詢操做。數據庫複製被用來把事務性操做致使的變動同步到集羣中的從數據庫。 

 

2、同類產品比較 

  1. 雖然大多數都是從程序裏直接實現讀寫分離的,但對於分佈式的部署和水平和垂直分割,一些代理的相似中間件的軟件仍是挺實用的,Amoeba for Mysql 與MySQL Proxy比較 在MySQL proxy 6.0版本 上面若是想要讀寫分離而且 讀集羣、寫集羣 機器比較多狀況下,用mysql proxy 須要至關大的工做量,目前mysql proxy沒有現成的 lua腳本。mysql proxy根本沒有配置文件, lua腳本就是它的所有,固然lua是至關方便的。那麼一樣這種東西須要編寫大量的腳本才能完成一 個複雜的配置。而Amoeba for Mysql只須要進行相關的配置就能夠知足需求。 
 
3、關於Amoeba
 
  1. Amoeba(變形蟲)項目,該開源框架於2008年 開始發佈一款 Amoeba for Mysql軟件。這個軟件致力於MySQL的分佈式數據庫前端代理層,它主要在應用層訪問MySQL的 時候充當SQL路由功能,專一於分佈式數據庫代理層(Database Proxy)開發。座落與 Client、DB Server(s)之間,對客戶端透明。具備負載均衡、高可用性、SQL 過濾、讀寫分離、可路由相關的到目標數據庫、可併發請求多臺數據庫合併結果。 經過Amoeba你可以完成多數據源的高可用、負載均衡、數據切片的功能,目前Amoeba已在不少 企業的生產線上面使用。 

 

4、Amoeba的安裝

4.1下載 

  1. wget http://nchc.dl.sourceforge.net/project/amoeba/Amoeba%20for%20mysql/2.x/amoeba-mysql-binary-2.1.0-RC5.tar.gz 

4.2安裝amoeba 

  1. mkdir /usr/local/amoeba 
  2. #mv amoeba-mysql-binary-2.1.0-RC5.tar.gz /usr/local/amoeba 
  3. #tar  xvf amoeba-mysql-binary-2.1.0-RC5.tar.gz  

4.3安裝JDK 

  1. 由於Amoeba是java開發的,須要JDK支持。 Amoeba框架是基於Java SE1.5開發的,建議使用Java SE 1.5版本。 
  2.  
  3. % java -version 
  4. java version "1.6.0_18" 
  5. Java(TM) SE Runtime Environment (build 1.6.0_18-b07) 
  6. Java HotSpot(TM) Client VM (build 16.0-b13, mixed mode, sharing) 
  7. 目前Amoeba經驗證在JavaTM SE 1.5和Java SE 1.6能正常運行,(可能包括其餘未經驗證的版本)。 若是你的機器上沒有安裝JavaTM環境,能夠訪問http://www.oracle.com/technetwork/java/javase/downloads/index.html進行下載。能夠根據你的操做系統等詳情安裝JavaTM環境。 
  8.  
  9. 去oracle官網下載jdk安裝包後,安裝jdk 
  10.  
  11. # chmod 755 jdk-6u25-linux-i586.bin 
  12. # ./jdk-6u25-linux-i586.bin 
  13. # mv jdk1.6.0_25/ /usr/local/jdk 
  14. 聲明路徑,修改/etc/profile,在末尾加上如下代碼 
  15.  
  16. export AMOEBA_HOME=/usr/local/amoeba 
  17. export JAVA_HOME=/usr/local/jdk 
  18. export PATH=$PATH:$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$AMOEBA_HOME/bin 


 5、Amoeba配置

  1. cd /usr/local/amoeba/conf 主要配置如下2個配置文件:  
  2. dbServers.xml  #定義鏈接數據庫信息 
  3. amoeba.xml     #定義讀寫分離節點管理信息 

5.1 配置dbServers.xml

  1. <?xml version="1.0" encoding="gbk"?> 
  2.  
  3. <!DOCTYPE amoeba:dbServers SYSTEM "dbserver.dtd"
  4. <amoeba:dbServers xmlns:amoeba="http://amoeba.meidusa.com/"
  5.  
  6.                 <!--  
  7.                         Each dbServer needs to be configured into a Pool, 
  8.                          such as 'multiPool' dbServer    
  9.                 --
  10.  
  11.         <dbServer name="abstractServer" abstractive="true"
  12.                 <factoryConfig class="com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory"
  13.                         <property name="manager">${defaultManager}</property
  14.                         <property name="sendBufferSize">64</property
  15.                         <property name="receiveBufferSize">128</property
  16.  
  17.                         <!-- mysql port --> 
  18.                         <property name="port">3306</property>         __ ** ##後端數據庫端口**__ 
  19.  
  20.                         <!-- mysql schema --> 
  21.                         <property name="schema">test</property>        __ ** ##後端數據庫默認庫**__ 
  22.                         <!--  mysql password 
  23.                         <property name="password">password</property
  24.                         --
  25.                 </factoryConfig
  26.  
  27.                 <poolConfig class="com.meidusa.amoeba.net.poolable.PoolableObjectPool"
  28.                         <property name="maxActive">500</property
  29.                         <property name="maxIdle">500</property
  30.                         <property name="minIdle">10</property
  31.                         <property name="minEvictableIdleTimeMillis">600000</property
  32.                         <property name="timeBetweenEvictionRunsMillis">600000</property
  33.                         <property name="testOnBorrow">true</property
  34.                         <property name="testWhileIdle">true</property
  35.                 </poolConfig
  36.         </dbServer
  37.   
  38.         <dbServer name="master"  parent="abstractServer">                          __ ** ##定義主的寫的節點**__ 
  39.                 <factoryConfig
  40.                         <property name="ipAddress">192.168.1.1</property>      __ ** ##主masterIP**__ 
  41.                         <property name="user">test1</property>                 __ ** ##與主mysql通訊,鏈接數據庫的賬號,如下是密碼**__ 
  42.                         <property name="password">test1</property
  43.                 </factoryConfig
  44.         </dbServer
  45.  
  46.         <dbServer name="slave"  parent="abstractServer"
  47.                 <factoryConfig
  48.                         <property name="ipAddress">192.168.1.2</property
  49.                         <property name="user">test2</property>                 __ ** ##與從mysql通訊,鏈接數據庫的賬號,如下是密碼**__ 
  50.                         <property name="password">test2</property
  51.                 </factoryConfig
  52.         </dbServer
  53.  
  54.         <dbServer name="server1" virtual="true"
  55.                 <poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">    __ ** ##定義寫的池,把master節點加入**__ 
  56.                         <property name="loadbalance">1</property
  57.                         <property name="poolNames">master</property
  58.                 </poolConfig
  59.         </dbServer
  60.  
  61.         <dbServer name="server2" virtual="true"
  62.                 <poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">    __ ** ##定義讀的池,把slave節點加入**__ 
  63.                         <property name="loadbalance">1</property
  64.                         <property name="poolNames">slave</property
  65.                 </poolConfig
  66.         </dbServer
  67. </amoeba:dbServers

5.2 配置amoeba.xml

  1. <?xml version="1.0" encoding="gbk"?> 
  2. <amoeba:configuration xmlns:amoeba="http://amoeba.meidusa.com/"
  3.  
  4.         <proxy
  5.  
  6.                 <!-- service class must implements com.meidusa.amoeba.service.Service --> 
  7.                         <!-- port --> 
  8.                          <property name="port">6666</property>                   __ ** ##定義amoeba讀寫分離proxy對外代理的端口**__ 
  9.                         <!-- bind ipAddress --> 
  10.                         <!--  
  11.                         <property name="ipAddress">127.0.0.1</property> 
  12.                          --> 
  13.  
  14.                         <property name="manager">${clientConnectioneManager}</property
  15.  
  16.                         <property name="connectionFactory"
  17.                                         <property name="sendBufferSize">128</property
  18.                                         <property name="receiveBufferSize">64</property
  19.                                 </bean
  20.                         </property
  21.  
  22.                         <property name="authenticator"
  23.                                          <property name="user">dbproxy</property>     __ ** ##定義proxy的管理賬號密碼,客戶端和程序只須要鏈接proxy的賬號密碼便可,至關於中間接封裝**__ 
  24.                                         <property name="password">123456</property
  25.  
  26.                                         <property name="filter"
  27.                                                 </bean
  28.                                         </property
  29.                                 </bean
  30.                         </property
  31.  
  32.                 </service
  33.  
  34.                 <!-- server class must implements com.meidusa.amoeba.service.Service --> 
  35.                         <!-- port --> 
  36.                         <!--  default value: random number 
  37.                         <property name="port">9066</property
  38.                         --
  39.                         <!-- bind ipAddress --> 
  40.                         <property name="ipAddress">127.0.0.1</property
  41.                         <property name="daemon">true</property
  42.                         <property name="manager">${clientConnectioneManager}</property
  43.                         <property name="connectionFactory"
  44.                 <runtime class="com.meidusa.amoeba.mysql.context.MysqlRuntimeContext"
  45.                         <!-- proxy server net IO Read thread size --> 
  46.                         <property name="readThreadPoolSize">20</property
  47.  
  48.                         <!-- proxy server client process thread size --> 
  49.  
  50.                         <!-- per connection cache prepared statement size  --> 
  51.                         <property name="statementCacheSize">500</property
  52.  
  53.                         <!-- query timeout( default: 60 second , TimeUnit:second) --> 
  54.                         <property name="queryTimeout">60</property
  55.                 </runtime
  56.  
  57.         </proxy
  58.  
  59.         <!--  
  60.                 Each ConnectionManager will start as thread 
  61.                 manager responsible for the Connection IO read , Death Detection 
  62.         --
  63.         <connectionManagerList
  64.                         <!--  
  65.                           default value is avaliable Processors  
  66.                         <property name="processors">5</property
  67.                          --
  68.                 </connectionManager
  69.  
  70.                         <!--  
  71.                           default value is avaliable Processors  
  72.                         <property name="processors">5</property
  73.                          --
  74.                 </connectionManager
  75.         </connectionManagerList
  76.  
  77.                 <!-- default using file loader --> 
  78.         <dbServerLoader class="com.meidusa.amoeba.context.DBServerConfigFileLoader"
  79.                 <property name="configFile">${amoeba.home}/conf/dbServers.xml</property
  80.         </dbServerLoader
  81.  
  82.         <queryRouter class="com.meidusa.amoeba.mysql.parser.MysqlQueryRouter"
  83.                 <property name="ruleLoader"
  84.                         <bean class="com.meidusa.amoeba.route.TableRuleFileLoader"
  85.                                 <property name="ruleFile">${amoeba.home}/conf/rule.xml</property
  86.                                 <property name="functionFile">${amoeba.home}/conf/ruleFunctionMap.xml</property
  87.                         </bean
  88.                 </property
  89.                 <property name="sqlFunctionFile">${amoeba.home}/conf/functionMap.xml</property
  90.                 <property name="LRUMapSize">1500</property
  91.                 <property name="defaultPool">server1</property>                   __ ** ##定義默認的池,一些除了SELECT\UPDATE\INSERT\DELETE的語句都會在defaultPool執行。**__ 
  92.                 <property name="writePool">server1</property>                      __ ** ##定義寫的池**__ 
  93.                 <property name="readPool">server2</property>                      __ ** ##定義讀的池**__ 
  94.                 <property name="needParse">true</property
  95.         </queryRouter
  96. </amoeba:configuration

 

6、啓動Amoeba

  1. /usr/local/amoeba/bin/amoeba start & 
  2. 開機自動啓動可加入到 /etc/rc.local內 
  3. echo "/usr/local/amoeba/bin/amoeba start &" >> /etc/rc.local 

7、日誌排錯

  1. 日誌文件在/usr/local/amoeba/log下   

 

   PS:amoeba雖然是Java寫的,看似效率不高,但功能異常強大,支持讀寫分離,表和庫級別的讀寫分離,數據庫水平分割,垂直分割,還有集羣。是淘寶的得力做品。喜歡的童鞋能夠嘗試下。mysql-proxy 只是輕量級的讀寫分離程序,雖然C寫的,可是驅動是須要lua的腳本跑,並且在高併發下常常掛掉。程序還忽略了一些字符設定,若是數據庫不是同一編碼還會出現亂碼,amoeba就不存在。就簡單介紹到這裏吧。

 

 使用Amoeba for mysql實現mysql讀寫分離

原址以下:

http://www.centos.bz/2012/05/amoeba-for-mysql/

 

Amoeba for MySQL致力於MySQL的分佈式數據庫前端代理層,它主要在應用層訪問MySQL的時候充當query 路由功能,專一 分佈式數據庫 proxy 開發。座落與Client、DB Server(s)之間。對客戶端透明。具備負載均衡、高可用性、Query過濾、讀寫分離、可路由相關的query到目標數據庫、可併發請求多臺數據庫合併結果。 在Amoeba上面你可以完成多數據源的高可用、負載均衡、數據切片的功能。目前在不少企業的生產線上面使用。
www.centos.bz這裏使用Amoeba for mysql來實現mysql的讀寫分離,起到緩解主數據庫服務器的壓力,下面是實現這一方案的架構圖:

mysql主從複製配置

由於讀寫分離,因此一臺負責mysql的寫操做,另外一臺負責mysql的讀操做,因此咱們這裏使用mysql的主從複製再合適不過了。關於這一配置,請移步:
http://www.centos.bz/2011/07/linux-mysql-replication-sync-configure/

java環境配置

Amoeba框架是基於Java SE1.5開發的,建議使用Java SE 1.5版本。目前Amoeba經驗證在JavaTM SE 1.5和Java SE 1.6能正常運行,(可能包括其餘未經驗證的版本)。
Java SE 1.6下載地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk-6u32-downloads-1594644.html
我這裏下載jdk-6u32-linux-i586-rpm.bin。
下載完成後執行sh jdk-6u32-linux-i586-rpm.bin開始安裝,將會安裝到/usr/java/jdk1.6.0_32目錄。

Amoeba的安裝

Amoeba下載地址:http://sourceforge.net/projects/amoeba/
下面是安裝步驟:

  1. cd /tmp
  2. mkdir /usr/local/amoeba
  3. wget http://softlayer.dl.sourceforge.net/project/amoeba/Amoeba%20for%20mysql/2.x/amoeba-mysql-binary-2.1.0-RC5.tar.gz
  4. tar xzf amoeba-mysql-binary-2.1.0-RC5.tar.gz -C /usr/local/amoeba

配置用戶環境變量

  1. vi ~/.bash_profile

設置爲:

  1. PATH=$PATH:$HOME/bin:/usr/local/amoeba/bin
  2. JAVA_HOME=/usr/java/jdk1.6.0_32
  3.  
  4. export JAVA_HOME
  5. export PATH

當即生效:

  1. source  ~/.bash_profile

Amoeba for mysql配置

配置Amoeba for mysql的讀寫分離主要涉及兩個文件:
一、/usr/local/amoeba/conf/dbServers.xml
此文件定義由Amoeba代理的數據庫如何鏈接,好比最基礎的:主機IP、端口、Amoeba使用的用戶名和密碼等等。
二、/usr/local/amoeba/conf/amoeba.xml
此文件定義了Amoeba代理的相關配置。

dbServers.xml文件配置

abstractServer配置:

  1. <dbServer name="abstractServer" abstractive="true">
  2.                 <factoryConfig class="com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory">
  3.                         <property name="manager">${defaultManager}</property>
  4.                         <property name="sendBufferSize">64</property>
  5.                         <property name="receiveBufferSize">128</property>
  6.  
  7.                         <!-- mysql port -->
  8.                         <property name="port">3306</property>
  9.  
  10.                         <!-- mysql schema -->
  11.                         <property name="schema">dbname</property>
  12.  
  13.                         <!-- mysql user -->
  14.                         <property name="user">root</property>
  15.  
  16.                         <!--  mysql password -->
  17.                         <property name="password">root</property>
  18.  
  19.                 </factoryConfig>
  20.  
  21.                 <poolConfig class="com.meidusa.amoeba.net.poolable.PoolableObjectPool">
  22.                         <property name="maxActive">500</property>
  23.                         <property name="maxIdle">500</property>
  24.                         <property name="minIdle">10</property>
  25.                         <property name="minEvictableIdleTimeMillis">600000</property>
  26.                         <property name="timeBetweenEvictionRunsMillis">600000</property>
  27.                         <property name="testOnBorrow">true</property>
  28.                         <property name="testWhileIdle">true</property>
  29.                 </poolConfig>
  30.         </dbServer>

此部分定義真實mysql服務器的端口,數據庫名稱,mysql用戶及密碼。
主從數據庫定義:

  1. <dbServer name="Master"  parent="abstractServer">
  2.                 <factoryConfig>
  3.                         <!-- mysql ip -->
  4.                         <property name="ipAddress">192.168.0.1</property>
  5.                 </factoryConfig>
  6.         </dbServer>
  7. <dbServer name="Slave1"  parent="abstractServer">
  8.                 <factoryConfig>
  9.                         <!-- mysql ip -->
  10.                         <property name="ipAddress">192.168.0.2</property>
  11.                 </factoryConfig>
  12.         </dbServer>
  13. <dbServer name="Slave2"  parent="abstractServer">
  14.                 <factoryConfig>
  15.                         <!-- mysql ip -->
  16.                         <property name="ipAddress">192.168.0.3</property>
  17.                 </factoryConfig>
  18.         </dbServer>
  19.         <dbServer name="virtualSlave" virtual="true">
  20.                 <poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">
  21.                         <!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA-->
  22.                         <property name="loadbalance">1</property>
  23.  
  24.                         <!-- Separated by commas,such as: server1,server2,server1 -->
  25.                         <property name="poolNames">Slave1,Slave2</property>
  26.                 </poolConfig>
  27.         </dbServer>

此部分定義主服務器,從服務器,及從服務器鏈接池。這裏只定義數據庫地址,它們的用戶及密碼就是上面的abstractServer裏的設置。注意用來鏈接真實mysql服務器的用戶必須擁有遠程鏈接權限。

amoeba.xml配置

amoeba鏈接驗證配置:

  1. <property name="authenticator">
  2.                                 <bean class="com.meidusa.amoeba.mysql.server.MysqlClientAuthenticator">
  3.  
  4.                                         <property name="user">root</property>
  5.                                         
  6.                                         <property name="password">root</property>
  7.  
  8.                                         <property name="filter">
  9.                                                 <bean class="com.meidusa.amoeba.server.IPAccessController">
  10.                                                         <property name="ipFile">${amoeba.home}/conf/access_list.conf</property>
  11.                                                 </bean>
  12.                                         </property>
  13.                                 </bean>
  14.                         </property>

這裏定義鏈接amoeba時用來驗證的用戶及密碼。
讀寫分離配置:

  1. <property name="defaultPool">Master</property>
  2.                 <property name="writePool">Master</property>
  3.                 <property name="readPool">virtualSlave</property>

defaultPool:配置了默認的數據庫節點,一些除了SELECTUPDATEINSERTDELETE的語句都會在defaultPool執行。
writePool :配置了數據庫寫庫,一般配爲Master,如這裏就配置爲以前定義的Master數據庫。
readPool :配置了數據庫讀庫,一般配爲Slave或者Slave組成的數據庫池,如這裏就配置以前的virtualSlave數據庫池。

amoeba啓動

啓動命令:

  1. amoeba start

此命令之前臺的方式啓動,會輸出啓動時的信息,檢查沒有錯誤信息後,中斷,並後臺運行:

  1. amoeba start &

FAQ

一、沒法正常鏈接?
首先根據執行amoeba start輸出的信息排除配置文件沒有問題,以後確認mysql用戶是否有遠程鏈接的權限,而後檢查網站的數據庫配置文件是否設置正確。
二、如何配置網站數據庫鏈接文件?
默認的端口應該爲8066,用戶及密碼在amoeba.xml裏設置。
參考:http://docs.hexnova.com/amoeba/single-dbserver.html
http://docs.hexnova.com/amoeba/rw-splitting.html

相關文章
相關標籤/搜索