首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL Proxy 實戰:從源碼編譯到 Lua 腳本實現讀寫分離與負載均衡完整教學

     編輯:MySQL 資料庫相關知識

MySQL Proxy 定位

官方 C 語言開發的 MySQL 協議層代理,支援 Lua 腳本可編程控制連線路由、查詢改寫、審計、熔斷。定位:輕量、透明、可編程的中間件。

注意:MySQL Proxy 0.8.x 後官方停止維護,生產環境建議改用 ProxySQL(高效能、多執行緒、生產就緒)或 MySQL Router(官方、InnoDB Cluster 整合)。本文為歷史版本教學保留。

環境準備


# CentOS 5.2 範例
yum install -y autoconf automake libtool flex pkgconfig bzr mysql-devel

# 手動編譯依賴(系統版本過低)
wget https://monkey.org/~provos/libevent-1.4.9-stable.tar.gz
tar zxf libevent-1.4.9-stable.tar.gz && cd libevent-1.4.9-stable && ./configure && make && make install

wget https://ftp.gnome.org/pub/gnome/sources/glib/2.18/glib-2.18.4.tar.gz
tar zxf glib-2.18.4.tar.gz && cd glib-2.18.4 && ./configure && make && make install

wget https://www.lua.org/ftp/lua-5.1.4.tar.gz
tar zxf lua-5.1.4.tar.gz && cd lua-5.1.4
# 64位需修改 src/Makefile CFLAGS += -fPIC
make linux && make install
cp etc/lua.pc /usr/local/lib/pkgconfig/
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig

編譯安裝 MySQL Proxy 0.7.0


wget https://dev.mysql.com/get/Downloads/MySQL-Proxy/mysql-proxy-0.7.0.tar.gz
tar zxf mysql-proxy-0.7.0.tar.gz && cd mysql-proxy-0.7.0
./configure && make && make check && make install

# 驗證
mysql-proxy -V
# 輸出版本、glib、libevent、lua 版本

SELinux 阻擋問題解決


# 錯誤:error while loading shared libraries: libmysql-chassis.so.0: cannot restore segment prot after reloc: Permission denied
# 方案 1:關閉 SELinux(永久)
vi /etc/selinux/config
SELINUX=disabled
reboot

# 方案 2:針對性放行(不關閉 SELinux)
chcon -t texrel_shlib_t /usr/local/lib/libmysql-chassis.so.0
chcon -t texrel_shlib_t /usr/local/lib/libmysql-proxy.so.0

核心參數速查

參數說明預設
--proxy-address監聽地址:埠(應用連這裡):4040
--proxy-backend-addresses後端 Master 寫入節點,可多個無
--proxy-read-only-backend-addresses後端 Slave 唯讀節點,可多個無
--proxy-lua-scriptLua 腳本路徑(核心邏輯)無
--admin-address管理介面埠:4041
--daemon守護進程模式前景
--proxy-skip-profiling關閉查詢分析開啟

啟動腳本範例


#!/bin/bash
# /etc/init.d/mysql-proxy
export LUA_PATH=/usr/local/share/mysql-proxy/?.lua

case "$1" in
  start)
    /usr/local/sbin/mysql-proxy --daemon \
      --proxy-address=192.168.1.6:3306 \
      --proxy-backend-addresses=192.168.1.6:3307 \
      --proxy-read-only-backend-addresses=192.168.1.10:3306 \
      --proxy-lua-script=/usr/local/share/mysql-proxy/rw-splitting.lua
    ;;
  stop)
    killall mysql-proxy
    ;;
  restart)
    $0 stop && $0 start
    ;;
  *)
    echo "Usage: $0 {start|stop|restart}"
    exit 1
    ;;
esac

Lua 腳本核心邏輯:rw-splitting.lua 關鍵點


-- 內建讀寫分離腳本關鍵片段
function read_query(packet)
  if packet:byte() == proxy.COM_QUERY then
    local sql = packet:sub(2)
    if sql:match("^%s*SELECT") then
      -- SELECT 路由到 Slave
      proxy.connection.backend_ndx = proxy.global.config.rnd:get_n()
    else
      -- 非 SELECT(含事務、DDL、DML)路由到 Master
      proxy.connection.backend_ndx = 1
    end
  end
end

-- 修正 Bug:DEFAULT DB 同步問題
if cmd.type ~= proxy.COM_INIT_DB and
   c.default_db and c.default_db ~= s.default_db then
  proxy.queries:prepend(2, string.char(proxy.COM_INIT_DB) .. c.default_db)
end

管理介面驗證


mysql -u root -h 127.0.0.1 -P 4041
SELECT * FROM proxy_connections;
SELECT * FROM proxy_config;

負載均衡驗證腳本


-- test-conn.lua
function read_query(packet)
  print("read_query: connection.backend_ndx: " .. proxy.connection.backend_ndx)
end

# 啟動帶測試腳本
mysql-proxy --proxy-address=192.168.1.6:3306 \
  --proxy-backend-addresses=192.168.1.231:3306 \
  --proxy-backend-addresses=192.168.1.10:3306 \
  --proxy-lua-script=/opt/test-conn.lua

# 客戶端多次連線,觀察輸出輪詢 1,2,1,2...

生產級替代方案對比

中間件語言多執行緒熱加載配置監控指標推薦指數
MySQL ProxyC + Lua單執行緒支援基礎⭐ (停止維護)
ProxySQLC++多執行緒支援 (Admin 介面)豐富 (Prometheus Exporter)⭐⭐⭐⭐⭐
MySQL RouterC++多執行緒支援 (配置檔/Metadata)基礎⭐⭐⭐⭐ (InnoDB Cluster 首選)
MaxScaleC++多執行緒支援豐富⭐⭐⭐⭐ (MariaDB 生態)
MySQL Proxy 是啟蒙教材,ProxySQL 是生產主力。理解 Proxy 協議層路由原理,遷移 ProxySQL 只需改配置與管理介面習慣。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved