Skip to content
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

Query storage by iterating through chunks by batches. #782

Merged
merged 4 commits into from
Aug 2, 2019

Conversation

cyriltovena
Copy link
Contributor

@cyriltovena cyriltovena commented Jul 18, 2019

This changes how the store retrieves chunks, previously one chunks per stream were retrieved first, and in case of large query (high cardinality) even only one chunks per stream could return 3k chunks or more which can easily OOM Loki (3k*2m=6gib).

Now chunks are retrieved by batches of predefined size, default to 50, we iterate through those 50 chunks by first fetching one chunks per stream to filter out streams with matchers and finally we load the full batch (we don't need the lazy iterator anymore) and create an iterator out of it, when the iterator is exhausted we pull the next batch, until there is no more chunks to fetch.

I'd like to also mention that the slice of chunks ref within the batch iterator is split (copy and not resliced) when retrieving a batch to avoid to keep reference from loaded and used chunks.

I've added tests to make sure direction and overlapping are correctly handled but I've also took the time to add all missing tests within the storage package which brings this package to 90% coverage.

/cc @gouthamve I believe this is the continuation of your work so it should be fairly simple for your to review.

This should put an end to any memory issues related to query, except for the labels query which is also on my todo list.

@cyriltovena
Copy link
Contributor Author

WDYT @gouthamve ?

Copy link
Member

@gouthamve gouthamve left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Just curious if we can optimise by filtering in the beginning rather than in every batch.

through = time.Unix(0, nextChunk.Chunk.From.UnixNano())
}
// we save all overlapping chunks as they are also needed in the next batch to properly order entries.
it.lastOverlapping = []*chunkenc.LazyChunk{}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it.lastOverlapping = it.lastOverlapping[:0]?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep I think this would work.

@cyriltovena cyriltovena merged commit 2b40392 into grafana:master Aug 2, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants