You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: blog/2024/2024-08-28-redis-cluster-tls-laravel/index.mdx
+45-3Lines changed: 45 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -194,7 +194,7 @@ So lets break this down:
194
194
* Anything `_PREFIX` is because Redis Clusters does NOT support multiple databases. So we prefix items to prevent collisions on a shared server.
195
195
*`REDIS_PERSISTENCE` keeps Laravel using the same connection instead of opening a connection on each Redis usage.
196
196
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:
198
198
199
199
*`Cannot use 'DEL' with redis-cluster`
200
200
*`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
307
307
127.0.0.1:6379>
308
308
```
309
309
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.
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.
311
353
312
354
---
313
355
@@ -327,7 +369,7 @@ This was working great
327
369
328
370
##### `Couldn't map cluster keyspace using any provided seed`
329
371
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.
0 commit comments