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

(POOLER-129) Allow setting weights for backends #298

Merged
merged 4 commits into from
Sep 18, 2018

Conversation

mattkirby
Copy link
Contributor

This commit updates get_vm in the vmpooler API to allow for setting weights for backends. Additionally, when an alias for a pool exists, and the backend configured is not weighted, then the selection of the pool based on alias will be randomly sampled. Without this change any pool with the title of the alias is exhausted before an alternate pool with the configured alias is used, which results in an uneven distribution of VMs. When all backends involved are configured with weighted values the VM selection will be based on probability using those weights.

A bug is fixed when setting the default ttl for check_ready_vm.

Pickup is added to handle weighted VM selection.

A dockerfile is added that allows for building and installing vmpooler
from the current HEAD in docker to make for easy testing.

This commit updates get_vm in the vmpooler API to allow for setting weights for backends. Additionally, when an alias for a pool exists, and the backend configured is not weighted, then the selection of the pool based on alias will be randomly sampled. Without this change any pool with the title of the alias is exhausted before an alternate pool with the configured alias is used, which results in an uneven distribution of VMs. When all backends involved are configured with weighted values the VM selection will be based on probability using those weights.

A bug is fixed when setting the default ttl for check_ready_vm.

Pickup is added to handle weighted VM selection.

A dockerfile is added that allows for building and installing vmpooler
from the current HEAD in docker to make for easy testing.
next unless pool_index.key? t
index = pool_index[t]
clone_target = pools[index]['clone_target'] || config['clone_target']
next unless config.key?('backend_weight')
Copy link
Contributor

Choose a reason for hiding this comment

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

We should add this backend_weight to the docs.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point.

@@ -428,7 +428,7 @@ def destroy_vm(pool_name, vm_name)

def vm_ready?(_pool_name, vm_name)
begin
open_socket(vm_name)
open_socket(vm_name, global_config[:config]['domain'])
Copy link
Contributor

Choose a reason for hiding this comment

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

this looks like an unrelated change?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. I previously implemented the ability to specify a VM domain to use when opening a socket connection. Without this change that domain setting is never used. When interacting with a local instance of vmpooler in docker I found that I could not get VMs to reach the ready state without this addition. I could make this a separate commit if you think that makes more sense.

def fetch_single_vm(template)
vm = backend.spop('vmpooler__ready__' + template)
return [vm, template] if vm
def pool_backend(pool)
Copy link
Contributor

@sbeaulie sbeaulie Sep 13, 2018

Choose a reason for hiding this comment

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

a similar method already exists as a helper method and used 4-5 times in the code

def get_target_datacenter_from_config(pool_name)
pool = pool_config(pool_name)
return nil if pool.nil?
return pool['datacenter'] unless pool['datacenter'].nil?
return provider_config['datacenter'] unless provider_config['datacenter'].nil?
nil
end

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This method was temporary and isn't used. I need to push the change that removes it. Sorry for the noise.

if weighted_pools.count == template_backends.count
pickup = Pickup.new(weighted_pools)
selection = pickup.pick
template_backends.delete(selection)
Copy link
Contributor

Choose a reason for hiding this comment

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

why remove and re-add it at the beginning of the array?

Copy link
Contributor

@sbeaulie sbeaulie Sep 13, 2018

Choose a reason for hiding this comment

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

I think I'm following the logic now. Why not capture the selection here and in the else below. Then instead of doing template_backends.each on line 75 again, just backend.spop() the selection?

Copy link
Contributor Author

@mattkirby mattkirby Sep 13, 2018

Choose a reason for hiding this comment

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

My goal is to order the array so the first VM we try to retrieve is based on the selection from pickup. There is an each statement because we need to try this for the next one in the list in case there are no ready VMs for the first selection. If no pool or matching alias can provide the VM only then will it return nil.

Copy link
Contributor

@kevpl kevpl left a comment

Choose a reason for hiding this comment

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

I'm 👍 on this, but a challenge I had is that I'm not sure I understand how the weight numbers work from the docs.

They seem to imply that the weights should add to 100, but it doesn't appear true. If you look to the pickup docs, it shows that they don't have to add to 100, but I assume they're normalized to 100% by having whatever number they add to be be the denominator of the fraction?

@mattkirby
Copy link
Contributor Author

From what I understand with reading the pickup docs you are setting a probability with that value that is relative to the other values, but has no requirements for equalling a total value, or anything like that. Do you think the example would be more clear if single digits, or values that do not total 100 were used?

@mchllweeks mchllweeks merged commit 98a84ab into puppetlabs:master Sep 18, 2018
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.

4 participants