apollographql / federation

🌐  Build and scale a single data graph across multiple services with Apollo's federation gateway.
https://apollographql.com/docs/federation/
Other
657 stars 242 forks source link

Query plan cache key support for distributed cache implementations #2638

Open timward60 opened 1 year ago

timward60 commented 1 year ago

I would appreciate any insights/thoughts about this, before we/or someone else contributes an implementation.

Feature Request

Support query plan cache key support for distributed cache implementations.

Background

As a follow up to #2385 (contributed by a colleague), we have this deployed against a distributed cache and seeing really promising results in reduction in latency for low volume operations (we run a large number of instances).

Currently we are applying are own key prefix (temporary) in our distributed cache implementation to ensure that query plans are tied to specific build SHA (unmanaged, and compose our schema statically at build time). However this still suffers from increased latencies during deployments.

Currently the key passed by query planner is combination of (operation name) + (query signature) SHA, however this does not take into account the other inputs that may impact query plan calculation (subgraph schemas).

We are planning to follow up with using the super graph schema SDL SHA as this should account for any changes in subgraphs in addition to the existing keys.

Proposal

The feature request here would be: Have the query planner inject the super graph SDL hash as part of the key and/or expose the super-graph SDL hash.

theJC commented 1 year ago

One request in implementation, please if possible try to decouple whether or not you pass your own cache from the behavior of the server around if its a passed in cache vs the default cache.

For example: In the Apollo Server documentStore, we pass in our own implementation so that we can instrument the cache for tracking its size and cache hit/miss performance, but the way the apollo server code is currently written, if you pass in a document store, you are stuck with behavioral changes... those changes do make sense if you are doing so to have a shared state/cache across servers, but not so much if you are passing an "observable wrapped" implementation in.

  1. it prefixes keys with a unique uuid (no prefix if you use the default) making them longer
  2. it changes the behavior that with a new schema it continues to keep the existing cache (versus creating a new one as it does by default) thus if your cache is sized appropriately, you will always have cache eviction activity only when you pass in your own documentStore.

https://github.com/apollographql/apollo-server/blob/80ee904231ff98e55901ab07890057b8b5cf298e/packages/server/src/ApolloServer.ts#L734-L741