openresty / lua-resty-redis

Lua redis client driver for the ngx_lua based on the cosocket API
1.9k stars 448 forks source link

Redis close or keepalive #147

Open Roycohen opened 6 years ago

Roycohen commented 6 years ago

Hi There,

We are using the module for a long time and I think we have a mem leak or something regarding the connections. I would like to know the following:

  1. Do we need to close redis connections? What happen if we are not closing the connection?
  2. When to use close and when to use keepalive? Do we need to use keepalive all the time?
  3. If we have timeout in connection do we still need to close or use keepalive on the object?
  4. If we get timeout when making a command, what we need to do? Is there a chance for mem leak?

Basically I want to understand what may cause mem leaks and what action to take under several circumstances.

spacewander commented 6 years ago

What happen if we are not closing the connection?

The connection will be closed during GC. However, when the GC will start is unpredictable and connection is limited, it will be better to close/keepalive the connections in time.

When to use close and when to use keepalive?

When you want to reuse the connection, use keepalive. If the connection is unreusable (for example, there is an network error happened in the connection). use close.

If we have timeout in connection do we still need to close or use keepalive on the object?

AFAIK, lua-resty-redis will close the connection when the timeout happened. A simple way to decide to use keepalive or not: if error happened, use close, else use keepalive.

If we get timeout when making a command, what we need to do? Is there a chance for mem leak?

Maybe there is network problem or the Redis server is too busy to handle the connection. Because the connection will be closed in GC eventually, I don't think it will cause a memory leak.

What's your kind of mem leak? Does it leak in C land or Lua land?

If it leaks in C land, you might need to trace malloc and free methods. If it leaks in Lua land, you might need to make a core dump and analyse the Lua State with gdb. See https://github.com/openresty/openresty-gdb-utils for some examples.

spacewander commented 6 years ago

Another option to detect leaking in C land: you could build OpenResty with ASAN support, like: https://github.com/openresty/openresty-packaging/blob/master/rpm/SPECS/openresty-openssl-asan.spec#L52, and see if there is any error report in the error log.

terryburton commented 4 years ago

When you want to reuse the connection, use keepalive. If the connection is unreusable (for example, there is an network error happened in the connection). use close.

Is there a consistent way to know whether a return results in the connection being unusable such that is should be closed?

In particular:

Thanks for entertaining 20 questions...

spacewander commented 4 years ago

@terryburton To answer all the questions, we need a new blog.

Short answer: As the doc says:

A Redis "error reply" results in a false value and a string describing the error.

If the command call returns false, "msg", then it is a redis protocol error. If the call returns nil, "msg", it is connection error and you can close the connection.