phpredis / phpredis

A PHP extension for Redis
Other
9.97k stars 2.13k forks source link

Sentinel session handler #1862

Open amfleurke opened 3 years ago

amfleurke commented 3 years ago

The redis session handler does not support sentinel. It is not usable for High Availability.

Add sentinel support with a retry mechanism when master dies till slave is promoted to master.

jankelemen commented 2 years ago

Adding proposal on how this feature could behave.

php.ini could look as follows:

session.save_handler = redissentinel
session.save_path = "tcp://host1:26379, tcp://host2:26379, tcp://host3:26379"

Then when trying to connect to Redis, there would be a loop in which each specified sentinel would be asked what is the IP address and port of the master (probably with the info sentinel command). So IP and port would be used from the sentinel that responded first. In case none of them respond, an error would be thrown.

And in case of failover, the loop where everybody is asked who is the master would be repeated.

zenstark commented 2 years ago

+1

jtz-ar commented 2 years ago

+2

damienbkx commented 1 year ago

+3

Adam7288 commented 1 year ago

+4

BHare1985 commented 1 year ago

+5

bradymiller commented 1 year ago

+6

Adam7288 commented 1 year ago

Is there any recommended workaround for this?

Tristan971 commented 1 year ago

Recommended I don’t know, but we use HAProxy to front various redis sentinel setups and have the relevant PHP applications connect to it instead @Adam7288 ; this might help in that regard https://www.haproxy.com/blog/haproxy-advanced-redis-health-check

edit: note that this introduces an extra hop between PHP and Redis, which can slow things down depending on your network setup and your speed requirements

Adam7288 commented 1 year ago

Thank you for the response. I am not sure that will work for our situation, we may have to accept lack of HA and go with memcache for now as the session handler. Seems like a simple addition, really wish the phpredis team would take this request seriously.

Tristan971 commented 1 year ago

Fwiw I haven’t personally used it so I can’t vouch for it but https://github.com/twitter/twemproxy is another option for either of redis or memcache that you might be interested in

As for native sentinel support and why this issue isn’t done yet, while I also wish it was there the whole sentinel protocol is alas not that great with PHP, because it involves a get-master command prior to all connections (to the sentinel instance, to find out who’s the current master) followed by a conn to the actual redis instance, so in practice it can be a somewhat significant overhead if you don’t have some statefulness capacity (this can be worked around in PHP, but it’s certainly not natural), or your connections are short lived (like in a webapp context)

At least for us that was the primary motivation to go the haproxy route (as holder and checker of the information of who is the current master node) at the time; I only ended up reusing it when an app made use of sessions and I found this unfixed issue

bradymiller commented 1 year ago

@Adam7288 and @Tristan971 ,

I also had to figure out a way to get this to work for a OpenEMR project kubernetes installation. Ended up using the pipy proxy (https://flomesh.io/pipy/) that likely does same as above HAProxy, where the pipy proxy connects to each of the 3 redis nodes every 5 seconds to ensure always pointing the traffic to the master redis node: https://github.com/openemr/openemr-devops/tree/master/kubernetes

The problem I have run into is getting the pipy proxy to support tls connections to redis (btw, need to build dev version of phpredis since the tls support is not yet in a production phpredis version), which I haven't figured out how to get to work (https://github.com/openemr/openemr-devops/pull/349) yet. Will probably give HAProxy a stab and see if have better luck with that.

Tristan971 commented 1 year ago

A tip in advance then @bradymiller, you’ll probably want to combine haproxy’s support for DNS resolution of backends (server-template is the doc keyword you want) with a k8s headless service (which exposes SRV records); as for tls to redis I’m not sure if that will work

brgsousa commented 11 months ago

+7