Scheduled OOO Compaction without dependency on in-order head Compaction#11847
Scheduled OOO Compaction without dependency on in-order head Compaction#11847MarkintoshZ wants to merge 6 commits intoprometheus:mainfrom
Conversation
7726448 to
cf12151
Compare
bboreham
left a comment
There was a problem hiding this comment.
Recommend you do include a test.
codesome
left a comment
There was a problem hiding this comment.
We need to make changes to not do OOO compaction every minute (more in below comments).
Additionally, right now we can predict when in-order and out-of-order compactions happen (i.e. in between the block durations, so every odd hours for a 2h block duration). It would be nice to preserve this predictability. We can trigger the OOO compaction in the middle of two aligned OOOCompactInterval. i.e. if OOOCompactInterval was 2h, then OOO compactions would be attempted at odd hours (while even hours are the "aligned" OOOCompactInterval), which should be around the time in-order compaction happens. We can achieve this by calculating the time remaining until next trigger after every OOO compaction trigger and use time.After.
|
|
||
| // interval * 3 / 2 so that OOO compaction will happen around the same time as | ||
| // in-order compaction with default options | ||
| OOOScheduledCompact := time.NewTimer(db.opts.OutOfOrderCompactInterval * 3 / 2) |
There was a problem hiding this comment.
We need to actually align the time w.r.t. the wall clock. So in this case, the math would be like this:
OutOfOrderCompactInterval := 2 * time.Hour // The config.
nowUnix := time.Now().Unix()
oooCompactionIntvSec := int64(OutOfOrderCompactInterval / time.Second)
// Aligned 'now'. In this example, an even hour.
nextCompaction := (nowUnix / oooCompactionIntvSec) * oooCompactionIntvSec
// Move the aligned 'now' to midway of the interval. In this example, the next odd hour.
nextCompaction += oooCompactionIntvSec / 2
if nextCompaction < nowUnix {
nextCompaction += oooCompactionIntvSec
}
timeUntilNextCompaction := time.Duration(nextCompaction-nowUnix) * time.Second
// oooScheduledCompact := time.NewTimer(timeUntilNextCompaction) // Use this now. Note the OOO->ooo.
fmt.Println("Now", time.Now().UTC())
fmt.Println("Waiting time", timeUntilNextCompaction)
fmt.Println("Compaction will happen at", time.Now().Add(timeUntilNextCompaction).UTC())The print statements and comments are for explaining. In the final code, you can say something like We align the compactions to happen with in-order compaction, which happens midway between aligned intervals of time.
There was a problem hiding this comment.
Those make a lot of sense. When I implemented the change last time, I was actually quite confused about why we needed to align the compaction time if the alignment would change during the execution of the program (e.g. backoff from failing compaction). Now I understand what you mean by aligning with the compaction. Thank you for being extra patient with me!
|
Since we do regular compaction and OOO compaction separately now, should we have two sets of compaction metric counters, one for regular and one for OOO? |
|
We definitely need a counter with some label "type" that is "head" or "ooo" perhaps (: @MarkintoshZ Good work on this, happy to help going forward with @jesusvazquez sorry for lag! |
Yes I think this a good call and also agree with Bartek's idea of using label values like |
dcfb6e9 to
28b5183
Compare
28b5183 to
10a4d46
Compare
Signed-off-by: Mark Zhang <[email protected]>
Signed-off-by: Mark <[email protected]>
Signed-off-by: Mark <[email protected]>
Signed-off-by: Mark Zhang <[email protected]>
Signed-off-by: Mark Zhang <[email protected]>
10a4d46 to
2e9b1f7
Compare
Signed-off-by: Mark Zhang <[email protected]>
85bd0f3 to
ed7288e
Compare
|
I updated the db metrics to include both head and ooo completion counters. It's ready for review now @jesusvazquez :) |
|
cc @jesusvazquez would you please take a look at this pull request again? Thanks! |
ArthurSens
left a comment
There was a problem hiding this comment.
I've made some suggestions to how you're handling the new metrics.
Working with different labels, instead of different metrics, makes aggregation easier
| headCompactionsFailed prometheus.Counter | ||
| headCompactionsTriggered prometheus.Counter | ||
| headCompactionsSkipped prometheus.Counter | ||
| oooCompactionsFailed prometheus.Counter | ||
| oooCompactionsTriggered prometheus.Counter | ||
| oooCompactionsSkipped prometheus.Counter |
There was a problem hiding this comment.
I wouldn't split the compaction metrics. Ideally, we keep the same metric but use different label values for each type of head.
Since we want new labels now, we would use prometheus.CounterVec instead of prometheus.Counter
Something like this:
- compactionsFailed prometheus.Counter
- compactionsTriggered prometheus.Counter
- compactionsSkipped prometheus.Counter
+ compactionsFailed prometheus.CounterVec
+ compactionsTriggered prometheus.CounterVec
+ compactionsSkipped prometheus.CounterVec| m.compactionsTriggered = prometheus.NewCounter(prometheus.CounterOpts{ | ||
| Name: "prometheus_tsdb_compactions_triggered_total", | ||
| Help: "Total number of triggered compactions for the partition.", |
There was a problem hiding this comment.
Here we need to keep the metric you just deleted, but we'll use NewCounterVec instead. For example:
m.compactionsTriggered = *prometheus.NewCounterVec(prometheus.CounterOpts{
Name: "prometheus_tsdb_head_compactions_triggered_total",
Help: "Total number of triggered compactions for the partition.",
}, []string{"type"})| case <-oooScheduledCompact.C: | ||
| oooScheduledCompact.Reset(db.opts.OutOfOrderCompactInterval) | ||
|
|
||
| db.metrics.oooCompactionsTriggered.Inc() |
There was a problem hiding this comment.
When increasing the metric, you'll want:
db.metrics.compactionsTriggered.WithLabelValues("ooohead").Inc()or, when increasing the regular head metrics:
db.metrics.compactionsTriggered.WithLabelValues("head").Inc()
ArthurSens
left a comment
There was a problem hiding this comment.
Sorry for taking so long to review though, could we also ask you to resolve the conflicts? 😅
| // We align the compactions to happen with in-order compaction, which happens midway | ||
| // between aligned intervals of time. |
There was a problem hiding this comment.
| // We align the compactions to happen with in-order compaction, which happens midway | |
| // between aligned intervals of time. | |
| // We align the out-of-order compactions to happen with in-order compaction, which happens midway | |
| // between aligned intervals of time. |
jesusvazquez
left a comment
There was a problem hiding this comment.
@MarkintoshZ this is close to completion, would you like to give it one last push?
|
@MarkintoshZ gentle reminder about this PR! We'll be cutting Prometheus 3.0 major release in a month and we'd love to have this in if you are still up for it! |
|
Hello from the bug-scrub! @MarkintoshZ do you think you will come back to this? |
|
Yes, I will try to fix this PR and get it up to date by this weekend |
|
Hello again from the bug-scrub! @MarkintoshZ we can hold this open since you indicated you would come back. @poi1649 indicated they could pick it up. |
|
Hello again from the bug-scrub! @poi1649, did you get anywhere? You commented at #11834 (comment) |
PR for #11834
This is my first time contributing so I am unsure if I did everything right. Pointers are much appreciated!
Is it necessary to add a test for the new behavior? If so, what is the best way to test the 2-hour scheduled OOO compaction behavior?