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

Cache serializations across watchers #81914

Merged

Conversation

wojtek-t
Copy link
Member

@wojtek-t wojtek-t commented Aug 25, 2019

Reuse serialization result across watchers - before this change, we were serializing objects independently for every single watcher. With this PR, when dispatching an event in watchcache:

  • wrap the object into one that is caching its encodings
  • reuse them if multiple watchers expect the same serialization format

This is significant performance improvement:

Ref kubernetes/enhancements#1152

@k8s-ci-robot
Copy link
Contributor

@wojtek-t: Adding the "do-not-merge/release-note-label-needed" label because no release-note block was detected, please follow our release note process to remove it.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@k8s-ci-robot k8s-ci-robot added size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. needs-kind Indicates a PR lacks a `kind/foo` label and requires one. needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. needs-priority Indicates a PR lacks a `priority/foo` label and requires one. labels Aug 25, 2019
@k8s-ci-robot k8s-ci-robot added area/apiserver kind/api-change Categorizes issue or PR as related to adding, removing, or otherwise changing an API sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. sig/cli Categorizes an issue or PR as relevant to SIG CLI. and removed needs-kind Indicates a PR lacks a `kind/foo` label and requires one. needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. labels Aug 25, 2019
@fejta-bot
Copy link

This PR may require API review.

If so, when the changes are ready, complete the pre-review checklist and request an API review.

Status of requested reviews is tracked in the API Review project.

@wojtek-t wojtek-t force-pushed the cache_serializations_across_watchers branch from 899779b to 3f20ed6 Compare August 26, 2019 02:33
@wojtek-t
Copy link
Member Author

/retest

Copy link
Contributor

@jpbetz jpbetz left a comment

Choose a reason for hiding this comment

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

First pass, I'l try to get another pass out shortly

@wojtek-t wojtek-t force-pushed the cache_serializations_across_watchers branch from 3f20ed6 to 7eb32f6 Compare August 26, 2019 20:30
Copy link
Member Author

@wojtek-t wojtek-t left a comment

Choose a reason for hiding this comment

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

The updates to first 5 commits were done in the parent PR: #81585

Copy link
Contributor

@jpbetz jpbetz left a comment

Choose a reason for hiding this comment

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

a couple more suggestions

@wojtek-t wojtek-t force-pushed the cache_serializations_across_watchers branch from 7eb32f6 to e876bce Compare August 27, 2019 00:03
// The following functions implement metav1.Object interface:
// - getters simply delegate for underlying object
// - SetSelfLink stores the value passed in the first call
// - all other setters ignore the passed value.
Copy link
Member

Choose a reason for hiding this comment

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

this is pretty confusing... I expected all getters/setters to pass through

Copy link
Member Author

Choose a reason for hiding this comment

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

This is a bit tricky. We can let them pass through and this will work, because noone is really using that.
But if we would e.g. create an encoder that is trying to overwrite one of the metadata, this can clearly break it for everyone. If course this is possible to fix - that encode instead of using CacheEncode should be calling GetObject() and operate on it. But that's relying on others.

I personally think that ignoring the values is safer - passing it through is easy to do, but I'm not sure it's what we really want.

Copy link
Member

@liggitt liggitt Sep 20, 2019

Choose a reason for hiding this comment

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

spoke offline. will switch setters to lock, invalidate the cache on changes, and pass through. we don't actually expect these to get called frequently, so this is just for completeness and to fulfill the objectmeta interface

Copy link
Member Author

Choose a reason for hiding this comment

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

done

