-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Client possibly leaking state under high load #507
Comments
FWIW a similar issue occurs when using |
The Redis server version is 2.8.17 by the way.
|
Thanks for the detailed report. Will look into it. |
@fw42 Both @badboy and I spent some time trying to reproduce the issue, without luck. A couple of questions:
|
Yes, Linux (both locally and production), kernel 3.8.x. Sorry, I guess the "high load" was a bit vague. I can't really quantify that too much, but if you think it helps I can try to get some metrics (if you tell me what exactly you are looking for). Most of our graphs on the server-side look normal though. Redis itself is not under particularly high load at the time. Our application does about 315.000 http requests per minute and about 5000-7000 requests per minute to the Redis server in question, but that's a "normal" level for us. The reason why I said "under load" is just that we start seeing problems as soon as we enable a certain new codepath that triggers a higher amount of requests to Redis than before (about 1000 requests/minute more). Sorry for the confusion. And thanks for looking into this! |
We just tried switching from the hiredis connection driver to the Ruby driver. Same problem. |
I just added additional logging to the |
Thanks for investigating further. I'm gonna read the code once more, maybe I can find the problem (or even reproducing it). One question: is the |
As far as I can tell, the |
You said you were using Unicorn, that means you have forks. Update: Just took a deeper look: First, |
We reconnect all Redis clients in Unicorn's after_fork hook |
How do you reconnect? Having one global Redis instance and reconnecting that or creating a new one per fork? |
We just call |
So yeah, we don't instantiate a new object in after_fork (that's why we think there might be state leaking across requests). Changing it so that we do use a new object seems kind of like a hacky workaround, although it might actually work I guess. I can try that next to confirm/disconfirm your suspicions about this being a forking-related issue. Note though that this bug does not occur close in time to us forking Unicorn, so I don't think it's related. |
Thinking about it the fork-theory shouldn't cause this issue, especially if you're doing the right thing and reconnect. |
Ok, I feel like an idiot now :-) The bug is in our code, not in redis-rb. Please stop investigating. Thanks guys for trying to help! I will add another comment later explaining what exactly caused this. I'm sure you are curious now :-) @badboy: Wenn ich das nächste mal in Aachen bin geb ich dir ein Bier aus ;-) |
\o/ putting german hat on: Klingt super :) |
We are running into some problems that look very related to #502, #501.
We have code that looks like this:
and we occasionally get an exception that says:
NoMethodError: undefined method
each_slice' for nil:NilClass`The backtrace looks as follows:
Looking at the redis-rb source code, this seems very odd, given that the only command that seems to use
_hashify
for parsing ishgetall
. As you can see, neither our code nor the backtrace show any usage of thehgetall
command. We have somehgetall
though in other areas of our code.The above exception does not happen consistently but only sometimes and we haven't yet figured out how to reproduce it locally, although we can consistently trigger it in a production environment by enabling new code that uses
hgetall
(in a different codepath) using the same Redis client object as the above code.We use redis-rb in a single-threaded Ruby on Rails (4.1.8) web application, running on the Unicorn application server (4.8.2). Our redis-rb version is 26a4309 and we use hiredis 0.6.0. We use MRI Ruby 2.1.5. We use the default timeout values for the redis-rb client configuration.
Our current assumption is that the pipelining code might somehow be leaking state across requests (maybe there could be a
Future
forhgetall
in the pipeline that the client is trying to parse when reading the result of the aboveincrby
+expire
).Any tips on how to debug this would be greatly appreciated.
Thanks!
Ping @djanowski @badboy since you guys worked on the PR that fixed the issue which we thought was the cause of this (#502)
cc @camilo @jasonhl @byroot @csfrancis @tjoyal
The text was updated successfully, but these errors were encountered: