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

perf(blooms): Resolve bloom blocks on index gateway and shard by block address #12720

Merged
merged 28 commits into from
Apr 23, 2024

Conversation

chaudum
Copy link
Contributor

@chaudum chaudum commented Apr 22, 2024

This pull request changes how data is sharded across bloom gateways.

Currently, chunks are grouped by series and shared by the fingerprint of the series across the available bloom gateways using jumphash algorithm. This however, leads to over-querying bloom blocks, because bloom blocks have consecutive fingerprint ranges, whereas sharding keys are evenly distributed across keyspace.

This PR changes the sharding in the way that bloom blocks for series are already resolved on the index gateways and that their address is used for sharding data. This has the advantage that the grouped series can be mapped to the correct bloom blocks on the client side. Sending the block ref along with the grouped series to the bloom gateway allows for efficient querying of the data because each bloom gateway therefore owns exactly 1/nth of the blocks.

Checklist

  • Reviewed the CONTRIBUTING.md guide (required)
  • Documentation added
  • Tests updated
  • Title matches the required conventional commits format, see here
  • Changes that require user attention or interaction to upgrade are documented in docs/sources/setup/upgrade/_index.md
  • For Helm chart changes bump the Helm chart version in production/helm/loki/Chart.yaml and update production/helm/loki/CHANGELOG.md and production/helm/loki/README.md. Example PR
  • If the change is deprecating or removing a configuration option, update the deprecated-config.yaml and deleted-config.yaml files respectively in the tools/deprecated-config-checker directory. Example PR

Signed-off-by: Christian Haudum <christian.haudum@gmail.com>
Signed-off-by: Christian Haudum <christian.haudum@gmail.com>
When preset, the bloom gateway should use the given blocks
instead of resolving them from the request parameters.

Signed-off-by: Christian Haudum <christian.haudum@gmail.com>
later we want to resolve bloom blocks for a filter single request, and
because blocks are built per day, we need to split the original interval
into separate days

Signed-off-by: Christian Haudum <christian.haudum@gmail.com>
Signed-off-by: Christian Haudum <christian.haudum@gmail.com>
Signed-off-by: Christian Haudum <christian.haudum@gmail.com>
Signed-off-by: Christian Haudum <christian.haudum@gmail.com>
Signed-off-by: Christian Haudum <christian.haudum@gmail.com>
Signed-off-by: Christian Haudum <christian.haudum@gmail.com>
Signed-off-by: Christian Haudum <christian.haudum@gmail.com>
Signed-off-by: Christian Haudum <christian.haudum@gmail.com>
Signed-off-by: Christian Haudum <christian.haudum@gmail.com>
```console
$ benchstat old.txt new.txt
goos: linux
goarch: amd64
pkg: github.com/grafana/loki/v3/pkg/bloomgateway
cpu: 11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz
                 │   old.txt    │              new.txt               │
                 │    sec/op    │   sec/op     vs base               │
GroupChunkRefs-8   12.42µ ± 18%   11.43µ ± 3%  -8.01% (p=0.000 n=10)

                 │   old.txt    │             new.txt              │
                 │     B/op     │     B/op      vs base            │
GroupChunkRefs-8   7.148Ki ± 0%   7.148Ki ± 0%  ~ (p=1.000 n=10) ¹
¹ all samples are equal

                 │  old.txt   │            new.txt             │
                 │ allocs/op  │ allocs/op   vs base            │
GroupChunkRefs-8   100.0 ± 0%   100.0 ± 0%  ~ (p=1.000 n=10) ¹
¹ all samples are equal
```

Signed-off-by: Christian Haudum <christian.haudum@gmail.com>
Signed-off-by: Christian Haudum <christian.haudum@gmail.com>
Signed-off-by: Christian Haudum <christian.haudum@gmail.com>
Signed-off-by: Christian Haudum <christian.haudum@gmail.com>
Signed-off-by: Christian Haudum <christian.haudum@gmail.com>
Signed-off-by: Christian Haudum <christian.haudum@gmail.com>
Signed-off-by: Christian Haudum <christian.haudum@gmail.com>
Signed-off-by: Christian Haudum <christian.haudum@gmail.com>
Signed-off-by: Christian Haudum <christian.haudum@gmail.com>
Signed-off-by: Christian Haudum <christian.haudum@gmail.com>
Signed-off-by: Christian Haudum <christian.haudum@gmail.com>
@chaudum chaudum marked this pull request as ready for review April 22, 2024 12:17
@chaudum chaudum requested a review from a team as a code owner April 22, 2024 12:17
}

// Shortcut if request does not contain blocks
// TOOD(chaudum): Comment out when blocks are resolved on index gateways
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this TODO be addressed?

Copy link
Contributor Author

@chaudum chaudum Apr 22, 2024

Choose a reason for hiding this comment

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

I would have removed that after the weekly release, but you are right, since we don't run this in ops yet and it's an experimental feature, we don't need to care that much about compatibility.

duration := time.Since(start)
level.Debug(p.logger).Log("msg", "fetched metas", "count", len(metas), "duration", duration, "err", err)
// fallback to existing block resolving
// TODO(chaudum): Remove once client side block resolving is implemented
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this be removed?

Copy link
Contributor

Choose a reason for hiding this comment

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

IIUC we are keeping this for compatibility but:

  • This is an experimental feature so breaking changes across releases are ok.
  • This is running only in dev so not a big deal to break things for a bit till gateways are rolled out.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

See comment above. Agree, we can remove the code path.

Plan plan = 5 [
(gogoproto.customtype) = "github.com/grafana/loki/v3/pkg/querier/plan.QueryPlan",
(gogoproto.nullable) = false
];
repeated string blocks = 6;
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: what about adding this to the plan instead?

Signed-off-by: Christian Haudum <christian.haudum@gmail.com>
Signed-off-by: Christian Haudum <christian.haudum@gmail.com>
Copy link
Member

@owen-d owen-d left a comment

Choose a reason for hiding this comment

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

A few comments but LGTM

}

sort.Slice(grouped, func(i, j int) bool {
Copy link
Member

Choose a reason for hiding this comment

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

Are these not already sorted here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right, I think since series are sorted lexicographically in the index, this function should have the chunks already sorted by their respective fingerprint.

pkg/loki/loki.go Outdated
// Add BloomStore dependency to IndexGateway in case bloom gateway component is enabled.
// This is needed because the blocks for the bloom gateway are resolved on the index gateway.
if t.Cfg.BloomGateway.Enabled {
deps[IndexGateway] = append(deps[IndexGateway], BloomStore)
Copy link
Member

Choose a reason for hiding this comment

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

nit: I think it makes more sense to use this check in initBloomStore instead and just return a nil or noop impl if it's disabled. Reason being, module dependency is hard enough and it's nice to keep it conceptually simple + pass the implementation decisions downward to the implementor

Signed-off-by: Christian Haudum <christian.haudum@gmail.com>
Signed-off-by: Christian Haudum <christian.haudum@gmail.com>
@chaudum chaudum merged commit 5540c92 into main Apr 23, 2024
57 checks passed
@chaudum chaudum deleted the chaudum/resolve-blocks-on-index-gateway branch April 23, 2024 07:31
@grafanabot
Copy link
Collaborator

Hello @chaudum!
Backport pull requests need to be either:

  • Pull requests which address bugs,
  • Urgent fixes which need product approval, in order to get merged,
  • Docs changes.

Please, if the current pull request addresses a bug fix, label it with the type/bug label.
If it already has the product approval, please add the product-approved label. For docs changes, please add the type/docs label.
If the pull request modifies CI behaviour, please add the type/ci label.
If none of the above applies, please consider removing the backport label and target the next major/minor release.
Thanks!

chaudum added a commit that referenced this pull request Apr 23, 2024
…k address (#12720)

This pull request changes how data is sharded across bloom gateways.

Currently, chunks are grouped by series and shared by the fingerprint of the series across the available bloom gateways using jumphash algorithm. This however, leads to over-querying bloom blocks, because bloom blocks have consecutive fingerprint ranges, whereas sharding keys are evenly distributed across keyspace.

This PR changes the sharding in the way that bloom blocks for series are already resolved on the index gateways and that their address is used for sharding data. This has the advantage that the grouped series can be mapped to the correct bloom blocks on the client side. Sending the block ref along with the grouped series to the bloom gateway allows for efficient querying of the data because each bloom gateway therefore owns exactly 1/nth of the blocks.

---

Signed-off-by: Christian Haudum <christian.haudum@gmail.com>
chaudum added a commit that referenced this pull request Apr 23, 2024
…k address (#12743)

Manual backport of #12720 to k199


Signed-off-by: Christian Haudum <christian.haudum@gmail.com>
mattgialelis pushed a commit to mattgialelis/loki that referenced this pull request Apr 23, 2024
…k address (grafana#12720)

This pull request changes how data is sharded across bloom gateways.

Currently, chunks are grouped by series and shared by the fingerprint of the series across the available bloom gateways using jumphash algorithm. This however, leads to over-querying bloom blocks, because bloom blocks have consecutive fingerprint ranges, whereas sharding keys are evenly distributed across keyspace.

This PR changes the sharding in the way that bloom blocks for series are already resolved on the index gateways and that their address is used for sharding data. This has the advantage that the grouped series can be mapped to the correct bloom blocks on the client side. Sending the block ref along with the grouped series to the bloom gateway allows for efficient querying of the data because each bloom gateway therefore owns exactly 1/nth of the blocks.

---

Signed-off-by: Christian Haudum <christian.haudum@gmail.com>
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.

None yet

4 participants