X Tutup
Skip to content

Proposal: Native multi-host support for RedisSentinel #2819

@nikamodis

Description

@nikamodis

Summary

Currently, RedisSentinel accepts only a single host, requiring users to manually implement failover logic across multiple Sentinel instances. This defeats the purpose of Sentinel as a high-availability solution, since a single Sentinel node is itself a single point of failure.

This was previously raised in #2132, where the maintainer confirmed: "current implementation doesn't imply multiple sentinel nodes so you have to manage them by yourself."

I'd like to propose a concrete implementation and would appreciate feedback on the API design before opening a PR.

Proposed API

Backward-compatible — the current single-host usage continues to work unchanged.

// Current (unchanged)
$sentinel = new RedisSentinel(['host' => '10.0.0.1', 'port' => 26379]);

// New: multiple hosts with automatic failover
$sentinel = new RedisSentinel([
    'host' => [
        ['host' => '10.0.0.1', 'port' => 26379],
        ['host' => '10.0.0.2', 'port' => 26379],
        ['host' => '10.0.0.3', 'port' => 26379],
    ],
    'timeout' => 0.1,
    'password' => 'secret',
]);

// Automatically tries the next Sentinel if the current one is unreachable
$master = $sentinel->getMasterAddrByName('mymaster');

Proposed behavior

  1. On construction, connect to the first available Sentinel from the host array
  2. If the connected Sentinel becomes unreachable during a command, iterate through the remaining hosts and reconnect
  3. If no Sentinel is reachable, throw RedisException (same as current behavior with a single unreachable host)
  4. When host is a string (current usage), behavior is identical to today - no BC break

Implementation approach

Changes would be limited to:

  • redis_sentinel.c (__construct) - detect array-of-arrays in host, store the host list
  • sentinel_library.c - add a sentinel_connect_next() helper that iterates through hosts
  • REDIS_PROCESS_KW_CMD macro path - wrap command execution with retry-on-disconnect logic that calls sentinel_connect_next()

The existing redis_sock_create / redis_sock_connect / redis_sock_disconnect infrastructure can be reused - no new socket-level code needed.

Estimated scope: ~150-250 lines of C code + tests.

Why this matters

  • predis supports multi-host Sentinel natively - it's the primary reason many users stay on predis instead of phpredis (as noted in Support for multiple Redis Sentinels #2132)
  • Frameworks like Laravel could then offer phpredis + Sentinel as a first-class option
  • The laravel-redis-sentinel package exists solely to work around this limitation at the PHP level

Questions for maintainers

  1. Is overloading the host option (string vs array-of-arrays) acceptable, or would you prefer a separate option like hosts?
  2. Should retry behavior be configurable (e.g. retryInterval, maxRetries) or is simple iterate-and-fail sufficient?
  3. Any concerns with the general approach?

Happy to submit a PR once we align on the design. Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      X Tutup