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

Reintroduce query plan reuse during warmup #5255

Draft
wants to merge 87 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 62 commits
Commits
Show all changes
87 commits
Select commit Hold shift + click to select a range
f61d243
add test cases
IvanGoncharov Apr 26, 2024
12658ac
add a separator between each part of the hash
Geal May 27, 2024
b768d00
deactivate the query string hashing for now
Geal May 27, 2024
78ca936
fix some tests
Geal May 27, 2024
2511864
reactivate all tests
Geal May 27, 2024
d783eee
fixes for query variables
Geal May 27, 2024
459681d
fix some field hashing tests
Geal May 27, 2024
842dce9
add separators
Geal May 27, 2024
9bb31df
hash some directives
Geal May 27, 2024
d632e8a
hash the schema
Geal May 28, 2024
9da105e
hash directive definitions
Geal May 28, 2024
6e6d517
cleanup
Geal May 28, 2024
85d93fe
hash interface implementers
Geal May 28, 2024
7968c22
update hashes
Geal May 28, 2024
47dc6fe
Merge branch 'dev' into geal/fix-hashing-algorithm
Geal Jun 3, 2024
4d7ceea
lint
Geal Jun 3, 2024
9c34952
add a test for directives applied to interface definitions
Geal Jun 3, 2024
fcb3f3f
cleanup
Geal Jun 3, 2024
0b17980
add a metric tracking how many query plans could be reused
Geal Jun 3, 2024
bd7e5eb
simplify the caching key
Geal Jun 3, 2024
22359ed
update hashes
Geal Jun 3, 2024
dfd8819
Merge branch 'dev' into geal/fix-hashing-algorithm
Geal Jun 3, 2024
4d47696
fix integration tests
Geal Jun 3, 2024
d1e2f34
Merge branch 'dev' into geal/fix-hashing-algorithm
Geal Jun 7, 2024
adb9d11
lint
Geal Jun 7, 2024
2263dcb
Merge branch 'dev' into geal/fix-hashing-algorithm
Geal Jun 7, 2024
98ec603
Merge branch 'dev' into geal/fix-hashing-algorithm
Geal Jun 13, 2024
bf53aa2
Merge branch 'dev' into geal/fix-hashing-algorithm
Geal Jun 13, 2024
b8361b9
update snapshots
Geal Jun 13, 2024
ccf9fe2
update snapshots
Geal Jun 13, 2024
c218be8
hash the rust query planner options too
Geal Jun 13, 2024
3e53969
remove JSON serialization in redis key generation
Geal Jun 13, 2024
37bd5de
Merge branch 'dev' into geal/fix-hashing-algorithm
Geal Jun 13, 2024
f9d5b10
Merge branch 'dev' into geal/fix-hashing-algorithm
Geal Jun 18, 2024
935ecf9
update separators for default_valur
Geal Jun 18, 2024
b4ce95a
update snapshots
Geal Jun 18, 2024
9dae438
Merge branch 'dev' into geal/fix-hashing-algorithm
Geal Jun 24, 2024
edca1bc
update snapshots
Geal Jun 24, 2024
56ce0db
update SetContext snapshots
Geal Jun 24, 2024
88b8d5d
Merge branch 'dev' into geal/fix-hashing-algorithm
Geal Jun 26, 2024
049834e
fix log message
Geal Jun 27, 2024
3f128e1
Merge branch 'dev' into geal/fix-hashing-algorithm
Geal Jul 1, 2024
52bee1d
docs and changeset
Geal Jul 1, 2024
df38cec
update changeset
Geal Jul 1, 2024
42a7dfe
use both schema hash and query hash
Geal Jul 1, 2024
f80c1e7
more precise way to write the redis cache key
Geal Jul 1, 2024
4b492de
fmt
Geal Jul 1, 2024
183bc4c
Update apollo-router/src/query_planner/caching_query_planner.rs
Geal Jul 1, 2024
b4ed22a
Update apollo-router/src/query_planner/caching_query_planner.rs
Geal Jul 1, 2024
1a46211
fix config hashing
Geal Jul 1, 2024
6c88132
Merge branch 'dev' into geal/fix-hashing-algorithm
Geal Jul 31, 2024
750aaa1
fix
Geal Jul 31, 2024
52e3424
fix QP test
Geal Jul 31, 2024
66ebc0d
introduce the metrics
Geal Jul 31, 2024
d4170f7
Apply suggestions from code review
Geal Jul 31, 2024
df8e6fc
add a prefix for planner configuration hashing
Geal Jul 31, 2024
52e27df
use the new metrics
Geal Jul 31, 2024
66c9a00
algorithm documentation
Geal Jul 31, 2024
391ab81
Update apollo-router/src/spec/query/change.rs
Geal Jul 31, 2024
e1067ed
add more tests
Geal Jul 31, 2024
bf734b9
more tests for input objects
Geal Jul 31, 2024
81604c2
update metadata hashing
Geal Jul 31, 2024
f9c71a5
Merge branch 'dev' into geal/fix-hashing-algorithm
Geal Aug 13, 2024
4f8f5ec
Merge branch 'dev' into geal/fix-hashing-algorithm
Geal Aug 27, 2024
bd11be2
update snapshots
Geal Aug 27, 2024
e3ca286
Merge branch 'dev' into geal/fix-hashing-algorithm
Geal Aug 29, 2024
1b76c0a
isolate loops
Geal Aug 29, 2024
555e507
hash implemented interfaces
Geal Aug 29, 2024
efc3274
Merge branch 'dev' into geal/fix-hashing-algorithm
Geal Aug 30, 2024
6bf14a7
lint
Geal Aug 30, 2024
2a37728
hash implemented interfaces for objects
Geal Aug 30, 2024
603b27b
update keys in tests
Geal Aug 30, 2024
a5c0c7c
update snapshots
Geal Aug 30, 2024
5fdaa4b
Merge branch 'dev' into geal/fix-hashing-algorithm
Geal Sep 6, 2024
0151f0f
fix
Geal Sep 6, 2024
028a088
Merge branch 'dev' into geal/fix-hashing-algorithm
Geal Sep 9, 2024
1fcb704
add a mode to measure query plan reuse
Geal Sep 9, 2024
c57ec66
fix
Geal Sep 9, 2024
cde0142
aranch 'dev' into geal/fix-hashing-algorithm
Geal Sep 16, 2024
bd325e6
Merge branch 'dev' into geal/fix-hashing-algorithm
Geal Oct 18, 2024
fc348d7
unneeded change
Geal Oct 18, 2024
e22917d
snapshots
Geal Oct 21, 2024
3d053cb
snapshots
Geal Oct 21, 2024
86b70b0
Merge branch 'dev' into geal/fix-hashing-algorithm
abernix Oct 23, 2024
72bc405
add separators for the query plan cache key
Geal Oct 29, 2024
f58c7e8
Merge branch 'dev' into geal/fix-hashing-algorithm
Geal Oct 29, 2024
59d1e2c
Merge branch 'dev' into geal/fix-hashing-algorithm
Geal Nov 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .changesets/fix_geal_fix_hashing_algorithm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
### Fix cache key hashing algorithm ([Issue #5160](https://github.com/apollographql/router/issues/5160))

