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

Only retrieve relevant volumes #41785

Merged

Conversation

jamiehannaford
Copy link
Contributor

@jamiehannaford jamiehannaford commented Feb 21, 2017

What this PR does / why we need it:

Improves performance for Cinder volume attach/detach calls.

Currently when Cinder volumes are attached or detached, functions try to retrieve details about the volume from the Nova API. Because some only have the volume name not its UUID, they use the list function in gophercloud to iterate over all volumes to find a match. This incurs severe performance problems on OpenStack projects with lots of volumes (sometimes thousands) since it needs to send a new request when the current page does not contain a match. A better way of doing this is use the ?name=XXX query parameter to refine the results.

Which issue this PR fixes:

#26404

Special notes for your reviewer:

There were 2 ways of addressing this problem:

  1. Use the name query parameter
  2. Instead of using the list function, switch to using volume UUIDs and use the GET function instead. You'd need to change the signature of a few functions though, such as DeleteVolume, so I'm not sure how backwards compatible that is.

Since #1 does effectively the same as #2, I went with it because it ensures BC.

One assumption that is made is that the volumeName being retrieved matches exactly the name of the volume in Cinder. I'm not sure how accurate that is, but I see no reason why cloud providers would want to append/prefix things arbitrarily.

Release note:

Improves performance of Cinder volume attach/detach operations

@k8s-ci-robot
Copy link
Contributor

Hi @jamiehannaford. Thanks for your PR.

I'm waiting for a kubernetes member to verify that this patch is reasonable to test. If it is, they should reply with @k8s-bot ok to test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

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.

@k8s-ci-robot k8s-ci-robot added the cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. label Feb 21, 2017
@k8s-github-robot k8s-github-robot added size/XS Denotes a PR that changes 0-9 lines, ignoring generated files. release-note Denotes a PR that will be considered when it comes time to generate release notes. labels Feb 21, 2017
@k8s-reviewable
Copy link

This change is Reviewable

@thockin thockin assigned jingxu97 and unassigned thockin Feb 21, 2017
@@ -115,7 +115,8 @@ func (os *OpenStack) getVolume(diskName string) (volumes.Volume, error) {
return volume, err
}

err = volumes.List(sClient, nil).EachPage(func(page pagination.Page) (bool, error) {
opts := &volumes.ListOpts{Name: diskName}
err = volumes.List(sClient, opts).EachPage(func(page pagination.Page) (bool, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

What is the difference of using opts vs. nil?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The Cinder API allows you to provide query parameters in the URL when retrieving a list of volumes. Filtering by name for example allows you to restrict the amount of volumes down considerably. Otherwise, the K8s code will traverse the entire collection of volumes in an OpenStack project to find a match (some project could have 10s of thousands). Filtering by name reduces/eliminates the need for subsequent pagination calls.

@jamiehannaford
Copy link
Contributor Author

Any status update for this?

@jamiehannaford
Copy link
Contributor Author

@k8s-sig-openstack-pr-reviews Would somebody mind reviewing this?

@xsgordon
Copy link

@idvoretskyi can you add the sig/openstack label please?

@hogepodge
Copy link

lgtm

@k8s-github-robot k8s-github-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Mar 30, 2017
@k8s-github-robot k8s-github-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Mar 31, 2017
@jamiehannaford
Copy link
Contributor Author

@hogepodge Would you mind re-running tests? There seems to be a flaky test case failing

@grodrigues3 grodrigues3 added the needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. label Apr 5, 2017
@jamiehannaford
Copy link
Contributor Author

@jingxu97 @xsgordon @grodrigues3 @k8s-sig-openstack-api-reviews Would somebody mind commenting with ok to test so I can fix flaky tests?

@jingxu97 jingxu97 removed the needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. label Apr 12, 2017
@jingxu97
Copy link
Contributor

/approve

@jingxu97
Copy link
Contributor

@k8s-bot ok to test

@jamiehannaford
Copy link
Contributor Author

@jingxu97 @anguslees Would somebody mind commenting with /approve and /lgtm?

@@ -111,7 +111,9 @@ func (volumes *VolumesV2) createVolume(opts VolumeCreateOpts) (string, error) {
func (volumes *VolumesV1) getVolume(diskName string) (Volume, error) {
var volume_v1 volumes_v1.Volume
var volume Volume
err := volumes_v1.List(volumes.blockstorage, nil).EachPage(func(page pagination.Page) (bool, error) {

opts := &volumes_v1.ListOpts{Name: diskName}
Copy link
Member

Choose a reason for hiding this comment

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

The logic below looks for either name == diskName or the ID contains diskName. That latter case sounds amazingly terrible, but are we confident we don't need it? (and if so, can we remove it in this PR to make it clear that that logic isn't going to trigger anymore?)

@@ -149,7 +151,9 @@ func (volumes *VolumesV1) getVolume(diskName string) (Volume, error) {
func (volumes *VolumesV2) getVolume(diskName string) (Volume, error) {
var volume_v2 volumes_v2.Volume
var volume Volume
err := volumes_v2.List(volumes.blockstorage, nil).EachPage(func(page pagination.Page) (bool, error) {

opts := &volumes_v2.ListOpts{Name: diskName}
Copy link
Member

Choose a reason for hiding this comment

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

Ditto - clarify the "ID contains diskName" case below

@jamiehannaford jamiehannaford force-pushed the cinder-performance branch 2 times, most recently from 25d7dc3 to ba33b16 Compare May 2, 2017 12:49
@jamiehannaford
Copy link
Contributor Author

@anguslees I've refactored a bunch of signatures to make the volume ID stuff clearer. I don't why it was implemented to handle both names and IDs, but I've switched it to the latter. It also seems that the current volume implementation uses IDs too, so I think this is backwards compatible.

@k8s-github-robot k8s-github-robot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/XS Denotes a PR that changes 0-9 lines, ignoring generated files. labels May 2, 2017
@jamiehannaford
Copy link
Contributor Author

@mikedanese Would you mind weighing in here and if necessary approving this change?

@jsafrane
Copy link
Member

Since the behaviour change interacted with this ID/name confusion, the PR seeks to also simplify it. I don't see a reason why this PR can't do both.

I am not against the PR, I am trying to find out what it tries to do, as it is quite a long one and I do not want to miss some important spot hidden between renames.

So far it looks good, please rebase and I'll mark it as lgtm.

@mikedanese mikedanese assigned saad-ali and unassigned mikedanese May 11, 2017
@k8s-github-robot k8s-github-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label May 12, 2017
@jamiehannaford
Copy link
Contributor Author

@jsafrane Thanks for the feedback. I've made those changes - would you mind taking another quick look and adding /lgtm?

@jsafrane
Copy link
Member

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label May 16, 2017
@jamiehannaford
Copy link
Contributor Author

@mikedanese Can you /approve this PR?

@mikedanese
Copy link
Member

/approve

@k8s-github-robot k8s-github-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label May 16, 2017
@k8s-github-robot k8s-github-robot removed the lgtm "Looks good to me", indicates that a PR is ready to be merged. label May 17, 2017
@jamiehannaford jamiehannaford force-pushed the cinder-performance branch 3 times, most recently from 9520b26 to 8fe7860 Compare May 17, 2017 12:37
@jamiehannaford
Copy link
Contributor Author

@jsafrane Can you add /lgtm again? sorry for the pestering 😛

@jamiehannaford
Copy link
Contributor Author

Bump cc/ @jsafrane

@jsafrane
Copy link
Member

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label May 24, 2017
@k8s-github-robot
Copy link

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: jamiehannaford, jingxu97, jsafrane, mikedanese

Needs approval from an approver in each of these OWNERS Files:

You can indicate your approval by writing /approve in a comment
You can cancel your approval by writing /approve cancel in a comment

@k8s-github-robot
Copy link

Automatic merge from submit-queue (batch tested with PRs 38505, 41785, 46315)

@k8s-github-robot k8s-github-robot merged commit 70dd10c into kubernetes:master May 24, 2017
@k8s-ci-robot
Copy link
Contributor

k8s-ci-robot commented May 24, 2017

@jamiehannaford: The following test(s) failed:

Test name Commit Details Rerun command
pull-kubernetes-federation-e2e-gce 4bd71a3 link @k8s-bot pull-kubernetes-federation-e2e-gce test this

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.

dims pushed a commit to dims/kubernetes that referenced this pull request Feb 8, 2018
…mance

Automatic merge from submit-queue (batch tested with PRs 38505, 41785, 46315)

Only retrieve relevant volumes

**What this PR does / why we need it**:

Improves performance for Cinder volume attach/detach calls. 

Currently when Cinder volumes are attached or detached, functions try to retrieve details about the volume from the Nova API. Because some only have the volume name not its UUID, they use the list function in gophercloud to iterate over all volumes to find a match. This incurs severe performance problems on OpenStack projects with lots of volumes (sometimes thousands) since it needs to send a new request when the current page does not contain a match. A better way of doing this is use the `?name=XXX` query parameter to refine the results.

**Which issue this PR fixes**:

kubernetes#26404

**Special notes for your reviewer**:

There were 2 ways of addressing this problem:

1. Use the `name` query parameter
2. Instead of using the list function, switch to using volume UUIDs and use the GET function instead. You'd need to change the signature of a few functions though, such as [`DeleteVolume`](https://github.com/kubernetes/kubernetes/blob/master/pkg/volume/cinder/cinder.go#L49), so I'm not sure how backwards compatible that is.

Since #1 does effectively the same as #2, I went with it because it ensures BC.

One assumption that is made is that the `volumeName` being retrieved matches exactly the name of the volume in Cinder. I'm not sure how accurate that is, but I see no reason why cloud providers would want to append/prefix things arbitrarily. 

**Release note**:
```release-note
Improves performance of Cinder volume attach/detach operations
```
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/provider/openstack Issues or PRs related to openstack provider cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lgtm "Looks good to me", indicates that a PR is ready to be merged. release-note Denotes a PR that will be considered when it comes time to generate release notes. sig/storage Categorizes an issue or PR as relevant to SIG Storage. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet