WordPress 安裝 Redis 與 PHP 擴展

在 WordPress 那台 VPS 上安裝 Redis 伺服器以及讓 PHP 能與 Redis 溝通的擴展模組。

# 更新套件清單
sudo apt update

# 安裝 Redis 伺服器與 PHP Redis 擴展
sudo apt install redis-server php-redis -y

安裝完成後,確認 Redis 是否正常啟動:

sudo systemctl status redis-server


配置 Redis 記憶體限制

為了防止 Redis 佔用過多系統記憶體導致主機當機,建議設定上限。編輯設定檔:

sudo nano /etc/redis/redis.conf

在檔案中找到或加入以下兩行(假設分配 256MB 給快取,可根據你的 VPS 記憶體大小調整):

程式碼片段

maxmemory 256mb
maxmemory-policy allkeys-lru

這代表記憶體滿了時,Redis 會自動刪除最近最少使用的舊資料。修改後重啟 Redis:

sudo systemctl restart redis-server

WordPress 設定檔調整

雖然外掛會幫你處理大部分工作,但有時候需要手動在 wp-config.php 定義 Redis 的連線資訊,特別是如果你有特殊需求時。編輯 WordPress 根目錄下的 wp-config.php,在 /* That's all, stop editing! */ 之前加入:

PHP

define('WP_REDIS_HOST', '127.0.0.1');
define('WP_REDIS_PORT', 6379);
// 如果這台主機上有連往不同網站,可以用這個區分快取
define('WP_CACHE_KEY_SALT', 'my_site_name_');

安裝與啟用外掛

  1. 登入 WordPress 後台。
  2. 前往 外掛 -> 安裝外掛
  3. 搜尋 Redis Object Cache(作者通常是 Till Krüss)。
  4. 點擊安裝並啟用。
  5. 前往 設定 -> Redis,點擊 Enable Object Cache 按鈕。

驗證快取是否運作

啟用後,你可以在後台看到 Status 顯示為 Connected。你也可以在主機終端機輸入以下指令來即時監控:

redis-cli monitor

當你重新整理網頁時,終端機會瘋狂跳出 GETSET 的指令,這代表 WordPress 已經成功將原本要丟給 MySQL 的負擔,轉移到 Redis 記憶體快取中了。


Redis 記憶體分配評估

從你的系統負載來看,總實體記憶體只有 961Mi(約 1GB),目前已使用了 537Mi,可用空間(available)僅剩 423Mi。在這種記憶體受限的環境下,將 Redis 設定為 256MB 會有點冒險,因為這還沒計算 PHP-FPM 或是其他系統服務在流量高峰時可能增加的消耗。

為了確保系統穩定,不至於因為記憶體耗盡(OOM)而導致資料庫連線或 PHP 崩潰,我建議將 Redis 的 maxmemory 調低。


修正後的設定建議

建議先從 128MB 開始,這對於一般的 WordPress 網站來說,存放 Object Cache(如選單、文章 metadata、選項等)通常已經足夠。

編輯 /etc/redis/redis.conf

程式碼片段

# 針對 1GB RAM 的小主機建議值
maxmemory 128mb
maxmemory-policy allkeys-lru

這樣的設定能確保 Redis 在記憶體用滿時,會優先刪除最久沒被使用的資料,而不會導致系統當機。


觀察可用記憶體

你可以定期觀察 available 這一欄。如果設定 128MB 後,available 穩定維持在 200Mi 以上,且 Redis 的命中率很高,則可以維持現狀。如果 available 掉到 100Mi 以下,你就必須考慮縮減 Redis 或是 PHP-FPM 的行程數量。

設定完成並重啟 Redis 後,可以到 WordPress 後台的 Redis 設定頁面看目前的 Memory Usage,如果它一直沒用到 100MB,那就代表 128MB 的上限非常安全。


查看 Redis 記憶體即時狀態

你可以直接在終端機輸入以下指令,這會顯示 Redis 目前實際使用的記憶體、峰值以及目前的碎片率:

Bash

redis-cli info memory | grep -E "used_memory_human|used_memory_peak_human|maxmemory_human"

