在 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_');
安裝與啟用外掛
- 登入 WordPress 後台。
- 前往 外掛 -> 安裝外掛。
- 搜尋 Redis Object Cache(作者通常是 Till Krüss)。
- 點擊安裝並啟用。
- 前往 設定 -> Redis,點擊 Enable Object Cache 按鈕。
驗證快取是否運作
啟用後,你可以在後台看到 Status 顯示為 Connected。你也可以在主機終端機輸入以下指令來即時監控:
redis-cli monitor
當你重新整理網頁時,終端機會瘋狂跳出 GET 或 SET 的指令,這代表 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"
- 儲存離開,並賦予執行權限:
chmod +x check_redis.sh
如何閱讀監控結果
之後你只需要輸入 ./check_redis.sh 就能看到結果。
- used_memory_human 如果接近你設定的 maxmemory,代表快取空間快滿了。
- keyspace_hits 與 keyspace_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_options 與 site_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 稍微放寬到 200mb 到 256mb,只要確保系統整體的 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 等)。
主要原因有三點:
- 管理方便:從你跑出來的腳本可以看到,目前 3 個網站的 Key 總數才 3300 多個,佔用記憶體僅 7.41MB,遠低於 128MB 的上限。放在一起管理非常輕鬆。
- 性能差異極小:在 Redis 中,切換 DB 並不會帶來明顯的性能提升,反而會讓你的監控腳本變複雜(需要切換資料庫才能掃描)。
- 擴充性:使用前綴(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。這通常是因為:
- 快取過期:某些資料的 TTL(存活時間)設太短。
- 不支援快取的查詢:某些複雜的 SQL 查詢或特定外掛(如購物車、會員中心)為了即時性會避開快取。
你可以試著在離峰時段執行 redis-cli monitor,看看哪些 Key 經常出現 MISS,如果是某些特定的頁面,可以檢查該頁面的外掛設定。
目前你的兩台 VPS 溝通效率已經比「裸奔」狀態好很多了。需要我幫你看看 MySQL 那台主機的 slow query log (慢查詢日誌),找出那些 Redis 擋不掉、且執行太慢的 SQL 指令嗎?