Skip to content

Commit fa03886

Browse files
committed
chore: finish blog
1 parent 73bca81 commit fa03886

File tree

1 file changed

+45
-3
lines changed
  • blog/2024/2024-08-28-redis-cluster-tls-laravel

1 file changed

+45
-3
lines changed

blog/2024/2024-08-28-redis-cluster-tls-laravel/index.mdx

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ So lets break this down:
194194
* Anything `_PREFIX` is because Redis Clusters does NOT support multiple databases. So we prefix items to prevent collisions on a shared server.
195195
* `REDIS_PERSISTENCE` keeps Laravel using the same connection instead of opening a connection on each Redis usage.
196196

197-
With all of that we booted up our system and clicked around. We had a few crashes that became apparent when utilizing the cache or queues. These errors were:
197+
With all of that we booted up our system and clicked around. We had a few crashes that became apparent when utilizing the queues. These errors were:
198198

199199
* `Cannot use 'DEL' with redis-cluster`
200200
* `Cannot use 'EVAL' with redis-cluster`
@@ -307,7 +307,49 @@ This code would automatically build a key hash tag based on the queue name. Sure
307307
127.0.0.1:6379>
308308
```
309309

310-
This was working great
310+
This was working great and allowed us to leverage a cluster connection without having to remember to change any specific value. Any usage of our queue system would automatically produce a key that was safe for cluster usage. Now we were ready to ramp it up with TLS support. At this point with our confidence working with a local cluster we were ready to move to AWS and test our cluster with TLS.
311+
312+
We spun up an ElastiCache instance and made some configurations:
313+
314+
* Multi-AZ: Enabled
315+
* Encrypted at Rest: Enabled
316+
* Encrypted in Transit: Enabled
317+
* Transit Encryption Mode: Required
318+
319+
These tests didn't work too well with errors like:
320+
321+
* "Can't communicate with any node in the cluster"
322+
* "Couldn't map cluster keyspace using any provided seed"
323+
324+
This took us a bit, but it seemed PhpRedis was not configured to use TLS. We found digging through [PhpRedis documentation](https://github.com/phpredis/phpredis/blob/develop/cluster.md#declaring-a-cluster-with-an-array-of-seeds) that we needed to set `verify_peer` to `false` in our config. So we just needed to know how to pass a value to the `new RedisCluster` execution.
325+
326+
Fortunately, we can peek [Laravel sourcecode](https://github.com/laravel/framework/blob/12.x/src/Illuminate/Redis/Connectors/PhpRedisConnector.php#L199-L203) to see how it builds the RedisCluster, which was via the `context` array element.
327+
328+
```php {8-10}
329+
'redis' => [
330+
'client' => env('REDIS_CLIENT', 'phpredis'),
331+
'options' => [
332+
'cluster' => env('REDIS_CLUSTER', 'redis'),
333+
'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
334+
'persistent' => env('REDIS_PERSISTENCE', true),
335+
'timeout' => env('REDIS_TIMEOUT', 5),
336+
'context' => [
337+
'verify_peer' => env('REDIS_SSL_VERIFY_PEER', false),
338+
],
339+
],
340+
],
341+
```
342+
Once we had a `context` block that introduced `verify_peer` - we had a successful Redis Cluster connection with TLS. However, for local usage this change forced TLS which was not preferred. We had to get creative reading the connection name and setting the context based on that.
343+
344+
To recap our journey:
345+
346+
* We set up our `docker-compose.yml` to run a Redis Cluster.
347+
* We configured our `.env` to point to the cluster.
348+
* We added a `clusters` block to our `config/database.php` file using a non-default name of `aws`.
349+
* We created a custom `QueueServiceProvider` to override the default Redis connection to use a key hash tag.
350+
* We changed the `context` block to include `verify_peer` to allow TLS connections on the base Redis options.
351+
352+
Now we tested out a few fault scenarios with failover to ensure our cluster was working as expected. As long as our timeout was set to a reasonable value (5 seconds) the node failover worked as expected and recovered.
311353

312354
---
313355

@@ -327,7 +369,7 @@ This was working great
327369

328370
##### `Couldn't map cluster keyspace using any provided seed`
329371

330-
* Your cluster server is unreachable, generally because its expecting TLS and you aren't sending it.
372+
* Your cluster server is unreachable, generally because its requiring/preferring TLS and you aren't sending it.
331373

332374
##### Laravel Horizon won't work with a Cluster
333375

0 commit comments

Comments
 (0)