這條指令會讓你看到:

  • used_memory_human:目前 Redis 裡面存的資料佔了多少空間。
  • used_memory_peak_human:從啟動到現在,最高曾經用到多少。
  • maxmemory_human:你剛剛在設定檔限制的 128MB。

判斷是否需要加碼記憶體

在觀察一段時間後,你可以根據顯示的數據做調整:

  • 如果 used_memory 經常達到 128MB:代表你的網站資料量大,Redis 正在頻繁刪除舊快取來放新資料(這稱為 Eviction)。這時連線效率會稍微下降,如果 available 還有剩,可以考慮調到 192MB。
  • 如果 used_memory 遠低於 128MB:代表 128MB 非常充足,不需要再動它。

另一個實用的監控指令

如果你想看更細節的統計資訊(例如快取命中率),可以執行:

Bash

redis-cli info stats | grep keyspace
  • keyspace_hits:從快取拿到資料的次數(越高越好)。
  • keyspace_misses:快取找不到,必須跑去問 MySQL 的次數(越低越好)。

如果你的命中率(Hits)遠高於遺失率(Misses),恭喜你,你的兩台 VPS 溝通效率已經因為 Redis 的加入而大幅提升,因為很多請求在 WordPress 這台就處理完了,根本不需要跨網段去吵 MySQL。


建立 Redis 與系統監控指令腳本

這個腳本會整合 Linux 剩餘記憶體、Redis 記憶體使用狀況以及快取命中率,方便你隨時檢查主機健康狀態。

請在 WordPress 主機執行以下步驟:

建立腳本檔案:

nano check_redis.sh

貼入以下內容:

#!/bin/bash
echo "=== 系統記憶體狀態 ==="
free -h | grep -E "Mem|可用"
echo ""
echo "=== Redis 記憶體使用現況 ==="
redis-cli info memory | grep -E "used_memory_human|used_memory_peak_human|maxmemory_human"
echo ""
echo "=== Redis 快取命中統計 ==="
redis-cli info stats | grep -E "keyspace_hits|keyspace_misses"
  1. 儲存離開,並賦予執行權限:chmod +x check_redis.sh

如何閱讀監控結果

之後你只需要輸入 ./check_redis.sh 就能看到結果。

  • used_memory_human 如果接近你設定的 maxmemory,代表快取空間快滿了。
  • keyspace_hitskeyspace_misses 的比例很重要。例如命中 1000 次、遺失 10 次,代表 99% 的請求都直接在本地端處理,兩台 VPS 之間的網路負擔降低了 99%。

進階調整建議

如果你發現 keyspace_misses 很高,通常是因為 WordPress 還有許多資料沒被快取進去,或是快取時間太短。這時可以檢查 WordPress 的 Redis 外掛設定,確保 Object Cache 確實有發揮作用。

另外,如果這兩台主機在同機房,別忘了檢查 WordPress 連接 MySQL 的 DB_HOST 是不是已經改成 內網 IP,這是最直接影響延遲的物理因素。


Redis 多網站衝突問題與解決方案

在同一台 VPS 上讓多個網站共用同一個 Redis 伺服器,確實會發生衝突。如果沒有特別設定,網站 A 的快取資料可能會被網站 B 讀取或覆蓋,導致登入狀態錯亂、顯示錯誤的文章內容或是後台設定被跳槽。

要解決這個問題,有兩種最常見且有效的方法:


方法一:使用不同的資料庫編號(最簡單)

Redis 預設提供 16 個資料庫(編號為 0 到 15)。你可以指定網站 A 使用資料庫 0,網站 B 使用資料庫 1。

編輯每個網站根目錄下的 wp-config.php,加入對應的資料庫編號:

PHP

// 網站 A 的設定
define('WP_REDIS_DATABASE', 0);

// 網站 B 的設定
define('WP_REDIS_DATABASE', 1);

這樣兩個網站的資料就會在 Redis 內部被隔離開來。


方法二:使用 Cache Key Salt(最推薦)

