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

streaming store-gateway: avoid copying postings when hashing them #3779

Merged
merged 9 commits into from
Dec 20, 2022

Conversation

dimitarvdimitrov
Copy link
Contributor

@dimitarvdimitrov dimitarvdimitrov commented Dec 20, 2022

This PR solves two problems:

  • a bug I just discovered - when we previously constructed the byte slice of the postings we were incorrectly setting the byte position of the octet from the posting
    • it was
      hashable[i+octet]   = byte(posting >> (octet * 8))
    • it should be
      hashable[i*8+octet] = byte(posting >> (octet * 8))
  • avoids copying the postings into a byte slice altogether. Instead, it creates a new sliceHeader that it points to the data of the postings and adjusts the length and capacity.

It also changes the hashing functions from SHA1 (20B) + Blake2 (32B) to only Blake2 (32B). The memcached cache key is too small to fit both SHA1 and Blake2. In another change that will also remove the matchers hash from the key I will use Blake2 with 42B

Signed-off-by: Dimitar Dimitrov <dimitar.dimitrov@grafana.com>
byteSlice := make([]byte, 0)
slicePtr := (*reflect.SliceHeader)(unsafe.Pointer(&byteSlice))
slicePtr.Data = (*reflect.SliceHeader)(unsafe.Pointer(&postings)).Data
slicePtr.Len = len(postings) * 8
Copy link
Collaborator

Choose a reason for hiding this comment

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

[nit, non blocking] Instead of hardcoding 8, can we read the size of storage.SeriesRef instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah i thought about that but the tradeoff was using the unsafe package more 😄

i did the change in e57efad, see what you think

pkg/storegateway/indexcache/cache.go Show resolved Hide resolved
@dimitarvdimitrov
Copy link
Contributor Author

These are the results of running BenchmarkCanonicalPostingsKey

name                                      old time/op    new time/op    delta
CanonicalPostingsKey/10000_postings-10       202µs ± 0%     107µs ± 2%   -47.12%  (p=0.008 n=5+5)
CanonicalPostingsKey/1000000_postings-10    20.0ms ± 0%    10.5ms ± 0%   -47.48%  (p=0.008 n=5+5)
CanonicalPostingsKey/100000_postings-10     2.00ms ± 0%    1.05ms ± 0%   -47.70%  (p=0.008 n=5+5)
CanonicalPostingsKey/100_postings-10        2.46µs ± 3%    1.27µs ± 3%   -48.13%  (p=0.008 n=5+5)
CanonicalPostingsKey/1000_postings-10       20.8µs ± 0%    10.6µs ± 0%   -48.87%  (p=0.016 n=5+4)
CanonicalPostingsKey/10_postings-10          497ns ± 1%     251ns ± 2%   -49.45%  (p=0.008 n=5+5)

name                                      old alloc/op   new alloc/op   delta
CanonicalPostingsKey/10_postings-10           720B ± 0%       96B ± 0%   -86.67%  (p=0.008 n=5+5)
CanonicalPostingsKey/100_postings-10        1.54kB ± 0%    0.10kB ± 0%   -93.75%  (p=0.008 n=5+5)
CanonicalPostingsKey/1000_postings-10       8.83kB ± 0%    0.10kB ± 0%   -98.91%  (p=0.008 n=5+5)
CanonicalPostingsKey/10000_postings-10      82.6kB ± 0%     0.1kB ± 0%   -99.88%  (p=0.008 n=5+5)
CanonicalPostingsKey/100000_postings-10      803kB ± 0%       0kB ± 0%   -99.99%  (p=0.008 n=5+5)
CanonicalPostingsKey/1000000_postings-10    8.00MB ± 0%    0.00MB ± 0%  -100.00%  (p=0.008 n=5+5)

name                                      old allocs/op  new allocs/op  delta
CanonicalPostingsKey/10_postings-10           6.00 ± 0%      2.00 ± 0%   -66.67%  (p=0.008 n=5+5)
CanonicalPostingsKey/100_postings-10          6.00 ± 0%      2.00 ± 0%   -66.67%  (p=0.008 n=5+5)
CanonicalPostingsKey/1000_postings-10         6.00 ± 0%      2.00 ± 0%   -66.67%  (p=0.008 n=5+5)
CanonicalPostingsKey/10000_postings-10        6.00 ± 0%      2.00 ± 0%   -66.67%  (p=0.008 n=5+5)
CanonicalPostingsKey/100000_postings-10       6.00 ± 0%      2.00 ± 0%   -66.67%  (p=0.008 n=5+5)
CanonicalPostingsKey/1000000_postings-10      6.00 ± 0%      2.00 ± 0%   -66.67%  (p=0.008 n=5+5)

@pracucci
Copy link
Collaborator

Remember to add the PR number to the existing CHANGELOG entry.

@pracucci
Copy link
Collaborator

I'm wondering if we could also have a simple unit test on CanonicalPostingsKey(). Like, same input, same hash. Different input, different hash.

Signed-off-by: Dimitar Dimitrov <dimitar.dimitrov@grafana.com>
Signed-off-by: Dimitar Dimitrov <dimitar.dimitrov@grafana.com>
Signed-off-by: Dimitar Dimitrov <dimitar.dimitrov@grafana.com>
Signed-off-by: Dimitar Dimitrov <dimitar.dimitrov@grafana.com>
Signed-off-by: Dimitar Dimitrov <dimitar.dimitrov@grafana.com>

return PostingsKey(base64.RawURLEncoding.EncodeToString(checksum))
const bytesPerPosting = int(unsafe.Sizeof(storage.SeriesRef(0)) / unsafe.Sizeof(byte(0)))
Copy link
Collaborator

Choose a reason for hiding this comment

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

I hope the size of 1 byte won't change :D

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah fair. we have the go 1.x guarantee 😄

Copy link
Collaborator

@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!

Signed-off-by: Dimitar Dimitrov <dimitar.dimitrov@grafana.com>
Copy link
Contributor

@56quarters 56quarters 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 a few small non-blocking things.

pkg/storegateway/indexcache/cache.go Outdated Show resolved Hide resolved
pkg/storegateway/indexcache/cache_test.go Show resolved Hide resolved
pkg/storegateway/indexcache/cache.go Show resolved Hide resolved
dimitarvdimitrov and others added 2 commits December 20, 2022 18:21
Co-authored-by: Nick Pillitteri <56quarters@users.noreply.github.com>
Signed-off-by: Dimitar Dimitrov <dimitar.dimitrov@grafana.com>
@dimitarvdimitrov dimitarvdimitrov merged commit 4f73f28 into main Dec 20, 2022
@dimitarvdimitrov dimitarvdimitrov deleted the dimitar/fix-postings-caching branch December 20, 2022 17:45
@grafanabot
Copy link
Contributor

The backport to r217 failed:

The process '/usr/bin/git' failed with exit code 1

To backport manually, run these commands in your terminal:

# Fetch latest updates from GitHub
git fetch
# Create a new branch
git switch --create backport-3779-to-r217 origin/r217
# Cherry-pick the merged commit of this pull request and resolve the conflicts
git cherry-pick -x 4f73f285aaadb5046a9fb8be8217b2d0f934e598
# Push it to GitHub
git push --set-upstream origin backport-3779-to-r217
git switch main
# Remove the local backport branch
git branch -D backport-3779-to-r217

Then, create a pull request where the base branch is r217 and the compare/head branch is backport-3779-to-r217.

dimitarvdimitrov added a commit that referenced this pull request Dec 20, 2022
)

This PR solves two problems:

a bug I just discovered - when we previously constructed the byte slice of the postings we were incorrectly setting the byte position of the octet from the posting
it was
hashable[i+octet]   = byte(posting >> (octet * 8))
it should be
hashable[i*8+octet] = byte(posting >> (octet * 8))
avoids copying the postings into a byte slice altogether. Instead, it creates a new sliceHeader that it points to the data of the postings and adjusts the length and capacity.
It also changes the hashing functions from SHA1 (20B) + Blake2 (32B) to only Blake2 (32B). The memcached cache key is too small to fit both SHA1 and Blake2. In another change that will also remove the matchers hash from the key I will use Blake2 with 42B

(cherry picked from commit 4f73f28)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants