perf: use write fraction when resizing pool#1031
Conversation
The write fraction was only used when filling the pool, and not when creating individual sessions. Instead, the type of session that was created was determined based on the type that was needed at that time. That type would then also be remembered for the lifetime of the session. This is a good default when no write fraction has been set, but it is not logical if the user has configured a write fraction. This change ensures that the write fraction is respected when one is set. When no write fraction has been configured, the default behavior is retained, which means that the type of session is determined based on the type of session that is being created. It is however not 'sticky', which means that if the pool only contains write sessions, and a read session is needed, the pool will return a write session, but its type will be changed to read-only and it will not be prepared for read/write transactions when it is returned to the pool. This improves latency for situations where a burst of write transactions has created a lot of write-prepared sessions in the pool that is followed by a sequence of read-only transactions.
Codecov Report
@@ Coverage Diff @@
## master #1031 +/- ##
========================================
Coverage 98.27% 98.27%
========================================
Files 21 21
Lines 20469 20602 +133
Branches 1094 1109 +15
========================================
+ Hits 20115 20247 +132
- Misses 351 352 +1
Partials 3 3
Continue to review full report at Codecov.
|
|
Hope you don't mind if I review this after #963 is merged in. |
| new Promise((_, reject) => { | ||
| this._createSessions({reads, writes}).catch(reject); | ||
| this._pending -= reads; | ||
| this._createSessions({reads, writes: 0}).catch(reject); |
There was a problem hiding this comment.
I got a little bit worried when I got here because I could no longer find where the write sessions are being created. Did I miss something?
Sorry if I misunderstood the change.
There was a problem hiding this comment.
I can understand the confusion. Instead of determining the number of write session to create here, it is determined when the session is released into the pool. That happens on line 568 in the release function. That way the pool can:
- Check whether there is anyone waiting for a session and give that session directly to that waiter, instead of first create a transaction for the session.
- Check the actual number of write sessions in the pool at that moment, and determine whether another write session is needed or not.
- Check whether a session was used as a write session during the last request and mark it as a session that should once again be prepared with a read/write transaction, even when the session pool configuration has the value
writes: 0.
If shouldBeWrite is true and there is no process waiting for a session, the session will be marked as a write-session and a transaction will be prepared at the end of the release function (line 634).
There was a problem hiding this comment.
Great, thanks for the explanation @olavloite. That makes sense.
Note: This PR depends on #963, which should be merged first.
The write fraction was only used when filling the pool, and not when creating individual sessions. Instead, the type of session that was created was determined based on the type that was needed at that time. That type would then also be remembered for the lifetime of the session. This is a good default when no write fraction has been set, but it is not logical if the user has configured a write
fraction.
This change ensures that the write fraction is respected when one is set. When no write fraction has been configured, the default behavior is retained, which means that the type of session is determined based on the type of session that is being created. It is however not 'sticky', which means that if the pool only contains write sessions, and a read session is needed, the pool will return a write session, but its type will be changed to read-only and it will not be prepared
for read/write transactions when it is returned to the pool. This improves latency for situations where a burst of write transactions has created a lot of write-prepared sessions in the pool that is followed by a sequence of read-only transactions.
This change reduces latency in 1-transaction-per-second scenarios where the user has not specified a value for
minandwritesgreater than zero in the session pool configuration. The default value for both configuration options are zero.The benchmarks for these scenarios are below. The TLDR version is: This change improves read/write transaction latency by approx 15ms, except when
minandwriteshave both been configured to values above 0. In that case, there is no significant difference.