首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL Proxy 部署與 Lua 腳本實現讀寫分離實戰

     編輯:MySQL 綜合教學

MySQL Proxy 是官方早期推出的 Lua 可編程代理層,雖然已停止維護(最後版本 0.8.5),但其 Lua 腳本引擎實現讀寫分離 的思路極具啟發性,也是後續 Kingshard、MyCat、ProxySQL 等中間件的架構鼻祖。本文記錄在 Linux 下部署預編譯版 MySQL Proxy 0.6.0,配置 rw-splitting.lua 實現主寫從讀,並通過 sysbench 壓測驗證穩定性。

核心原理

  • Proxy 監聽應用端連接(如 3307),後端掛載 1 個 Master(寫)+ N 個 Slave(讀)。
  • Lua 腳本攔截查詢:SELECT、SHOW 等路由至 Slave;INSERT/UPDATE/DELETE、事務語句路由至 Master。
  • 連接池複用後端連接,減少應用頻繁建連開銷。

部署步驟(CentOS 6.x 示例)

1. 依賴與預編譯包獲取

# 需 Lua 5.1+,通常系統自帶
wget https://mysql.cdpa.nsysu.edu.tw/Downloads/MySQL-Proxy/mysql-proxy-0.6.0-linux-rhas4-x86.tar.gz
tar zxf mysql-proxy-0.6.0-linux-rhas4-x86.tar.gz
cd mysql-proxy-0.6.0-linux-rhas4-x86

2. 安裝二進制與 Lua 腳本

mv sbin/mysql-proxy /usr/local/sbin/
mv share/mysql-proxy /usr/local/share/
strip /usr/local/sbin/mysql-proxy  # 去除符號表縮小體積

3. 編寫啟動管理腳本 /etc/init.d/mysql-proxy

#!/bin/sh
export LUA_PATH="/usr/local/share/mysql-proxy/?.lua"
mode=${1:-start}

case $mode in
  start)
    mysql-proxy --daemon \
      --admin-address=:4401 \
      --proxy-address=:3307 \
      --proxy-backend-addresses=:3306 \
      --proxy-read-only-backend-addresses=192.168.133.232:3306 \
      --proxy-read-only-backend-addresses=10.10.74.61:3306 \
      --proxy-lua-script=/usr/local/share/mysql-proxy/rw-splitting.lua
    ;;
  stop)
    killall mysql-proxy
    ;;
  restart)
    $0 stop && $0 start || exit 1
    ;;
esac

關鍵參數說明:

  • --admin-address=:4401:管理界面(可查看連接池、執行 Lua 命令)。
  • --proxy-address=:3307:應用端連接地址(應用改連 3307)。
  • --proxy-backend-addresses=:3306:Master 寫節點。
  • --proxy-read-only-backend-addresses=IP:3306:可重複指定多個 Slave 讀節點。
  • --proxy-lua-script:指定讀寫分離腳本(官方自帶 rw-splitting.lua)。

4. 啟動與測試

chmod +x /etc/init.d/mysql-proxy
/etc/init.d/mysql-proxy start

# 應用端連接驗證
mysql -h127.0.0.1 -uroot -P3307 -e "SHOW PROCESSLIST;"
# 可見新連接建立在 Proxy 後端

5. sysbench 壓測驗證穩定性

# 準備測試數據
sysbench --test=oltp --mysql-table-engine=innodb --oltp-table-size=1000000 \
  --mysql-socket=/tmp/mysql.sock --mysql-user=root --mysql-db=test prepare

# 執行壓測
sysbench --test=oltp --mysql-table-engine=innodb --oltp-table-size=1000000 \
  --mysql-socket=/tmp/mysql.sock --mysql-user=root --mysql-db=test run

# 輸出示例
Threads fairness:
  events (avg/stddev): 10000.0000/0.00
  execution time (avg/stddev): 23.0387/0.00

無報錯、無掛起即說明基本穩定。

生產級調優建議

1. 連接池參數(修改 rw-splitting.lua)

-- 預設值過小,高並發易耗盡
min_idle_connections = 10   # 建議 10-50
max_idle_connections = 100  # 建議 100-500

2. 連接池保活與故障切換

  • Proxy 本身無心跳檢測後端存活,需外部監控(如 Keepalived + 脚本)實現 VIP 漂移。
  • 後端 Slave 掛掉時,Proxy 會返回錯誤給應用,應用層需有重試邏輯。

3. 讀寫分離邏輯擴展

官方 rw-splitting.lua 邏輯較簡單(按關鍵字判斷),實際業務中可能需:

  • 強制某些 SELECT 走主庫(如 /*master*/ SELECT ... 註釋標記)。
  • 事務內 SELECT 也走主庫(避免主從延遲導致讀舊數據)。
  • 識別 SELECT ... FOR UPDATE、LOCK IN SHARE MODE 路由主庫。

均可通過修改 Lua 腳本 read_query() 函數實現。

局限性與替代方案

維度MySQL Proxy 0.6/0.8現代替代品
維護狀態❌ 2014 年停止更新✅ ProxySQL、MyCat、Kingshard、Vitess 活躍維護
高可用無內建 HA,單點故障ProxySQL 支援 Cluster、Keepalived/VIP
效能單線程事件循環,極限 ~10k QPSProxySQL 多線程,單實例 100k+ QPS
功能豐富度僅基礎 RW 分離、Lua 擴展查詢重寫、緩存、熔斷、審計、分表路由
生產建議❌ 不推薦新項目使用✅ 首選 ProxySQL 或 MyCat

MySQL Proxy 適合作為「理解代理層原理、學習 Lua 腳本路由邏輯」的教學工具。生產環境請直接採用 ProxySQL(功能最全、社區最活)或 MyCat(國產、分表功能強),避免踩坑無人維護的舊專案。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved