Laravel 10 - phpredis with sentinels possible?

728 views Asked by At

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

2

There are 2 answers

0
Alex On BEST ANSWER

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

0
ArtS On

Also, edit horizon.php to have something like

'defaults' => [
    'supervisor-1' => [
        'connection' => 'sentinel',
        'queue' => ['default'],
        'balance' => 'auto',
        'autoScalingStrategy' => 'time',
        'maxProcesses' => 1,
        'maxTime' => 0,
        'maxJobs' => 0,
        'memory' => 128,
        'tries' => 1,
        'timeout' => 60,
        'nice' => 0,
    ],
],

so all workers use the right queue connection.