Skip to content

Commit ec2d8c4

Browse files
bborehamgouthamve
authored andcommitted
Report chunks flushed by spread-flushes option under separate label (#1978)
* Report chunks flushed by spread-flushes option under separate label This improves observability of flushing, creating separate labels for chunks that overflowed versus to series that reached their time under spread-flushes behaviour. The flushReason type shrinks to int8 to avoid bloating the chunk desc object. Signed-off-by: Bryan Boreham <[email protected]> * Add changelog note about new flush_reasons label value Signed-off-by: Bryan Boreham <[email protected]>
1 parent 209fe10 commit ec2d8c4

File tree

4 files changed

+22
-9
lines changed

4 files changed

+22
-9
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## master / unreleased
44

5+
* [ENHANCEMENT] metric `cortex_ingester_flush_reasons` gets a new `reason` value: `Spread`, when `-ingester.spread-flushes` option is enabled.
6+
57
* [CHANGE] Flags changed with transition to upstream Prometheus rules manager:
68
* `ruler.client-timeout` is now `ruler.configs.client-timeout` in order to match `ruler.configs.url`
79
* `ruler.group-timeout`has been removed

pkg/ingester/flush.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ func (i *Ingester) sweepUsers(immediate bool) {
137137
oldestUnflushedChunkTimestamp.Set(float64(oldest.Unix()))
138138
}
139139

140-
type flushReason int
140+
type flushReason int8
141141

142142
const (
143143
noFlush = iota
@@ -146,6 +146,7 @@ const (
146146
reasonAged
147147
reasonIdle
148148
reasonStale
149+
reasonSpreadFlush
149150
)
150151

151152
func (f flushReason) String() string {
@@ -162,6 +163,8 @@ func (f flushReason) String() string {
162163
return "Idle"
163164
case reasonStale:
164165
return "Stale"
166+
case reasonSpreadFlush:
167+
return "Spread"
165168
default:
166169
panic("unrecognised flushReason")
167170
}
@@ -196,6 +199,9 @@ func (i *Ingester) shouldFlushSeries(series *memorySeries, fp model.Fingerprint,
196199

197200
// Flush if we have more than one chunk, and haven't already flushed the first chunk
198201
if len(series.chunkDescs) > 1 && !series.chunkDescs[0].flushed {
202+
if series.chunkDescs[0].flushReason != noFlush {
203+
return series.chunkDescs[0].flushReason
204+
}
199205
return reasonMultipleChunksInSeries
200206
} else if len(series.chunkDescs) > 0 {
201207
// Otherwise look in more detail at the first chunk
@@ -287,7 +293,7 @@ func (i *Ingester) flushUserSeries(flushQueueIndex int, userID string, fp model.
287293
// Assume we're going to flush everything, and maybe don't flush the head chunk if it doesn't need it.
288294
chunks := series.chunkDescs
289295
if immediate || (len(chunks) > 0 && i.shouldFlushChunk(series.head(), fp, series.isStale()) != noFlush) {
290-
series.closeHead()
296+
series.closeHead(reasonImmediate)
291297
} else {
292298
chunks = chunks[:len(chunks)-1]
293299
}

pkg/ingester/ingester.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ func (i *Ingester) append(ctx context.Context, userID string, labels labelPairs,
355355
slot := startOfCycle.Add(time.Duration(uint64(fp) % uint64(i.cfg.MaxChunkAge)))
356356
// If adding this sample means the head chunk will span that point in time, close so it will get flushed
357357
if series.head().FirstTime < slot && timestamp >= slot {
358-
series.closeHead()
358+
series.closeHead(reasonSpreadFlush)
359359
}
360360
}
361361

pkg/ingester/series.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,11 @@ func firstAndLastTimes(c encoding.Chunk) (model.Time, model.Time, error) {
123123
return first, last, iter.Err()
124124
}
125125

126-
func (s *memorySeries) closeHead() {
126+
// closeHead marks the head chunk closed. The caller must have locked
127+
// the fingerprint of the memorySeries. This method will panic if this
128+
// series has no chunk descriptors.
129+
func (s *memorySeries) closeHead(reason flushReason) {
130+
s.chunkDescs[0].flushReason = reason
127131
s.headChunkClosed = true
128132
}
129133

@@ -212,11 +216,12 @@ func (s *memorySeries) isStale() bool {
212216
}
213217

214218
type desc struct {
215-
C encoding.Chunk // nil if chunk is evicted.
216-
FirstTime model.Time // Timestamp of first sample. Populated at creation. Immutable.
217-
LastTime model.Time // Timestamp of last sample. Populated at creation & on append.
218-
LastUpdate model.Time // This server's local time on last change
219-
flushed bool // set to true when flush succeeds
219+
C encoding.Chunk // nil if chunk is evicted.
220+
FirstTime model.Time // Timestamp of first sample. Populated at creation. Immutable.
221+
LastTime model.Time // Timestamp of last sample. Populated at creation & on append.
222+
LastUpdate model.Time // This server's local time on last change
223+
flushReason flushReason // If chunk is closed, holds the reason why.
224+
flushed bool // set to true when flush succeeds
220225
}
221226

222227
func newDesc(c encoding.Chunk, firstTime model.Time, lastTime model.Time) *desc {

0 commit comments

Comments
 (0)