Skip to content
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

Not very clear how connection pool works #80

Closed
danalex07 opened this issue Aug 12, 2020 · 9 comments
Closed

Not very clear how connection pool works #80

danalex07 opened this issue Aug 12, 2020 · 9 comments

Comments

@danalex07
Copy link

Hi @sewenew I'm using your client for my project and works like a charm, but I don't see clearly how to use the ConnectionPool option, I mean I'm no expert but I haven't been able to make it work, can u provide a clear example or maybe write it on the wiki? thanks a lot.

@sewenew
Copy link
Owner

sewenew commented Aug 13, 2020

@danalex07 Thanks for the suggestion! I'll add more detailed doc for connection pool to README.

struct ConnectionPoolOptions {
    // Max number of connections, including both in-use and idle ones.
    std::size_t size = 1;

    // Max time to wait for a connection. 0ms means client waits forever.
    std::chrono::milliseconds wait_timeout{0};

    // Max lifetime of a connection. 0ms means we never expire the connection.
    std::chrono::milliseconds connection_lifetime{0};
};

You can set the size of the pool with ConnectionPoolOptions::size, i.e. the max number of connections to Redis server for a Redis object. ConnectionPoolOptions::wait_timeout is the max time to wait for a connection, say, the pool size is 2, while 3 threads try to call the same Redis object at the same time, one of them will be blocked. ConnectionPoolOptions::connection_lifetime is the max lifetime of a connection, i.e. if the connection has been created for a long time, do a reconnection.

The following is an example of how to create a Redis object with connection pool.

ConnectionOptions connection_options;
connection_options.host = "127.0.0.1";
connection_options.port = 6666;

ConnectionPoolOptions pool_options;
pool_options.size = 3;
pool_options.wait_timeout = std::chrono::milliseconds(100);     // optional
pool_options.connection_lifetime = std::chrono::minutes(3);    // optional

Redis redis(connection_options, pool_options);

Regards

@danalex07
Copy link
Author

So that way I can create multiple Redis objects in multiple methods and all will be calling the same pool?
eg.

void method_a(){ Redis redis(connection_options, pool_options); redis.do_something(); }
void method_b(){ Redis redis(connection_options, pool_options); redis.do_something_else(); }

I'm asking this because in my app multiple threads are going to access method_a and method_b in a short period of time, so I'm worried about performance.

@sewenew
Copy link
Owner

sewenew commented Aug 19, 2020

@danalex07 These Redis objects DO NOT share a pool, instead they create different pool. Also each time method_a or method_b is called, it creates a new connection to Redis server, and it's expensive.

In fact, you should create a single Redis object, and reuse it in these two methods.

Redis redis(connection_options, pool_options);

void method_a(Redis &redis) {
    redis.do_something();
}

void method_b(Redis &redis) {
    redis.do_something_else();
}

It's thread-safe, and you can run both methods in a multi-thread environment.

Regards

@hrishikesh713
Copy link

hrishikesh713 commented Aug 21, 2020

@sewenew Really an awesome library with modern c++ support! I appreciate your efforts!
I also have couple of quick questions regarding the connection pool :

  1. if a connection is used within the pool does it get added back into the pool once it carries out a command without any error?
  2. If there is an error with the connection, does it still get added back to the pool ? If yes, then does an errored connection automatically tries to reconnect when another thread tries to use it?
  3. Is there any option of maximum retries with some kind of a backoff strategy for a connection within a connection pool?

@sewenew
Copy link
Owner

sewenew commented Aug 22, 2020

@hrishikesh713 Thanks for choosing redis-plus-plus :)

if a connection is used within the pool does it get added back into the pool once it carries out a command without any error?

YES

If there is an error with the connection, does it still get added back to the pool ? If yes, then does an errored connection automatically tries to reconnect when another thread tries to use it?

YES, a broken connection will be added to the pool. The next time when the broken connection is fetched from the pool, redis-plus-plus will reconnect it.

Is there any option of maximum retries with some kind of a backoff strategy for a connection within a connection pool?

NO, there's no such strategies. You have to do it with your own code, e.g. if you get an exception from redis-plus-plus, you can retry the command or give it up.

Regards

@sewenew
Copy link
Owner

sewenew commented Aug 24, 2020

Guys, I already updated doc for connection pool. I'll close this issue, if you still have problem on it, feel free to reopen it.

Regards

@sewenew sewenew closed this as completed Aug 24, 2020
@Nimrod0901
Copy link

Hi, I have some questions about the connection pool

  1. What's the difference between "create several Redis object with pool size 1, calling it in different threads" and "create one Redis object with a pool size of maybe thread number`? In another word, what's the benefit of using a connection pool?
  2. Will a broken connection be fetched with low priority since connect may be an expensive action.
  3. What is the best practice of setting the number of connection numbers? If I always call it under a single thread, will pool size 1 be enough?
    Thank you very much.

@sewenew
Copy link
Owner

sewenew commented Jan 19, 2022

@Nimrod0901

  1. The benefit of connection pool is to reuse connections and share connections between threads. To avoid too many connections to Redis, you can make the pool size smaller than the thread number, although some thread might wait a while before it gets the connection from the pool.
  2. NO. So far, we check whether the connection should be reconnected after we fetched the connection from the pool. NOTE: even if the connection is not broke, it might be reconnected if you set connection_lifetime or connection_idle_time.
  3. It depends on lots of things, and you'd better do a benchmark for it. However, if you runs in single thread, you don't need to set the size larger than 1.

Regards

@Nimrod0901
Copy link

Thanks for replying.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants