Does pool's connection number can be adjusted dynamically based on different RPS?
How does radix's pool work
I checked the source codes, it works as below
- The pool will create all connections initial with pool.size number: https://github.com/mediocregopher/radix/blob/v3/pool.go#L359
- When use redis connection to get data, if some crtical network happens, the connection will be removed from the pool
- This is test case for it: https://github.com/mediocregopher/radix/blob/v3/pool_test.go#L210
-
refill operation will be executed periodically to add connection:
- When do
refill operation, allow some overflow- https://github.com/mediocregopher/radix/blob/v3/pool.go#L485
- https://github.com/mediocregopher/radix/blob/v3/pool.go#L343
- When do
-
doOverflowDrain operation will be executed periodically to delete the redundant connection:
- If current connection number is greater than pool.size, the redundant connection will be deleted: https://github.com/mediocregopher/radix/blob/v3/pool.go#L520
(If i miss something, please tell me)
Does the pool work as below?
We expect the pool feature like below
- There should have
minConnectionNumberandmaxConnectionNumberconfiguration. - Normally, the init connection number should be
minConnectionNumber - The connection number should be adjusted automatically according to
how much the RPS against redis server- Under higher RPS, the connections should be created, but can't exceed maxConnectionNumber
- Under lower RPS, the connections should be removed, but cannot be lower than the minConnectionNumber
Is it possible to make radix pool to support adjust the connection number dynamically based on RPS in future?
(If already support, can share how to implement?)
Hi @ningyougang , I think you understand the Pool implementation pretty well, just a minor clarification:
When do refill operation, allow some overflow
The refill operation will not create a new connection if totalConns is greater-than/equal-to size (not totalSize). This means the refill operation never adds a connection into the overflow, but it will not remove it either. Removing from the overflow is only done by doOverflowDrain.
Based on your two links here I think you may have confused totalConns and totalSize. totalSize is the "idle" size of the pool plus the overflow, it does not change for the lifetime of the pool. totalConns is the number of connections currently existing, and it does change during the lifetime of the pool.
As for your question:
Does the pool work as below?
There should have minConnectionNumber and maxConnectionNumber configuration.
Let's be precise and call minConnectionNumber the idleConnectionNumber, since the minimum connection number is always zero (for example, if there is a network failure and all connections are killed). The idleConnectionNumber is the number of connections that Pool will attempt to maintain when there are no commands being executed, and is equal to the size parameter passed into NewPool.
Under higher RPS, the connections should be created, but can't exceed maxConnectionNumber
In the current implementation this requirement is not possible. You can have either:
-
maxConnectionNumber == idleConnectionNumber, by usingPoolOnEmptyWaitorPoolOnEmptyErrAfter. -
maxConnectionNumber == infinity, by usingPoolOnEmptyCreateAfterandPoolOnFullBuffer.
This limitation is mentioned in the documentation of PoolOnFullBuffer. Removing this limitation would require some kind of mechanism added before this line which only allows totalSize - totalConns new connections to be created concurrently. Adding a mechanism like this would be tricky and prone to impacting performing in the rest of the Pool, but I'm open to suggestions on how to implement it.
Some final notes on this subject:
In general relying on creating connections on the fly to handle commands has proven to be a poor strategy, as redis does not deal with connection churn very efficiently (or at least, it didn't in the past). The overflow buffer was introduced partially to combat this, but implicit pipelining is a much better solution, as it allows multiple concurrent commands to share a single connection in most cases.
radix/v4 expanded this mechanism to support all situations where it's theoretically possible, and so the radix/v4 Pool is drastically simpler than the v3, not supporting any dynamic sizing at all.
I hope this is helpful, please let me know if you have any further questions.
@mediocregopher thank you for your detail explanation
Closed