架構拓撲
Master (192.168.1.109) ──binlog──► Slave (192.168.1.110)
│ │
└──────────► mysql-proxy (192.168.1.112) ◄── 應用連接 (Port 4040)
│
讀寫分離 Lua 腳本
寫操作 → Master (192.168.1.109:3306)
讀操作 → Slave (192.168.1.110:3306)
環境準備 (3 台 CentOS/RHEL 5.8)
- MySQL 5.5.37 二進制包 (`mysql-5.5.37-linux2.6-i686.tar.gz`)
- mysql-proxy 0.8.4 (`mysql-proxy-0.8.4-linux-glibc2.3-x86-32bit.tar.gz`)
- 關閉防火牆 / SELinux:`service iptables stop`、`setenforce 0`
1. MySQL 統一安裝 (三台均執行)
cd /usr/local
tar -zxvf mysql-5.5.37-linux2.6-i686.tar.gz
ln -s mysql-5.5.37-linux2.6-i686 mysql
groupadd mysql; useradd -g mysql mysql
cd mysql
chown -R root:mysql .
chown -R mysql:mysql data/
cp support-files/my-large.cnf /etc/my.cnf
cp support-files/mysql.server /etc/init.d/mysqld
service mysqld start
2. Master 配置 (192.168.1.109)
vi /etc/my.cnf
[mysqld]
server-id = 1
log-bin = mysql-bin
thread_concurrency = 2
service mysqld restart
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.1.%' IDENTIFIED BY '123456';
mysql> FLUSH PRIVILEGES;
mysql> SHOW MASTER STATUS\G;
-- 記錄 File: mysql-bin.000001, Position: 107
3. Slave 配置 (192.168.1.110)
vi /etc/my.cnf
[mysqld]
server-id = 11
relay-log = mysql-log
relay-log-index = mysql-log.index
thread_concurrency = 2
service mysqld restart
mysql> CHANGE MASTER TO
MASTER_HOST='192.168.1.109',
MASTER_USER='repl',
MASTER_PASSWORD='123456',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=107;
mysql> START SLAVE;
mysql> SHOW SLAVE STATUS\G;
-- 確認 Slave_IO_Running: Yes, Slave_SQL_Running: Yes
4. mysql-proxy 安裝與基礎啟動 (192.168.1.112)
cd /usr/local
tar -zxvf mysql-proxy-0.8.4-linux-glibc2.3-x86-32bit.tar.gz
ln -s mysql-proxy-0.8.4-linux-glibc2.3-x86-32bit mysql-proxy
groupadd mysql-proxy; useradd -g mysql-proxy mysql-proxy
cd mysql-proxy
chown -R root:mysql-proxy .
echo 'export PATH=$PATH:/usr/local/mysql-proxy/bin' > /etc/profile.d/mysql-proxy.sh
source /etc/profile
# 基礎啟動 (無讀寫分離)
mysql-proxy --daemon --log-level=debug --log-file=/var/log/mysql-proxy.log \
--plugins="proxy" \
--proxy-backend-addresses="192.168.1.109:3306" \
--proxy-read-only-backend-addresses="192.168.1.110:3306"
# 驗證
netstat -ntulp | grep 4040
mysql -uroot -p123456 -h192.168.1.112 --port=4040
5. 讀寫分離:rw-splitting.lua 腳本啟用
# 停止現有進程
killall mysql-proxy
# 啟用 Lua 腳本
mysql-proxy --daemon --log-level=debug --log-file=/var/log/mysql-proxy.log \
--plugins="proxy" \
--proxy-backend-addresses="192.168.1.109:3306" \
--proxy-read-only-backend-addresses="192.168.1.110:3306" \
--proxy-lua-script="/usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua"
關鍵命令參數速查
| 參數 | 含義 |
| --proxy-backend-addresses | 寫操作目標 (Master) |
| --proxy-read-only-backend-addresses | 讀操作目標 (Slave,可多個逗號分隔) |
| --proxy-lua-script | 讀寫分離/熔斷/分片等邏輯腳本 |
| --daemon | 守護進程模式 |
| --log-level=debug | 調試日志級別 |
驗證讀寫分離效果
# 連接 proxy
mysql -uroot -p123456 -h192.168.1.112 -P4040
# 執行寫操作 → 應路由到 Master
INSERT INTO test.tbl VALUES (1);
# 執行讀操作 → 應路由到 Slave
SELECT * FROM test.tbl;
# 查看 proxy 日志確認路由
tail -f /var/log/mysql-proxy.log
生產環境避坑指南
- mysql-proxy 0.8.x 為 Alpha 版,不建議生產核心鏈路使用。替代方案:ProxySQL (GA、高性能、集群管理)、MaxScale (MariaDB)、VIP + Keepalived / HAProxy。
- 單點故障: proxy 掛掉全業務不可用 → 部署雙 proxy + Keepalived VIP 漂移。
- Slave 延遲導致讀舊數據: 關鍵業務強制走 Master (`SELECT /*+ MASTER */` 或單獨連接)。
- Lua 腳本限制: 複雜 SQL (預處理、存儲過程、多語句) 路由可能失效。
- 連接池配置: 應用連接池直連 proxy,proxy 後端連接池需單獨調優。