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

FIFO cache to support eviction based on memory usage #2319

Merged
merged 20 commits into from
Apr 3, 2020

Conversation

dmitsh
Copy link
Contributor

@dmitsh dmitsh commented Mar 24, 2020

Signed-off-by: Dmitry Shmulevich dmitry.shmulevich@sysdig.com

What this PR does:
Change FIFO cache to evict entries based on memory usage.

Which issue(s) this PR fixes:
Fixes #2316

Checklist

  • [ x] Tests updated
  • [ x] Documentation added
  • [ x] CHANGELOG.md updated - the order of entries should be [CHANGE], [FEATURE], [ENHANCEMENT], [BUGFIX]

@dmitsh dmitsh requested review from khaines and pracucci March 24, 2020 20:42
Copy link
Contributor

@pracucci pracucci left a comment

Choose a reason for hiding this comment

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

Thanks @dmitsh. Honestly the change set is larger than what I would have expected. I'm not sure I do understand why we need to change how the cache internally store data, instead of just keeping the current cache size (in bytes) and trigger the eviction based on that. I would suggest to see if there's an easier way to implement the bytes-size-based eviction without having to change the data structures.

CHANGELOG.md Outdated Show resolved Hide resolved
CHANGELOG.md Show resolved Hide resolved
pkg/chunk/cache/fifo_cache.go Outdated Show resolved Hide resolved
pkg/chunk/cache/fifo_cache.go Outdated Show resolved Hide resolved
pkg/chunk/cache/fifo_cache.go Outdated Show resolved Hide resolved
pkg/chunk/cache/fifo_cache.go Outdated Show resolved Hide resolved
@dmitsh
Copy link
Contributor Author

dmitsh commented Mar 25, 2020

Thanks @dmitsh. Honestly the change set is larger than what I would have expected. I'm not sure I do understand why we need to change how the cache internally store data, instead of just keeping the current cache size (in bytes) and trigger the eviction based on that. I would suggest to see if there's an easier way to implement the bytes-size-based eviction without having to change the data structures.

@pracucci The reason I cannot keep the internal cache storage implementation is because it is tailored for count-based eviction: we allocate the exact number of entries in the array, and play with indices. With the memory usage based eviction we cannot pre-allocate such an array, because we don't know up-front how many entries might fit in the cache (given the fact that the individual cache items might differ in size).

@dmitsh dmitsh force-pushed the ds-fifocache-limit branch from 65938ed to 8515412 Compare March 25, 2020 15:56
@dmitsh dmitsh requested a review from pracucci March 25, 2020 16:05
@khaines
Copy link
Contributor

khaines commented Mar 26, 2020

Thank you @dmitsh for making this work both with the item count and memory limits. The only items I have outstanding for myself is that one test question and the deprecated command flag.

@dmitsh
Copy link
Contributor Author

dmitsh commented Mar 26, 2020

@khaines @pracucci What do you think about not deprecating fifocache.size?
We can support both for the same price, and folks will have a choice what to use.
The count-based eviction is more intuitive, and the memory-based eviction can be used in k8s deployments, where memory usage is monitored.
I probably should rename it into max-size-items (and deprecate size).
What do you guys think?

@dmitsh
Copy link
Contributor Author

dmitsh commented Mar 26, 2020

@khaines @pracucci I went ahead and renamed fifocache.size to fifocache.max-size-items.
It seems to be the right thing to do - to leave both eviction options available.
I also deprecated fifocache.size, so this is now a breaking change again.
Hopefully it could make it to the 1.0 release (cc @gouthamve)

@dmitsh dmitsh requested a review from khaines March 26, 2020 12:08
@dmitsh dmitsh changed the title FIFO cache to evict entries based on used memory size FIFO cache to support eviction based on memory usage Mar 26, 2020
Copy link
Contributor

@pracucci pracucci left a comment

Choose a reason for hiding this comment

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

Good job @dmitsh. I finally had the time to properly look at it. I left few comments, please take a look.

pkg/chunk/cache/fifo_cache.go Outdated Show resolved Hide resolved
pkg/chunk/cache/fifo_cache.go Outdated Show resolved Hide resolved
pkg/chunk/cache/fifo_cache.go Show resolved Hide resolved
pkg/chunk/cache/fifo_cache_test.go Outdated Show resolved Hide resolved
pkg/chunk/cache/fifo_cache_test.go Outdated Show resolved Hide resolved
@gouthamve gouthamve added this to the v1 milestone Mar 30, 2020
@dmitsh dmitsh force-pushed the ds-fifocache-limit branch from 95d5e6c to 282c8a5 Compare March 30, 2020 20:12
@dmitsh dmitsh requested review from pracucci and gouthamve March 30, 2020 20:52
CHANGELOG.md Outdated Show resolved Hide resolved
pkg/chunk/cache/fifo_cache.go Show resolved Hide resolved
pkg/chunk/cache/fifo_cache.go Outdated Show resolved Hide resolved
pkg/chunk/cache/fifo_cache.go Outdated Show resolved Hide resolved
pkg/chunk/cache/fifo_cache.go Outdated Show resolved Hide resolved
pkg/chunk/cache/fifo_cache.go Outdated Show resolved Hide resolved
pkg/chunk/cache/fifo_cache.go Outdated Show resolved Hide resolved
pkg/chunk/cache/fifo_cache.go Outdated Show resolved Hide resolved
pkg/chunk/cache/fifo_cache_test.go Outdated Show resolved Hide resolved
pkg/chunk/cache/fifo_cache_test.go Outdated Show resolved Hide resolved
Copy link
Contributor

