rhubarbgroup / redis-cache

A persistent object cache backend for WordPress powered by Redis. Supports Predis, PhpRedis, Relay, replication, sentinels, clustering and WP-CLI.
https://wordpress.org/plugins/redis-cache/
GNU General Public License v3.0
425 stars 148 forks source link

TLS connection fails: Redis server went away using remote DigitalOcean Redis Cluster #501

Closed sangemaru closed 6 months ago

sangemaru commented 6 months ago

Hi. I have deployed a managed Redis 7 cluster on DigitalOcean. When trying to connect using redis-cli's AUTH command, it connects successfully. When trying to use WordPress, it fails.

Description

I configured it on my WordPress instance with the following settings:

Config::define( 'WP_REDIS_SCHEME', 'tls' );
Config::define( 'WP_REDIS_HOST', 'db-redis-url.c.db.ondigitalocean.com' );
Config::define( 'WP_REDIS_PORT', 25061 );

Config::define( 'WP_REDIS_PASSWORD', [ 'default', 'hidden' ] );
Config::define( 'WP_REDIS_TIMEOUT', 1 );
Config::define( 'WP_REDIS_READ_TIMEOUT', 1 );

// change the database for each site to avoid cache collisions
Config::define( 'WP_REDIS_DATABASE', 0 );

// prefix for cache key (separation between sites)
Config::define( 'WP_REDIS_PREFIX', env('WP_ENV') ?: 'dev1:' );

// selective flush of only the prefix above
Config::define( 'WP_REDIS_SELECTIVE_FLUSH', true );

// supported clients: `phpredis`, `credis`, `predis` and `hhvm`
Config::define( 'WP_REDIS_CLIENT', 'phpredis' );

// automatically delete cache keys after 1 days
Config::define( 'WP_REDIS_MAXTTL', 60 * 60 * 8 * 1 );

// consume less memory
Config::define( 'WP_REDIS_IGBINARY', true );

Expected Behavior

I expect it to connect or return a more descriptive error.

Actual Behavior

Error establishing a Redis connection Redis server went away

Possible Fix

It may be I just misconfigured it, and better documentation is needed for these scenarios.

Steps to Reproduce

  1. Set up managed database.
  2. Add connection parameters to wp-config.php or equivalent.
  3. Try to access from front-end.

Additional context

We are running into issues where high server load makes a locally running Redis instance unstable and prone to failure. Because of this, we want to move Redis to its own dedicated cluster and access it remotely.

Environment

tillkruss commented 6 months ago

If you’re using a Redis Cluster then you must use the cluster configuration constant and not the host/port constant.

If you’re unable to connect to Redis, make sure your droplet is on the same network as the Redis cluster.

sangemaru commented 6 months ago

@tillkruss I'm struggling to match the Cluster configuration I'm being provided with the documentation for setting up the configuration constant.

I get 3 types of connection options from DigitalOcean and I've tried to populate the cluster configuration using all 3 variants, but I have a feeling I'm misunderstand how the constant works.

Connection Parameters

username = username
password = password
host = private-db-redis-region-id-do-user-id-0.c.db.ondigitalocean.com
port = 25061

Connection String

rediss://username:password@private-db-redis-region-id-do-user-id-0.c.db.ondigitalocean.com:25061

Flags

redli --tls -h private-db-redis-region-id-do-user-id-0.c.db.ondigitalocean.com -a password -p 25061

tillkruss commented 6 months ago

@sangemaru: Are you sure you're using a cluster? Because you're connecting via -h parameter and not -c in redis-cli.

What does redis-cli info cluster say for your instance?

sangemaru commented 6 months ago

@tillkruss I was able to connect by establishing a TLS tunnel using stunnel4 (the instructions from here)

After that I was able to connect using just the password constant definition, no other changes to the config.