Search code examples
phplaravelredisredis-sentinelphpredis

Laravel 10 - phpredis with sentinels possible?


I'm looking into a way to setup Redis HA using Sentinels, and am looking into drivers that will work with laravel and laravel/horizon for job scheudling. I've been looking into solutions on google - there doesn't seem to be either documentation or tutorials available, so I'm wondering if that's even possible?

I've found this: https://github.com/monospice/laravel-redis-sentinel-drivers, but this seems to only support up to Laravel 8, and no more.

I've tried setting up a connection like this:

config/database.php

   'client' => 'phpredis',
 
   'redis-sentinel' => [
   env('REDIS_SENTINEL_1'),
   env('REDIS_SENTINEL_2'),
   env('REDIS_SENTINEL_3'),
   'options' => [
      'replication' => 'sentinel',
      'service' => env('REDIS_SENTINEL_SERVICE', 'mymaster'),
      'parameters' => [
         'password' => env('REDIS_SENTINEL_PASSWORD', null),
         'database' => 0,
      ],
   ],
]

and using it, but it doesn't quite seem to work.

Any help or resources how to set it up properly would be greatly appreciated


Solution

  • You have to install predis package composer require predis/predis and add this driver configuration to your config/database.php file (on the same level with connections array)

        'connections' => [
               ...skipped....
               'redis' => [
                   'driver' => 'redis'
               ]
         ],
    
        'redis' => [
            'client' => 'predis',
    
            // In this case default connection is for single redis instance
            'default' => [
                'host' => env('REDIS_HOST', 'localhost'),
                'password' => env('REDIS_PASSWORD', null),
                'port' => env('REDIS_PORT', 6379),
                'database' => 0,
            ],
    
            // We define sentinel connection for the HA cluster
            'sentinel' => [
                [
                    'host' => env('REDIS_SENTINEL_HOST1', 'localhost'),
                    'port' => env('REDIS_SENTINEL_PORT1', 26379),
                    'timeout' => env('REDIS_CONNECT_TIMEOUT', 0.2)
                ],
                [
                    'host' => env('REDIS_SENTINEL_HOST2', 'localhost'),
                    'port' => env('REDIS_SENTINEL_PORT2', 26379),
                    'timeout' => env('REDIS_CONNECT_TIMEOUT', 0.2)
                ],
                [
                    'host' => env('REDIS_SENTINEL_HOST3', 'localhost'),
                    'port' => env('REDIS_SENTINEL_PORT3', 26379),
                    'timeout' => env('REDIS_CONNECT_TIMEOUT', 0.2)
                ],
                'options' => [
                    'service' => env('REDIS_SENTINEL_SERVICE', 'mymaster'),
                    'replication' => 'sentinel', 
                    'password' => null,
                    'parameters' => [
                        'database' => 0,
                    ]
                ]
            ],
    
            // We can use different connection for cache
            'sentinel-cache' => [
                [
                    'host' => env('REDIS_SENTINEL_HOST1', 'localhost'),
                    'port' => env('REDIS_SENTINEL_PORT1', 26379),
                    'timeout' => env('REDIS_CONNECT_TIMEOUT', 0.2)
                ],
                [
                    'host' => env('REDIS_SENTINEL_HOST2', 'localhost'),
                    'port' => env('REDIS_SENTINEL_PORT2', 26379),
                    'timeout' => env('REDIS_CONNECT_TIMEOUT', 0.2)
                ],
                [
                    'host' => env('REDIS_SENTINEL_HOST3', 'localhost'),
                    'port' => env('REDIS_SENTINEL_PORT3', 26379),
                    'timeout' => env('REDIS_CONNECT_TIMEOUT', 0.2)
                ],
                'options' => [
                    'service' => env('REDIS_SENTINEL_SERVICE', 'mymaster'),
                    'replication' => 'sentinel',
                    'password' => null,
                    'parameters' => [
                        'database' => 1,
                    ]
                ],
            ]
        ]
    

    Please notice that cache cleans the database periodicaly, so you must check that it is able to specify different redis connection in the database/cache.php:

    'stores' => [
        ...skipped...
    
       'redis' => [
           'driver' => 'redis',
           'connection' => env('CACHE_CONNECTION','default')
       ]
    ]
    

    so now you can use

    SESSION_DRIVER=redis
    SESSION_CONNECTION=sentinel
    QUEUE_DRIVER=redis
    QUEUE_CONNECTION=sentinel
    CACHE_DRIVER=redis
    CACHE_CONNECTION=sentinel-cache
    

    as app environment variables