Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[Cache] Redis Sentinel only attempting connection via first host with PHP Redis extension #51570

Copy link
Copy link
Closed
@digilist

Description

@digilist
Issue body actions

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:

$sentinel = new $sentinelClass($host, $port, $params['timeout'], (string) $params['persistent_id'], $params['retry_interval'], $params['read_timeout'], ...$extra);
if ($address = $sentinel->getMasterAddrByName($params['redis_sentinel'])) {
[$host, $port] = $address;
}

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.