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

Change resource sync to use PATCH instead of PUTs #50

Merged
merged 1 commit into from
Oct 1, 2019

Conversation

patrick-east
Copy link
Contributor

@patrick-east patrick-east commented Sep 26, 2019

When sync'ing resources kube-mgmt would do a delete and then a PUT
request for each object. This will aggregate all of the objects into
one PUT request.

@patrick-east
Copy link
Contributor Author

/cc @tsandall

This handles part of what was talked about in #49 for batching together the sync requests. This does it for each generic sync (ie each resource type being sync'd). If we wanted to do a single patch for all of them I'll need to do some additional refactoring. Something like that might work as a solution to batch updates too, thinking a like generic buffering step in front of the OPA API's to batch requests.

Copy link
Member

@tsandall tsandall left a comment

Choose a reason for hiding this comment

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

Small comment about factoring the patch set generation into a helper and testing that separately. Also, would be good test both namespaced and non-namespaced resources, e.g., Pods and Nodes (respectively).

Did you have a chance to benchmark the change? Would be good to have a rough idea of hte improvement this yields.

pkg/data/generic.go Show resolved Hide resolved
pkg/data/generic.go Outdated Show resolved Hide resolved
pkg/data/generic.go Outdated Show resolved Hide resolved
@patrick-east patrick-east changed the title Change resource sync to use PATCH instead of PUTs [WIP] Change resource sync to use PATCH instead of PUTs Sep 26, 2019
@patrick-east
Copy link
Contributor Author

Updates still incoming. I was messing around with a test cluster and see some pretty decent preliminary results as far as performance improvements:

Current master:

time="2019-09-27T03:09:31Z" level=warning msg="First line of log stream."
time="2019-09-27T03:09:31Z" level=info msg="Syncing v1/pods."
time="2019-09-27T03:09:31Z" level=info msg="Syncing v1/nodes."
time="2019-09-27T03:09:31Z" level=info msg="Syncing apps/v1/deployments."
time="2019-09-27T03:09:31Z" level=info msg="Listed apps/v1/deployments and got 3 resources with resourceVersion 12088. Took 28.3787ms."
time="2019-09-27T03:09:31Z" level=info msg="Listed v1/nodes and got 5 resources with resourceVersion 12088. Took 32.5202ms."
time="2019-09-27T03:09:31Z" level=info msg="Loaded apps/v1/deployments resources into OPA. Took 50.1687ms. Starting watch at resourceVersion 12088."
time="2019-09-27T03:09:31Z" level=info msg="Loaded v1/nodes resources into OPA. Took 47.7993ms. Starting watch at resourceVersion 12088."
time="2019-09-27T03:09:31Z" level=info msg="Listed v1/pods and got 417 resources with resourceVersion 12088. Took 166.6928ms."
time="2019-09-27T03:09:32Z" level=info msg="Loaded v1/pods resources into OPA. Took 693.6081ms. Starting watch at resourceVersion 12088."

This branch:

time="2019-09-27T03:02:02Z" level=warning msg="First line of log stream."
time="2019-09-27T03:02:02Z" level=info msg="Syncing v1/pods."
time="2019-09-27T03:02:02Z" level=info msg="Syncing v1/nodes."
time="2019-09-27T03:02:02Z" level=info msg="Syncing apps/v1/deployments."
time="2019-09-27T03:02:02Z" level=info msg="Listed apps/v1/deployments and got 3 resources with resourceVersion 11281. Took 15.9774ms."
time="2019-09-27T03:02:02Z" level=info msg="Listed v1/nodes and got 5 resources with resourceVersion 11281. Took 18.2052ms."
time="2019-09-27T03:02:02Z" level=info msg="Loaded apps/v1/deployments resources into OPA. Took 15.537ms. Starting watch at resourceVersion 11281."
time="2019-09-27T03:02:02Z" level=info msg="Loaded v1/nodes resources into OPA. Took 17.0578ms. Starting watch at resourceVersion 11281."
time="2019-09-27T03:02:03Z" level=info msg="Listed v1/pods and got 417 resources with resourceVersion 11281. Took 155.286ms."
time="2019-09-27T03:02:03Z" level=info msg="Loaded v1/pods resources into OPA. Took 206.1772ms. Starting watch at resourceVersion 11281."

@patrick-east patrick-east changed the title [WIP] Change resource sync to use PATCH instead of PUTs Change resource sync to use PATCH instead of PUTs Sep 30, 2019
Copy link
Member

@tsandall tsandall left a comment

Choose a reason for hiding this comment

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

See comment about PUT vs. PATCH.

// We don't do a 'remove' patch because doesn't exist we waste all the
// resources parsing the giant patch payload and have to try again.. Best
// option currently is to just do two requests.
err = s.opa.PutData("/", map[string]interface{}{})
Copy link
Member

Choose a reason for hiding this comment

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

I was thinking about this a bit more and now I'm wondering why we can't just set the entire collection at once? If we do a PUT on /v1/data/kubernetes/ it'll overwrite everything in the collection. This may even be more efficient than the PATCH method since the server and store don't have to process a bunch of separate patch operations. WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was also wondering about that. I shied-away from it initially because I was concerned about having to limit the size of the payloads and patches seemed like the most direct way to chunk them up. That being said.. there isn't really any difference between that and just building PUT payloads of different sizes. Let me update quickly to try it out and see if there is much of a difference in performance.

On paper I think you're right though that a single large PUT should be less load on the server as it is today.

When sync'ing resources kube-mgmt would do a delete and then a PUT
request for each object. This will aggregate all of the objects into
one PUT request.

Signed-off-by: Patrick East <[email protected]>
@patrick-east
Copy link
Contributor Author

Updated to single PUT, speeds appear to be pretty similar to PATCH but as seen in the unit tests the payload is considerably smaller so we're saving some resources on processing JSON on both ends.

time="2019-10-01T15:33:14Z" level=warning msg="First line of log stream."
time="2019-10-01T15:33:14Z" level=info msg="Syncing v1/pods."
time="2019-10-01T15:33:14Z" level=info msg="Syncing v1/nodes."
time="2019-10-01T15:33:14Z" level=info msg="Syncing apps/v1/deployments."
time="2019-10-01T15:33:14Z" level=info msg="Listed v1/nodes and got 5 resources with resourceVersion 13010. Took 29.1663ms."
time="2019-10-01T15:33:14Z" level=info msg="Listed apps/v1/deployments and got 3 resources with resourceVersion 13010. Took 39.1227ms."
time="2019-10-01T15:33:14Z" level=info msg="Loaded v1/nodes resources into OPA. Took 10.3794ms. Starting watch at resourceVersion 13010."
time="2019-10-01T15:33:14Z" level=info msg="Loaded apps/v1/deployments resources into OPA. Took 9.3372ms. Starting watch at resourceVersion 13010."
time="2019-10-01T15:33:14Z" level=info msg="Listed v1/pods and got 417 resources with resourceVersion 13010. Took 156.4264ms."
time="2019-10-01T15:33:15Z" level=info msg="Loaded v1/pods resources into OPA. Took 176.3088ms. Starting watch at resourceVersion 13010."

Copy link
Member

@tsandall tsandall left a comment

Choose a reason for hiding this comment

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

LGTM

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.

2 participants