將WordPress 的Redis plugin 配置為使用AWS ElastiCache redis cluster

Written by

in

這個plugin 已經存在很多年,一直以來我都使用single node 的方式,因為wordpress 的cache data 從mysql 取一遍沒有太大的難度,但是對於高負載的網站來說,這總是不合理的。

而single node 有他壞掉後就要從database reload data 的問題,雖然眾多的雲端服務商提供了failover 的機制來避免node 壞掉不可用的問題,但難免會有某些網站需要大量的寫入,比如wordpress.com這樣的。

這個plugin 應該很早就支持cluster 的方式了,只不過我從來沒注意過,而他的github 又語焉不詳,我想他可能是想要賣他的pro 版本。

嘗試了一下,有一點需要注意的地方:

single node 方式支持tls,但cluster mode 不支持tls,所以elasticache serverless 不行,因為serverless 的tls 無法關閉,只能是self design cluster mode enabled。

我認為作者在這個地方隱晦的表明了這一點,雖然他沒有直接講出來。

用如下的方式配置wp-config.php 即可。

/**wp redis object cache*/
define('WP_REDIS_CLIENT','pecl');
define('WP_REDIS_CLUSTER', [ 'tcp://valkey-cluster.clustercfg.apn3.cache.amazonaws.com:6379',] );

那麼php session 呢?

修改php.ini 原來的配置,如下兩處,

;session.save_handler = redis
session.save_handler = rediscluster

;session.save_path = "tcp://valkey.0001.apne1.cache.amazonaws.com"
session.save_path = "seed[]=valkey-cluster.clustercfg.apn3.cache.amazonaws.com:6379"

一個有用的測試session 的script

<?php
//simple counter to test sessions. should increment on each page reload.
session_start();
$count = isset($_SESSION['count']) ? $_SESSION['count'] : 1;
echo $count;

$_SESSION['count'] = ++$count;

再看看ElastiCache 裡面有了沒,雖然不應該用keys command ……

valkey-cluster.clustercfg.apn3.cache.amazonaws.com:6379> keys *PHP*
1) "PHPREDIS_CLUSTER_SESSION:d9uv2emobrcmpc7g5fk7bduqgq"
2) "PHPREDIS_CLUSTER_SESSION:d30c1t3kln5df0uij8f7gqibnt"
3) "PHPREDIS_CLUSTER_SESSION:bh5buktvsumi1k6j7hcpjcil6c"
4) "PHPREDIS_CLUSTER_SESSION:3s6jagi622rt0nqdof9i1otd09"
5) "PHPREDIS_CLUSTER_SESSION:fq6tnls1dcfv0bspljq9j2k5i4"
6) "PHPREDIS_CLUSTER_SESSION:1p1ajkvr641cp99edm9cm74o6s"

2025-08-22 update

糾正我的錯誤,這個plugin 是支持ElastiCache serverless 的,wp-config.php 中可以按照如下配置:

/**wp redis object cache*/
define('WP_REDIS_CLIENT', 'pecl');
define('WP_REDIS_HOST', 'valkey.serverless.apn3.cache.amazonaws.com');
define('WP_REDIS_PORT', 6379);
define('WP_REDIS_SCHEME', 'tls');
define('WP_REDIS_DATABASE', 0);

2025-11-16 update

我不是很確定可以使用ElastiCache serverless 是因為我的配置下他還沒有進行scaling,只有一個master 和一個slave,效果等同於主從複製模式,如果存在多個shards,是否還可用,能否正常跳轉?

valkey-serverless:6379> CLUSTER INFO
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:2
cluster_size:1
cluster_current_epoch:0
cluster_my_epoch:0
cluster_stats_messages_sent:0
cluster_stats_messages_received:0
total_cluster_links_buffer_limit_exceeded:0

okay,我創建了一個多分片的集群,實驗證明,這個plugin 看起來無法處理MOVED,之所以可暫時使用ElastiCache serverless 是因為他只有一個shard:

wp redis status
RedisException: MOVED 12096 valkey-cluster.cache.amazonaws.com:6379 in /home/www/bbken.org/wp-content/object-cache.php:1934
Stack trace:
#0 /home/www/bbken.org/wp-content/object-cache.php(1934): Redis->get()
#1 /home/www/bbken.org/wp-content/object-cache.php(193): WP_Object_Cache->get()
#2 /home/www/bbken.org/wp-includes/functions.php(1779): wp_cache_get()
#3 /home/www/bbken.org/wp-includes/load.php(939): is_blog_installed()
#4 /home/www/bbken.org/wp-settings.php(176): wp_not_installed()
#5 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/WP_CLI/Runner.php(1374): require('...')
#6 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/WP_CLI/Runner.php(1293): WP_CLI\Runner->load_wordpress()
#7 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/LaunchRunner.php(28): WP_CLI\Runner->start()
#8 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/bootstrap.php(84): WP_CLI\Bootstrap\LaunchRunner->process()
#9 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/wp-cli.php(35): WP_CLI\bootstrap()
#10 phar:///usr/local/bin/wp/php/boot-phar.php(20): include('...')
#11 /usr/local/bin/wp(4): include('...')
#12 {main}
Error: Error establishing a Redis connection. To disable Redis, delete the `object-cache.php` file in the `/wp-content/` directory.

2025-11-17 update

但是經過AI 對於source code 的分析,以及我的反覆測試,如下的配置實際測試可以使用:

/**wp redis object cache*/
define('WP_REDIS_CLIENT', 'phpredis');
define('WP_REDIS_CLUSTER', [
    'tls://clustercfg.valkey-cluster.cache.amazonaws.com:6379',
]);
define('WP_REDIS_SSL_CONTEXT', [
    'verify_peer' => false,
]);

從CloudWatch 的指標看起來,三個節點中都有讀寫keys,沒有問題,完美。

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *