Description
Symfony version(s) affected
>= 5.4
Description
#47003 added support for using multiple Redis Sentinel hosts. However, if the first Sentinel host cannot be resolved (e.g. because a DNS name cannot be resolved or because the server is not responding), a \RedisException
is thrown and the code does not try to connect to the other Sentinel hosts.
In this code block, it tries to connect to Sentinel and resolve the master address:
symfony/src/Symfony/Component/Cache/Traits/RedisTrait.php
Lines 228 to 232 in 64303aa
The call to getMasterAddrByName()
is throwing the RedisException
and will prevent any attempt to connect to other Sentinel hosts.
This exception is thrown if the hostname cannot be resolved:
RedisException {#407 ▼
#message: "Redis server sentinel1:26379 went away"
#code: 0
#file: "/srv/www/vendor/symfony/cache/Traits/RedisTrait.php"
#line: 231
-previous: ErrorException {#408 ▼
#message: "Warning: RedisSentinel::getMasterAddrByName(): php_network_getaddresses: getaddrinfo for sentinel1 failed: Name or service not known"
#code: 0
#file: "/srv/www/vendor/symfony/cache/Traits/RedisTrait.php"
#line: 231
#severity: E_WARNING
trace: {▶}
}
trace: {▶}
}
And this exception if the server port is invalid (no previous exception in this case):
RedisException {#408 ▼
#message: "Redis server redis:16379 went away"
#code: 0
#file: "/srv/www/vendor/symfony/cache/Traits/RedisTrait.php"
#line: 231
trace: {▶}
}
How to reproduce
You could use this environment variable / DSN to observe the behavior with invalid host names at first and valid host names afterwards:
REDIS_DSN=redis:?host[sentinel1:26379]&host[sentinel2:26379]&host[sentinel3:26379]&redis_sentinel=db
If you have a Redis Sentinel instance running, just add the host as second (or later) and observe that nothing is written into your Redis instance.
If you do not have a Redis Sentinel instance running, the same behavior can be verified by adding an exit
statement after the if-block from the code snippet above. The code will not terminate, since it never reaches that statement.
Possible Solution
The call to getMasterAddrByName()
could be wrapped in a simple try...catch to suppress any error.
I am not sure if there are valid errors that should not be caught. In that case, the exception message could be checked for specific errors.
Additional Context
I haven't investigated how this behaves with Relay.