@pstibrany pstibrany left a comment

Choose a reason for hiding this comment

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

I suggest:

  • use https://golang.org/pkg/container/list/?
  • simplify Put to use byte slices. This cache is only used with byte slices anyway. (Then Put can be removed and we can only keep Store)
  • using byte slices will simplify size computation code

pkg/chunk/cache/fifo_cache.go Outdated Show resolved Hide resolved
pkg/chunk/cache/fifo_cache.go Outdated Show resolved Hide resolved
pkg/chunk/cache/fifo_cache.go Outdated Show resolved Hide resolved
pkg/chunk/cache/fifo_cache.go Outdated Show resolved Hide resolved
pkg/chunk/cache/fifo_cache.go Outdated Show resolved Hide resolved
pkg/chunk/cache/fifo_cache.go Outdated Show resolved Hide resolved
Copy link
Contributor

@pracucci pracucci left a comment

Choose a reason for hiding this comment

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

Thanks @dmitsh for your patience on this! I left few minor comments and then LGTM. Peter also left an interesting feedback about using container/list which may make much sense to simplify it.

pkg/chunk/cache/fifo_cache.go Outdated Show resolved Hide resolved
pkg/chunk/cache/fifo_cache.go Outdated Show resolved Hide resolved
pkg/chunk/cache/fifo_cache.go Outdated Show resolved Hide resolved
Dmitry Shmulevich added 2 commits April 1, 2020 09:05
Signed-off-by: Dmitry Shmulevich <dmitry.shmulevich@sysdig.com>
…' are set to zero

Signed-off-by: Dmitry Shmulevich <dmitry.shmulevich@sysdig.com>
@dmitsh dmitsh requested review from pstibrany and pracucci April 1, 2020 16:26
Signed-off-by: Dmitry Shmulevich <dmitry.shmulevich@sysdig.com>
@pstibrany
Copy link
Contributor

Thank you for your work on this PR. There is one place where NewFifoCache is called, which now needs to check if returned value is ‘nil’:

cache := NewFifoCache(cfg.Prefix+"fifocache", cfg.Fifocache)

Signed-off-by: Dmitry Shmulevich <dmitry.shmulevich@sysdig.com>
@dmitsh
Copy link
Contributor Author

dmitsh commented Apr 1, 2020

@pstibrany Thank you for catching this. I've updated the PR.

Copy link
Contributor

@pracucci pracucci left a comment

Choose a reason for hiding this comment

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

Thanks for your hard work! I spotted a couple of issues. A part from this, LGTM.

pkg/chunk/cache/fifo_cache.go Outdated Show resolved Hide resolved
pkg/chunk/cache/fifo_cache.go Show resolved Hide resolved
…ave non-zero values

Signed-off-by: Dmitry Shmulevich <dmitry.shmulevich@sysdig.com>
Copy link
Contributor

@pracucci pracucci left a comment

Choose a reason for hiding this comment

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

I left a minor nit, but the current version LGTM.

pkg/chunk/cache/fifo_cache.go Outdated Show resolved Hide resolved
Signed-off-by: Dmitry Shmulevich <dmitry.shmulevich@sysdig.com>
@dmitsh dmitsh requested review from pstibrany and pracucci April 2, 2020 16:43
Signed-off-by: Dmitry Shmulevich <dmitry.shmulevich@sysdig.com>
@dmitsh dmitsh requested a review from pstibrany April 2, 2020 19:47
Comment on lines 284 to 288
func sizeOf(item *cacheEntry) int {
return int(unsafe.Sizeof(*item)) + // size of cacheEntry
cap(item.value) + // size of value
(2 * len(item.key)) + // counting key twice: in the cacheEntry and in the map
int(unsafe.Sizeof(&list.Element{})) // size of the pointer to an element in the map
Copy link
Contributor

Choose a reason for hiding this comment

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

sizeOf is little more tricky that I'd like.

For example, I don't really think string length should be counted twice, because it's only string descriptor that's copied, but not the actual string data.

Also cap(item.value) is not the full story, as subslice of large slice will report smaller cap, but still keep entire large slice referenced.

int(unsafe.Sizeof(&list.Element{})) – why counting just a pointer and not full Element struct?

Personally I would simplify it to len(item.key) + cap(item.value), since it's just a best-effort guess, ignoring maintainance structs.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, I updated sizeOf.

Copy link
Contributor

@pstibrany pstibrany left a comment

Choose a reason for hiding this comment

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

Thank you again for your work. I think this is a nice improvement, and good in its current form.

Signed-off-by: Dmitry Shmulevich <dmitry.shmulevich@sysdig.com>
@dmitsh dmitsh requested a review from pstibrany April 2, 2020 20:00
Copy link
Contributor

@pracucci pracucci left a comment

Choose a reason for hiding this comment

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

LGTM, thanks for your hard work! 🎉

@pstibrany pstibrany merged commit e3c582e into cortexproject:master Apr 3, 2020
@dmitsh dmitsh deleted the ds-fifocache-limit branch April 3, 2020 18:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

FIFO cache is limited by the number of entries, but not by their total size
5 participants