-
Notifications
You must be signed in to change notification settings - Fork 3
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
Add MinIdleConnsHeadroom support #10
Conversation
I would consider an alternative logic: define the Let me explain myself: consider a 1 minute period, if a connection has been used during that last 1 minute period, then we don't consider it "idle" at all: it is idle in terms of the network, but we know that some load spike during the last minute has used it, so we shouldn't really close it. Let's call these connections used during the last 1 minute "recently used". Let's say we have 100 active connections, then with If the use decreases, let's say to 50 active conns, then we'll close connections until we have 75 (50 recently used + 25 idle). This will not happen in a single close, as the number of active connections will naturally decrease over time. I see two advantages in this:
This is just an alternative idea to consider, I'm not saying there's something wrong with your logic 👍 |
I like your idea because you don't have to think about the absolute minimum value to set. I'm going to change the implementation. |
26b9689
to
ace2832
Compare
ace2832
to
a3b7d09
Compare
Signed-off-by: Marco Pracucci <marco@pracucci.com>
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.
LGTM, thanks!
memcache/memcache.go
Outdated
// 2. Keep at least 1 idle connection. | ||
numRecentlyUsed := len(freeConnections) - numIdle | ||
numIdleToKeep := int(math.Max(1, math.Ceil(float64(numRecentlyUsed)*minIdleHeadroom))) | ||
numIdleToClose := len(freeConnections) - numRecentlyUsed - numIdleToKeep |
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.
Maybe this is easier to follow? Not a strong opinion:
numIdleToClose := len(freeConnections) - numRecentlyUsed - numIdleToKeep | |
numIdleToClose := numIdle - numIdleToKeep |
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.
👍 Done in c873d2f.
memcache/memcache.go
Outdated
@@ -238,13 +278,91 @@ func (c *Client) netTimeout() time.Duration { | |||
return DefaultTimeout | |||
} | |||
|
|||
func (c *Client) minIdleConnsHeadroom() float64 { | |||
if c.MinIdleConnsHeadroom < 0 || c.MinIdleConnsHeadroom >= 1 { |
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.
Why MinIdleConnsHeadroom
can't be >= 1
? It's valid to want to have twice as much connections as the recently used ones. Doesn't make much sense, but it's valid.
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.
Reason was that to me didn't make much sense, but doesn't hurt to support it. Done in 4413597.
memcache/memcache.go
Outdated
|
||
// Compute the number of connections to close, honoring two properties: | ||
// 1. Keep a number of idle connections equal to the configured headroom. | ||
// 2. Keep at least 1 idle connection. |
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.
Why do we need to keep at least 1 idle connection? You already have the number of recently used ones, you may not want to have any extra ones.
Which implies: should we allow a minIdleHeadroom=0
here? I think we should.
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.
Agree. Done in 4413597.
Left some opinionated comments, they're not blockers, but consider thinking about them. |
…anged the value to the range 0-100+. A negative value disable the min idle connections headroom logic. Signed-off-by: Marco Pracucci <marco@pracucci.com>
a3b7d09
to
4413597
Compare
Signed-off-by: Marco Pracucci <marco@pracucci.com>
Signed-off-by: Marco Pracucci <marco@pracucci.com>
Signed-off-by: Marco Pracucci <marco@pracucci.com>
Signed-off-by: Marco Pracucci <marco@pracucci.com>
…oom percentage is set to a large number Signed-off-by: Marco Pracucci <marco@pracucci.com>
Thanks @colega for your review. I should have addressed all comments, plus added few more test cases and made |
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.
Looks awesome! Thank you!
Currently memcached client allows to configure the max number of idle connections. These idle connections are never closed, even if unused for a long time. There's some tensions on the value you set for idle connections:
In this PR I'm proposing to add a
MinIdleConnsHeadroom
config option. When configured, the client periodically closes idle connections up untilMinIdleConnsHeadroom
percentage of the recently used connections. IfMinIdleConnsHeadroom
is not configured (zero value) there's no difference compared to previous version.In order to periodically close the connections, the client now runs a maintenance goroutine. The client goroutine can be stopped calling the new
Close()
function.Other the new unit tests, I've manually tested it in Mimir (see grafana/mimir#4249) and looks working as designed.