8000 add caching for service catalog indexes by thrau · Pull Request #6672 · localstack/localstack · GitHub
[go: up one dir, main page]

Skip to content

add caching for service catalog indexes #6672

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

Merged
merged 2 commits into from
Aug 16, 2022
Merged

add caching for service catalog indexes #6672

merged 2 commits into from
Aug 16, 2022

Conversation

thrau
Copy link
Member
@thrau thrau commented Aug 15, 2022

This PR adds caching of the indexes created in the ServiceCatalog.

Problem

The ServiceCatalog is what powers the ServiceNameParser by providing indexes that allow fast lookup of service indicators to services (e.g., finding the service by its signing name or endpoint prefix). Creating the indexes involves loading all 300-something services, and iterating over all 11k-something operations. This takes around 1500 ms on my machine. This happens the first time an HTTP call is made that triggers the ServiceNameParser, making the first call take at least 1500ms.

Solution

@alexrashed raised some concerns in the past about shipping an index pre-built with the distribution, which was a valid point since that would involve an error-prone build step. So instead I opportunistically create the cache and store it in the localstack volume directory cache. I restructured the service catalog a bit to separate concerns (providing access to the index, vs actually holding the data). I added both the localstack and botocore version identifier to the file name so we always re-load the cache on new versions.

Result

Loading the cache takes 8ms vs. creating it lazily which takes about 1500ms. This has a dramatic effect on cold starts, specifically the first invocation of a service now only loads the service model, which is much faster (previously we would also load all service models to build the index).

Here's me executing awslocal opensearch list-domains. "process" is the end-to-end server latency (timer around Gateway.process, and by_signing_name is what's being executed to look up the service):

Without caching:

# first invocation
Execution of "by_signing_name" took 1458.67ms
Execution of "process" took 1562.29ms
# second invocation
Execution of "by_signing_name" took 0.00ms
Execution of "process" took 23.25ms

With caching:

# first invocation
Execution of "by_signing_name" took 0.01ms
Execution of "process" took 127.29ms
# second invocation
Execution of "by_signing_name" took 0.00ms
Execution of "process" took 22.81ms

I also tried cold-starting several different services in a row. There's only a measurable effect for the first one.
But a pretty dramatic one: 10x speedup for the first cold start.

Drawbacks/Limitations

The index obviously has to be computed at some point. Previously we would do that on the first invocation of any HTTP request for every localstack run. Now we do it once when localstack starts up for the very first time. Any subsequent localstack runs will have no startup delay. This means that this PR has no effect on ephemeral instances of localstack (e.g., in CI environments). For that we would have to ship the index with the distribution.

@thrau thrau requested a review from alexrashed as a code owner August 15, 2022 15:50
@thrau thrau temporarily deployed to localstack-ext-tests August 15, 2022 15:50 Inactive
@coveralls
Copy link

Coverage Status

Coverage decreased (-0.01%) to 91.575% when pulling 7da0d72 on cache-service-catalog into a712228 on master.

@github-actions
Copy link

LocalStack integration with Pro

       3 files  ±0         3 suites  ±0   1h 9m 5s ⏱️ - 6m 31s
1 188 tests ±0  1 146 ✔️  - 1  42 💤 +1  0 ±0 
1 555 runs  ±0  1 482 ✔️  - 1  73 💤 +1  0 ±0 

Results for commit 7da0d72. ± Comparison against base commit a712228.

Copy link
Member
@alexrashed alexrashed left a comment

Choose a reason for hiding this comment

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

Wow! This is a great optimization! 🚀
Maybe we could also further optimize the cold-start by loading the index asynchronously before the first request even comes in (maybe with a new hook). I assume LocalStack will run for a short amount of time before it serves the first request (i.e. the timespan between localstack wait and the first request).

@thrau thrau merged commit 10b7ee7 into master Aug 16, 2022
@thrau thrau deleted the cache-service-catalog branch August 16, 2022 10:08
@localstack localstack locked and limited conversation to collaborators Aug 16, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants
0