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

add: caching for Discovery Client #682

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

VanillaSpoon
Copy link
Member

@VanillaSpoon VanillaSpoon commented Nov 7, 2023

Issue link

closes #611

What changes have been made

Adding a Discovery Client cache, which will reduce the calls to the Discovery Client, and prevent throttling. The cache is then refreshed by a ticker every 5 hours.

Checks

  • I've made sure the tests are passing.
  • Testing Strategy
    • Unit tests
    • Manual tests
    • Testing is not required for this change

Copy link

openshift-ci bot commented Nov 7, 2023

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign anishasthana for approval. For more information see the Kubernetes Code Review Process.

The full list of commands accepted by this bot can be found here.

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

Copy link
Contributor

@Fiona-Waters Fiona-Waters left a comment

Choose a reason for hiding this comment

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

Seems like a great solution. Just one small comment and one question -- what was the rationale around setting the timeframe to 5 hours?

if err = discovery.InitializeGlobalDiscoveryClient(restConfig); err != nil {
klog.Errorf("Error initializing global discovery client: %s", err)
} else {
klog.Infof("Initializing global discovery client")
Copy link
Contributor

Choose a reason for hiding this comment

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

I think adding the log level here makes sense as this is informational, so can be filtered out at other log levels.

Suggested change
klog.Infof("Initializing global discovery client")
klog.V(4).Infof("Initializing global discovery client")

Copy link
Member Author

Choose a reason for hiding this comment

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

Hey Fiona,
Thanks for the review. I'll update the log :)

The refresh timeframe set to 5 hours is an arbitrary number, I am aiming for a timeframe which both promotes the efficiency of the cache, whist not holding cache for too long, therefor I chose to half that of the controller-runtime resync period of 10 hours.

Although I am open for discussion if you have any suggestions towards the timeframe :)

Copy link
Contributor

Choose a reason for hiding this comment

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

Just thinking about it, and how it would work. From what I understand the client only initializes once, and then refreshes after 5 hours. If resources are created soon after a refresh, will they then only be available for manipulation after the next refresh?

Copy link
Contributor

Choose a reason for hiding this comment

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

If you query for an object type which doesn't exist in the cache it would cause a cache miss and invalidation triggering queries to the k8 discovery client to repopulate the cache.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks Kevin. So if a new object of an object type that does exist is created, this will be discoverable?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, but the discovery client cache doesn't cache individual k8 objects. As I understand it, the Discovery Client is the piece of k8 which resolves names such as pod or po into a fully resolved kubernetes API endpoint. Without a cache, every time one tries to get a pod from kubernetes it will iterate through the discovery API until it finds an entry with that name. This means that in the worst case that every resource will be checked using a GET request which can cause client throttling. Without a cache this would happen every time.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for explaining!

Copy link
Contributor

@KPostOffice KPostOffice left a comment

Choose a reason for hiding this comment

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

@VanillaSpoon
Copy link
Member Author

Hey @KPostOffice,
I believe mem cache would offer less latency between the discovery cache retrievals, as it appears to be the Discovery Api is used quite frequently. However, there may be other drawbacks to using the mem cache, so I'm open to suggestions/discussions on the topic :)

@KPostOffice
Copy link
Contributor

@VanillaSpoon I'm unclear on exactly how the disk cache works if I'm being honest, because as part of the struct it wraps the memcache which makes me think that most requests will still go through the memcache.


func RefreshDiscoveryCache() {
klog.Infof("Invalidating discovery cache")
GlobalCachedDiscoveryClient.Invalidate()
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps we should have some error handling or logging in case any errors arise when attempting to invalidate the discovery cache? WDYT

Copy link
Contributor

Choose a reason for hiding this comment

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

Invalidate doesn't return anything so I don't think this is possible

Copy link
Contributor

Choose a reason for hiding this comment

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

Gotcha, you're right! Thanks Kevin.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Optimise usage of the Discovery API
4 participants