> [!IMPORTANT]
> If you have enabled [Distributed query plan caching](https://www.apollographql.com/docs/router/configuration/distributed-caching/#distributed-query-plan-caching), this release changes the hashing algorithm used for the cache keys. On account of this, you should anticipate additional cache regeneration cost when updating between these versions while the new hashing algorithm comes into service.

The Router contains a schema aware query hashing algorithm, designed to return the same hash across schema updates if they do not affect the query. It was used mainly to avoid planning a lot of queries when warming up the query plan cache. It was deactivated due to a regression. This reintroduces this algorithm, with a number of reliability and performance fixes, along with better observability.

The hashing algorithm can be activated in configuration, if query plan cache warm up is already enabled:
Geal marked this conversation as resolved.
Show resolved Hide resolved

```yaml title="router.yaml"
supergraph:
query_planning:
warmed_up_queries: 100
experimental_reuse_query_plans: true
```
Geal marked this conversation as resolved.
Show resolved Hide resolved


We've also introduced changes to our metrics to help track the impact of these changes. There is a counter metric named `apollo.router.query.planning.warmup.reused` that can be used to track the hashing algorithm benefits:
- if the `experimental_reuse_query_plans` option is false, the `query_plan_reuse_active` metric attribute will be false. Cache warm up will not reuse query plans according to the algorithm, but it will evaluate if some of them could have been reused and report that in the metric
- if the `experimental_reuse_query_plans` option is true, then the `query_plan_reuse_active` metric attribute will be true

Summary:
- strengthen the hashing algorithm to prevent collisions. In particular, the query string is always hashed in, making sure that different queries cannot get the same hash
- remove inefficiencies in cache key generation
- use prefixes for each part of the Redis cache key, so they become self describing

By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/5255
15 changes: 15 additions & 0 deletions apollo-router/src/configuration/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,21 @@ impl Configuration {
type_conditioned_fetching: self.experimental_type_conditioned_fetching,
}
}