如果你的網站超過 16 個,或是想更保險一點,可以使用「加鹽」機制。這會讓 Redis 在儲存每一筆資料時,都在 key 的前面加上一段特定的前綴字串。

在每個網站的 wp-config.php 加入唯一的識別碼:

PHP

// 網站 A
define('WP_CACHE_KEY_SALT', 'site_a_name_');

// 網站 B
define('WP_CACHE_KEY_SALT', 'site_b_name_');

這樣即使它們都在同一個 Redis 資料庫裡,Key 的名稱也會變成 site_a_name_optionssite_b_name_options,彼此互不干涉。


注意事項與記憶體壓力

雖然解決了衝突,但你必須注意記憶體用量

  • 加總計算:你之前設定的 maxmemory 128mb 是所有網站共用的總額。如果 site A 佔了 80MB,site B 佔了 60MB,總合就會超過 128MB。
  • LRU 機制:當總量超過 128MB 時,Redis 會根據我們設定的 allkeys-lru 策略,隨機刪除所有網站中最舊的快取。這不會讓網站掛掉,但會導致兩邊的快取命中率都下降。

如果你發現 check_redis.sh 顯示的 used_memory 經常卡在 128MB,建議稍微上修這個數值,或是增加 VPS 的實體記憶體。

需要我幫你檢查目前這台 VPS 上所有網站加起來大約佔用了多少 Redis Key 嗎?


查看 Redis 中各網站的 Key 數量

你可以利用 Redis 的 INFO keyspace 指令來查看目前各個資料庫(Database)分別存了多少筆資料。如果你是使用「方法一」(不同資料庫編號)來區隔網站,這個指令最精準。

請執行:

redis-cli info keyspace

輸出的結果會像這樣:

db0:keys=1250,expires=1200,avg_ttl=4500

db1:keys=850,expires=800,avg_ttl=3800

這代表 db0(網站 A)存了 1250 個 Key,而 db1(網站 B)存了 850 個。如果某個 db 的 keys 數量遠高於其他網站,代表該網站對 Redis 的依賴度最高,或是該網站的外掛/佈景產生了大量的快取資料。


查看具體的前綴分佈

如果你是使用「方法二」(Cache Key Salt),所有的 Key 都會擠在同一個 db0 裡面。這時我們可以用 SCAN 指令搭配 grep 來估算各網站的比例:

# 查看 site_a 開頭的 key 有多少個
redis-cli --scan --pattern 'site_a_name_*' | wc -l

# 查看 site_b 開頭的 key 有多少個
redis-cli --scan --pattern 'site_b_name_*' | wc -l

綜合效能評估建議

當多個網站併行時,請持續關注你的 check_redis.sh 指令。如果發現以下情況,請採取對應行動:

  • Evicted Keys 增加:執行 redis-cli info stats | grep evicted_keys。如果這個數字一直跳動,代表 128MB 真的不夠用了,Redis 正在被迫踢掉舊資料來塞新網站的資料。
  • CPU 使用率飆升:如果 Redis 所在的 WordPress 主機 CPU 負載變高,可能是因為某些網站的快取過期時間(TTL)設太短,導致 Redis 頻繁處理寫入動作。

目前你總共架設了幾個 WordPress 網站?如果超過 3 個,且平均流量不低,建議將 maxmemory 稍微放寬到 200mb256mb,只要確保系統整體的 available 記憶體還有 100Mi 以上即可。


建立多網站 Redis 統計腳本

這個腳本會自動掃描 Redis 裡所有的資料庫(Database),並針對你設定的網站前綴(Salt)進行統計。這能讓你一眼看出哪個網站最佔空間。

建立腳本:

nano redis_sites_check.sh

貼入以下內容(請根據你實際在 wp-config.php 設定的 SALT 修改 SITES 列表):

#!/bin/bash
# 在下方的括號內填入你各個網站設定的 WP_CACHE_KEY_SALT
SITES=("site_a_name_" "site_b_name_" "site_c_name_")

echo "=== 各資料庫 Key 總數 (按 DB 編號) ==="
redis-cli info keyspace | grep "^db"

echo ""
echo "=== 各網站前綴 Key 統計 (按 SALT 區分) ==="
for prefix in "${SITES[@]}"
do
    count=$(redis-cli --scan --pattern "${prefix}*" | wc -l)
    echo "網站前綴 [${prefix}]: ${count} 個 Key"
done

echo ""
echo "=== Redis 強制刪除統計 (Evicted) ==="
redis-cli info stats | grep evicted_keys

賦予權限並執行:

chmod +x redis_sites_check.sh && ./redis_sites_check.sh

如何解讀統計數據

  • Key 數量落差大:如果某個網站有數千個 Key,而其他只有幾百個,通常是因為該網站安裝了較多外掛(如 WooCommerce、多語系外掛),或是佈景主題寫得比較肥大。
  • evicted_keys > 0:如果這個數字不是 0,代表你的 maxmemory 已經封頂,Redis 正在「丟車保帥」。只要這數字增加得很快,就建議加碼 50-100MB 的記憶體。

最終優化小提醒

由於你的主機記憶體只有 1GB 左右,跑多個網站加上 Redis 會讓記憶體非常吃緊。除了 Redis 優化,建議也要檢查兩台 VPS 之間的 Ping 值

在 WordPress 主機輸入:

ping <MySQL 主機內網 IP>
  • < 1ms:完美,同機房內網。
  • 1ms ~ 10ms:普通,可能是同地區但不同機房。
  • > 50ms:不理想,建議考慮將兩台主機遷移到同一個機房,這比任何軟體優化都有效。

如果你發現 Ping 值過高,或是想要了解如何優化 PHP-FPM 的行程數量來騰出記憶體,隨時告訴我。


選擇建議:維持現狀使用 DB0 加前綴即可

針對只有 3 個網站的情況,我建議繼續使用 DB0 並搭配 Salt 前綴,不需要刻意切換到不同的 Keyspace(DB 1, DB 2 等)。

主要原因有三點:

  1. 管理方便:從你跑出來的腳本可以看到,目前 3 個網站的 Key 總數才 3300 多個,佔用記憶體僅 7.41MB,遠低於 128MB 的上限。放在一起管理非常輕鬆。
  2. 性能差異極小:在 Redis 中,切換 DB 並不會帶來明顯的性能提升,反而會讓你的監控腳本變複雜(需要切換資料庫才能掃描)。
  3. 擴充性:使用前綴(Salt)是目前 WordPress 社群最主流的做法,許多自動化備份或快取清理外掛對前綴的支援度也比切換 DB 來得好。

數據診斷與優化建議

從你的 redis_status.sh 結果來看,有幾個有趣的發現:

  • 命中率 (Hits) 表現良好:你的 keyspace_hits (25104) 遠大於 keyspace_misses (7042),這代表大約 78% 的請求已經不需要去吵 MySQL 了,這對提升兩台 VPS 間的溝通效率非常有感。
  • 記憶體非常充裕:目前只用了 7.41MB,你可以放心地把這 3 個網站都跑在 Redis 上,完全不需要擔心 128MB 不夠用。
  • 第三個網站活性低stickerline_ 只有 47 個 Key,這通常代表該網站流量極低,或者 Redis Object Cache 外掛雖然啟用了,但還沒累積足夠的存取資料。

下一個優化重點:減少 Misses

雖然 78% 的命中率不錯,但如果你想進一步壓榨效能,可以觀察 keyspace_misses。這通常是因為:

  1. 快取過期:某些資料的 TTL(存活時間)設太短。
  2. 不支援快取的查詢:某些複雜的 SQL 查詢或特定外掛(如購物車、會員中心)為了即時性會避開快取。

你可以試著在離峰時段執行 redis-cli monitor,看看哪些 Key 經常出現 MISS,如果是某些特定的頁面,可以檢查該頁面的外掛設定。

目前你的兩台 VPS 溝通效率已經比「裸奔」狀態好很多了。需要我幫你看看 MySQL 那台主機的 slow query log (慢查詢日誌),找出那些 Redis 擋不掉、且執行太慢的 SQL 指令嗎?

About the author

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *