萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 資料庫 >> MySQL 教學

MySQL 讀寫分離利器:mysqlnd_ms 插件安裝配置全攻略

什麼是 mysqlnd_ms?

mysqlnd_ms (Master Slave) 是 PHP mysqlnd (MySQL Native Driver) 的一個插件,能在 PHP 層透明實現:

  • 讀寫分離:SELECT 路由到 Slave,INSERT/UPDATE/DELETE 路由到 Master
  • 負載均衡:多 Slave 輪詢/隨機/加權分發讀請求
  • 連線切換與保持:自動處理主從切換、連線池複用

無需修改應用 SQL,僅需配置插件即可生效。

前置需求

  • PHP 編譯時指定 --with-mysqlnd(PHP 5.3+ 內建,無需額外安裝 MySQL Client Library)
  • PHP 版本 ≥ 5.3,推薦 5.6/7.x
  • MySQL 主從複寫已正常運行

一、編譯安裝 mysqlnd_ms

# 1. 下載源碼 (以 1.5.2 為例)
wget https://pecl.php.net/get/mysqlnd_ms-1.5.2.tgz
tar -zxvf mysqlnd_ms-1.5.2.tgz
cd mysqlnd_ms-1.5.2

# 2. phpize & 配置(路徑請替換為你的實際 PHP 安裝路徑)
/usr/local/php/bin/phpize
./configure --with-php-config=/usr/local/php/bin/php-config

# 3. 編譯安裝
make && make install

# 4. 記錄輸出的擴展路徑,例:
# Installing shared extensions: /usr/local/php/lib/php/extensions/no-debug-non-zts-20131226/

二、修改 php.ini 載入擴展

extension = /usr/local/php/lib/php/extensions/no-debug-non-zts-20131226/mysqlnd_ms.so
mysqlnd_ms.enable = On
mysqlnd_ms.config_file = /usr/local/php/etc/mysqlnd_ms_plugin.ini

三、建立插件配置檔 mysqlnd_ms_plugin.ini

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "192.168.6.135",
                "socket": "/tmp/mysql.sock"
            }
        },
        "slave": {
            "slave_0": {
                "host": "192.168.6.136",
                "port": "3306"
            },
            "slave_1": {
                "host": "192.168.6.137",
                "port": "3306"
            }
        },
        "filters": {
            "random": {
                "sticky": "1"
            }
        }
    }
}

關鍵配置解析:

  • myapp:邏輯集群名稱,PHP 連線時用作 host(如 mysqli_connect('myapp', ...))
  • master / slave:定義主/從節點,支援多個
  • filters.random.sticky=1:同一 PHP 請求內,讀操作固定路由到同一 Slave,避免同步延遲導致讀到舊資料
  • 其他策略:roundrobin(輪詢)、user(自定義回調)、quality_of_service(最終一致性/會話一致性/強一致性)

四、PHP 代碼測試

<?php
$mysqli = new mysqli("myapp", "user", "password", "dbname");
if ($mysqli->connect_errno) {
    die("連線失敗: " . $mysqli->connect_error);
}

// 寫操作 → 自動走 Master
$mysqli->query("INSERT INTO test (val) VALUES ('write from master')");

// 讀操作 → 自動走 Slave (random + sticky)
$result = $mysqli->query("SELECT * FROM test");
while ($row = $result->fetch_assoc()) {
    var_dump($row);
}
$mysqli->close();

五、WordPress 整合範例

編輯 wp-config.php:

/** MySQL 主機 - 使用 mysqlnd_ms 邏輯名稱 **/
define('DB_HOST', 'myapp');

其餘 DB_USER、DB_PASSWORD、DB_NAME 保持不變。

六、常見坑與避雷

  1. PHP 必須用 mysqlnd 編譯:php -i | grep mysqlnd 確認 mysqlnd 為 enabled。
  2. 事務邊界識別:插件靠 BEGIN/COMMIT 判斷寫事務,自動提交模式下單條 UPDATE 也會路由 Master。
  3. 預存程序/多語句:無法自動判斷讀寫,建議在 SQL 前加註解 /*mysqlnd_ms=master*/ 強制指定。
  4. 連線池復用:PHP-FPM 工行程模式下,連線在請求結束時釋放,下次請求重新路由,符合預期。

七、監控與除錯

// 獲取當前連線資訊
$mysqli->query("SELECT @@server_id");  // 觀察是否在 Master/Slave 間切換

// 開啟插件除錯日誌 (php.ini)
mysqlnd_ms.debug = 1
mysqlnd_ms.log_file = /tmp/mysqlnd_ms.log
copyright © 萬盛學電腦網 all rights reserved