pub(crate) fn rust_query_planner_config(
&self,
) -> apollo_federation::query_plan::query_planner::QueryPlannerConfig {
apollo_federation::query_plan::query_planner::QueryPlannerConfig {
reuse_query_fragments: self.supergraph.reuse_query_fragments.unwrap_or(true),
subgraph_graphql_validation: false,
generate_query_fragments: false,
incremental_delivery:
apollo_federation::query_plan::query_planner::QueryPlanIncrementalDeliveryConfig {
enable_defer: self.supergraph.defer_support,
},
debug: Default::default(),
}
}
}

impl Default for Configuration {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ expression: query_plan
"inputRewrites": null,
"outputRewrites": null,
"contextRewrites": null,
"schemaAwareHash": "12dda6193654ae4fe6e38bc09d4f81cc73d0c9e098692096f72d2158eef4776f",
"schemaAwareHash": "9b44446744b4cdb1a063511c35cb78fa79c519ac43671b1b60096b0984a17244",
"authorization": {
"is_authenticated": false,
"scopes": [],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ expression: query_plan
"inputRewrites": null,
"outputRewrites": null,
"contextRewrites": null,
"schemaAwareHash": "00ad582ea45fc1bce436b36b21512f3d2c47b74fdbdc61e4b349289722c9ecf2",
"schemaAwareHash": "d5ed8e0726a1b6f88dcd89ddf57620f3f878eecf169a01a921fa6f4efc2529f5",
"authorization": {
"is_authenticated": false,
"scopes": [],
Expand Down Expand Up @@ -63,7 +63,7 @@ expression: query_plan
"inputRewrites": null,
"outputRewrites": null,
"contextRewrites": null,
"schemaAwareHash": "a8ebdc2151a2e5207882e43c6906c0c64167fd9a8e0c7c4becc47736a5105096",
"schemaAwareHash": "d9d748cdc6d6e7a1e85d2ad07a24e749b15ccfac02aefe28b8acf6e190796fd4",
"authorization": {
"is_authenticated": false,
"scopes": [],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ expression: "serde_json::to_value(response).unwrap()"
"inputRewrites": null,
"outputRewrites": null,
"contextRewrites": null,
"schemaAwareHash": "7245d488e97c3b2ac9f5fa4dd4660940b94ad81af070013305b2c0f76337b2f9",
"schemaAwareHash": "527383ea0a0ef3ac37b096a8f1e5cfc0208a358ec45af6e41e5354459bf22768",
"authorization": {
"is_authenticated": false,
"scopes": [],
Expand Down Expand Up @@ -109,7 +109,7 @@ expression: "serde_json::to_value(response).unwrap()"
"inputRewrites": null,
"outputRewrites": null,
"contextRewrites": null,
"schemaAwareHash": "6e0b4156706ea0cf924500cfdc99dd44b9f0ed07e2d3f888d4aff156e6a33238",
"schemaAwareHash": "a85be34ef80bc1f92f03839733e8488c87f76b7b7fec0dbab3aabb9022392d95",
"authorization": {
"is_authenticated": false,
"scopes": [],
Expand Down Expand Up @@ -156,7 +156,7 @@ expression: "serde_json::to_value(response).unwrap()"
"inputRewrites": null,
"outputRewrites": null,
"contextRewrites": null,
"schemaAwareHash": "ff649f3d70241d5a8cd5f5d03ff4c41ecff72b0e4129a480207b05ac92318042",
"schemaAwareHash": "534733f432a250d11d412d158534cde6409ab67e77a8d56b39d66a2508816d42",
"authorization": {
"is_authenticated": false,
"scopes": [],
Expand Down Expand Up @@ -200,7 +200,7 @@ expression: "serde_json::to_value(response).unwrap()"
"inputRewrites": null,
"outputRewrites": null,
"contextRewrites": null,
"schemaAwareHash": "bf9f3beda78a7a565e47c862157bad4ec871d724d752218da1168455dddca074",
"schemaAwareHash": "242d0b3a066d67c9e80151b6ddf8996964ebae0ef78757bb6ea6d1e1c6a61819",
"authorization": {
"is_authenticated": false,
"scopes": [],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ expression: "serde_json::to_value(response).unwrap()"
"inputRewrites": null,
"outputRewrites": null,
"contextRewrites": null,
"schemaAwareHash": "7245d488e97c3b2ac9f5fa4dd4660940b94ad81af070013305b2c0f76337b2f9",
"schemaAwareHash": "527383ea0a0ef3ac37b096a8f1e5cfc0208a358ec45af6e41e5354459bf22768",
"authorization": {
"is_authenticated": false,
"scopes": [],
Expand Down Expand Up @@ -109,7 +109,7 @@ expression: "serde_json::to_value(response).unwrap()"
"inputRewrites": null,
"outputRewrites": null,
"contextRewrites": null,
"schemaAwareHash": "6e0b4156706ea0cf924500cfdc99dd44b9f0ed07e2d3f888d4aff156e6a33238",
"schemaAwareHash": "a85be34ef80bc1f92f03839733e8488c87f76b7b7fec0dbab3aabb9022392d95",
"authorization": {
"is_authenticated": false,
"scopes": [],
Expand Down Expand Up @@ -156,7 +156,7 @@ expression: "serde_json::to_value(response).unwrap()"
"inputRewrites": null,
"outputRewrites": null,
"contextRewrites": null,
"schemaAwareHash": "ff649f3d70241d5a8cd5f5d03ff4c41ecff72b0e4129a480207b05ac92318042",
"schemaAwareHash": "534733f432a250d11d412d158534cde6409ab67e77a8d56b39d66a2508816d42",
"authorization": {
"is_authenticated": false,
"scopes": [],
Expand Down Expand Up @@ -200,7 +200,7 @@ expression: "serde_json::to_value(response).unwrap()"
"inputRewrites": null,
"outputRewrites": null,
"contextRewrites": null,
"schemaAwareHash": "bf9f3beda78a7a565e47c862157bad4ec871d724d752218da1168455dddca074",
"schemaAwareHash": "242d0b3a066d67c9e80151b6ddf8996964ebae0ef78757bb6ea6d1e1c6a61819",
"authorization": {
"is_authenticated": false,
"scopes": [],
Expand Down
14 changes: 1 addition & 13 deletions apollo-router/src/query_planner/bridge_query_planner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,19 +140,7 @@ impl PlannerMode {
schema: &Schema,
configuration: &Configuration,
) -> Result<Arc<QueryPlanner>, ServiceBuildError> {
let config = apollo_federation::query_plan::query_planner::QueryPlannerConfig {
reuse_query_fragments: configuration
.supergraph
.reuse_query_fragments
.unwrap_or(true),
subgraph_graphql_validation: false,
generate_query_fragments: false,
incremental_delivery:
apollo_federation::query_plan::query_planner::QueryPlanIncrementalDeliveryConfig {
enable_defer: configuration.supergraph.defer_support,
},
debug: Default::default(),
};
let config = configuration.rust_query_planner_config();
Ok(Arc::new(QueryPlanner::new(
schema.federation_supergraph(),
config,
Expand Down
Loading
Loading