-
Notifications
You must be signed in to change notification settings - Fork 78
bin/resque: add support for connecting with a cluster client #59
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bin/resque: add support for connecting with a cluster client #59
Conversation
e8bf589
to
b7bb014
Compare
It seems to me that simply having a comma in the host variable would indicate that cluster mode is desired. We can drop some configuration complexity by checking for a comma ( |
We could however, that would mean for single hostname clusters, we'd need to have a wonky looking hostname like |
What is the benefit of using the cluster driver with a single host? |
In my specific use case, it's not a single host but a single hostname that is used for the entire cluster which is load balanced by a Kubernetes service. |
I must be missing something. The Cluster driver will still only create one connection per hostname, regardless of how many servers are actually behind that name (neither the Redis extension nor PHP stream connections have access to more than the first IP that a hostname resolves to, as is the norm for any software that doesn't explicitly work around that default behavior of OS-level hostname-lookup functions). So your Cluster still only has a single Client inside, giving you exactly zero benefit to using the driver in the first place, plus a bit of extra function call overhead for your trouble. |
You’re correct about the one connection per hostname but using the cluster client is also about knowing how to find data on the (potentially) sharded cluster. If the regular client attempts a lookup and doesn’t hit the correct node on the first go, it will throw an exception as it (by design) doesn’t follow the redirection from Redis; the cluster client will and successfully fetches the key regardless of which mode has the data. |
Interesting. I saw exactly zero code that would handle such a difference in the Cluster driver itself. It doesn't even handle connecting - it makes the regular driver do it. All the Credis Cluster class does is wrap one or more (regular) Credis Client objects, forwarding requests to the specific client object and returning the results without further processing, based on what i just read earlier. So I wonder what mechanism it uses to do that? In any case, I'm not against supporting the extra variable if we have to for things to function correctly, but i also think it should be an override for the single hostname edge case rather than an on/off switch for the entire feature. Commas in the host string should automatically select the Cluster driver accordingly whether the additional value is set or not. |
How do you feel about supporting either? Single hostnames needing cluster support can add the new environment flag and multiple hostnames separated by a comma also automatically get cluster support? I’m just thinking if I came across a single hostname with a trailing comma in a config file, I’d be confused as to why it was like that. Having an extra comma may also limit the reuse of REDIS_BACKEND as an environment variable as everything that used it would then need to take that into account. |
That hybrid approach is what I was trying to describe above, yeah, so I'm on board with that. |
b7bb014
to
c851597
Compare
Thanks for clarifying; that wasn't apparent to me. I've added support for comma delimitered hosts in |
Having a dig further into this, there is something not quite right either with Credis or our cluster. For the test, I'm doing the following:
I would expect that this works as the library mentions it support clustering, that this works out of the box. Probably hold on this PR until this is resolved in case I'm holding this wrong. |
Looks like there is something funky with single hostnames as if I explicitly add all the IPs in the cluster instead, this works as expected with the |
@danhunsaker do you happen to have a working example of multiple hostnames with
|
It's worth noting as well, |
As `bin/resque` currently works, it pulls in the hostname to use from the environment using `getenv`. The problem with this is that you cannot pass in an array which is what the underlying Redis library uses[1] to determine whether it initialises a `Credis_Client` or a `Credit_Cluster` for the connection. This solves that issue by introducing support for passing a comma separated list of hostnames to `REDIS_BACKEND` which will be expanded to an array before passing to `Credis_Cluster`. [1]: master/lib/Resque/Redis.php#L128
06f7629
to
51ea37f
Compare
if(!empty($REDIS_BACKEND)) { | ||
if (empty($REDIS_BACKEND_DB)) | ||
Resque::setBackend($REDIS_BACKEND); | ||
else | ||
Resque::setBackend($REDIS_BACKEND, $REDIS_BACKEND_DB); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
resque-scheduler has the same block, so support should probably also be added there
I've finally got this working for our use case however, not as I originally intended. The kicker is that This was an oversight on my behalf and confused the heck out of everything because I was expecting it to work in the same way where the client would follow the Thanks for your help though! |
Can you share what proxy? Or is it internal? Thanks |
envoy proxy with the redis cluster extension |
As
bin/resque
currently works, it pulls in the hostname to use fromthe environment using
getenv
. The problem with this is that you cannotpass in an array which is what the underlying Redis library uses to
determine whether it initialises a
Credis_Client
or aCredit_Cluster
for the connection.
This solves that issue by introducing support for passing a comma
separated list of hostnames to
REDIS_BACKEND
which will be expanded toan array before passing to
Credis_Cluster
.