defer o.lock.Unlock()
if o.selfLink != nil {
selfLink := *o.selfLink
result.selfLink = &selfLink
Copy link
Member

Choose a reason for hiding this comment

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

special-casing selfLink seems problematic. Can we generalize the object ownership principles so that the cached encoding can safely operate without this special-casing?

Copy link
Member Author

Choose a reason for hiding this comment

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

Once we will remove selflink, this special case will also be removed - this is sth that I had in the back of my head too.

Copy link
Member

Choose a reason for hiding this comment

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

can drop this as part of passing through setters

Copy link
Member Author

Choose a reason for hiding this comment

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

done

staging/src/k8s.io/apiserver/pkg/storage/cacher/cacher.go Outdated Show resolved Hide resolved
staging/src/k8s.io/apiserver/pkg/storage/cacher/cacher.go Outdated Show resolved Hide resolved
staging/src/k8s.io/apiserver/pkg/storage/cacher/cacher.go Outdated Show resolved Hide resolved
staging/src/k8s.io/apiserver/pkg/storage/cacher/cacher.go Outdated Show resolved Hide resolved
case !curObjPasses && oldObjPasses:
// return a delete event with the previous object content, but with the event's resource version
oldObj := event.PrevObject.DeepCopyObject()
if err := c.versioner.UpdateObject(oldObj, event.ResourceVersion); err != nil {
Copy link
Member

Choose a reason for hiding this comment

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

hmm... this is fragile and potentially problematic (the same original object+resourceVersion can be encoded with different resourceVersions)... definitely need a test that exercises an object at a given resourceVersion getting encoded into delete events at different resourceVersions. For example:

  • start three watchers
    • unfiltered
    • labelSelector=foo=true
    • labelSelector=bar=true
  • add object with labels foo=true, bar=true at rv=1
    • watch events with rv=1 get sent to all watchers
  • update object to remove foo=true label at rv=2
    • update event with rv=2 and bar=true content gets sent to unfiltered and bar=true watchers
    • delete event with rv=2 and foo=true,bar=true content gets sent to foo=true watcher
  • update object to remove bar=true label at rv=3
    • update event with rv=3 and no label content gets sent to unfiltered watcher
    • delete event with rv=3 and bar=true content gets sent to bar=true watcher
  • delete object at rv=4
    • delete event with rv=4 and no label content gets sent to unfiltered watcher

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah - this is also the reason why I think the deep-copy is needed.
Will work on adding this test now.

Copy link
Member Author

Choose a reason for hiding this comment

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

done

@wojtek-t wojtek-t force-pushed the cache_serializations_across_watchers branch from f4d16a5 to 25a728a Compare September 30, 2019 08:49
@k8s-ci-robot
Copy link
Contributor

@wojtek-t: Adding the "do-not-merge/release-note-label-needed" label because no release-note block was detected, please follow our release note process to remove it.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@k8s-ci-robot k8s-ci-robot added do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. and removed release-note-none Denotes a PR that doesn't merit a release note. labels Sep 30, 2019
@wojtek-t wojtek-t added release-note-none Denotes a PR that doesn't merit a release note. and removed do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. labels Sep 30, 2019
@wojtek-t
Copy link
Member Author

/retest

@liggitt
Copy link
Member

liggitt commented Oct 1, 2019

/lgtm
/approve

thanks for all the work on this

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Oct 1, 2019
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: liggitt, wojtek-t

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

The pull request process is described 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

@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Oct 1, 2019
@k8s-ci-robot k8s-ci-robot merged commit 7878160 into kubernetes:master Oct 1, 2019
@k8s-ci-robot k8s-ci-robot added this to the v1.17 milestone Oct 1, 2019
@k8s-ci-robot
Copy link
Contributor

@wojtek-t: The following test failed, say /retest to rerun them all:

Test name Commit Details Rerun command
pull-kubernetes-e2e-gce-100-performance 25a728a link /test pull-kubernetes-e2e-gce-100-performance

Full PR test history. Your PR dashboard. Please help us cut down on flakes by linking to an open issue when you hit one in your PR.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. area/apiserver area/kubectl cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. kind/api-change Categorizes issue or PR as related to adding, removing, or otherwise changing an API lgtm "Looks good to me", indicates that a PR is ready to be merged. priority/important-soon Must be staffed and worked on either currently, or very soon, ideally in time for the next release. release-note-none Denotes a PR that doesn't merit a release note. sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. sig/cli Categorizes an issue or PR as relevant to SIG CLI. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants