<div dir="ltr">Thank you very much for in-depth discussion about this topic, @Nikola and @Sylvain.<div><br></div><div>I agree that we should solve the technical debt firstly, and then make the scheduler better.</div><div><br></div><div>Best Regards.</div></div><div class="gmail_extra"><br><div class="gmail_quote">2015-03-05 21:12 GMT+08:00 Sylvain Bauza <span dir="ltr"><<a href="mailto:sbauza@redhat.com" target="_blank">sbauza@redhat.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
Le 05/03/2015 13:00, Nikola Đipanov a écrit :<div><div class="h5"><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
On 03/04/2015 09:23 AM, Sylvain Bauza wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Le 04/03/2015 04:51, Rui Chen a écrit :<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hi all,<br>
<br>
I want to make it easy to launch a bunch of scheduler processes on a<br>
host, multiple scheduler workers will make use of multiple processors<br>
of host and enhance the performance of nova-scheduler.<br>
<br>
I had registered a blueprint and commit a patch to implement it.<br>
<a href="https://blueprints.launchpad.net/nova/+spec/scheduler-multiple-workers-support" target="_blank">https://blueprints.launchpad.<u></u>net/nova/+spec/scheduler-<u></u>multiple-workers-support</a><br>
<br>
This patch had applied in our performance environment and pass some<br>
test cases, like: concurrent booting multiple instances, currently we<br>
didn't find inconsistent issue.<br>
<br>
IMO, nova-scheduler should been scaled horizontally on easily way, the<br>
multiple workers should been supported as an out of box feature.<br>
<br>
Please feel free to discuss this feature, thanks.<br>
</blockquote>
<br>
As I said when reviewing your patch, I think the problem is not just<br>
making sure that the scheduler is thread-safe, it's more about how the<br>
Scheduler is accounting resources and providing a retry if those<br>
consumed resources are higher than what's available.<br>
<br>
Here, the main problem is that two workers can actually consume two<br>
distinct resources on the same HostState object. In that case, the<br>
HostState object is decremented by the number of taken resources (modulo<br>
what means a resource which is not an Integer...) for both, but nowhere<br>
in that section, it does check that it overrides the resource usage. As<br>
I said, it's not just about decorating a semaphore, it's more about<br>
rethinking how the Scheduler is managing its resources.<br>
<br>
<br>
That's why I'm -1 on your patch until [1] gets merged. Once this BP will<br>
be implemented, we will have a set of classes for managing heterogeneous<br>
types of resouces and consume them, so it would be quite easy to provide<br>
a check against them in the consume_from_instance() method.<br>
<br>
</blockquote>
I feel that the above explanation does not give the full picture in<br>
addition to being factually incorrect in several places. I have come to<br>
realize that the current behaviour of the scheduler is subtle enough<br>
that just reading the code is not enough to understand all the edge<br>
cases that can come up. The evidence being that it trips up even people<br>
that have spent significant time working on the code.<br>
<br>
It is also important to consider the design choices in terms of<br>
tradeoffs that they were trying to make.<br>
<br>
So here are some facts about the way Nova does scheduling of instances<br>
to compute hosts, considering the amount of resources requested by the<br>
flavor (we will try to put the facts into a bigger picture later):<br>
<br>
* Scheduler receives request to chose hosts for one or more instances.<br>
* Upon every request (_not_ for every instance as there may be several<br>
instances in a request) the scheduler learns the state of the resources<br>
on all compute nodes from the central DB. This state may be inaccurate<br>
(meaning out of date).<br>
* Compute resources are update by each compute host periodically. This<br>
is done by updating the row in the DB.<br>
* The wall-clock time difference between the scheduler deciding to<br>
schedule an instance, and the resource consumption being reflected in<br>
the data the scheduler learns from the DB can be arbitrarily long (due<br>
to load on the compute nodes and latency of message arrival).<br>
* To cope with the above, there is a concept of retrying the request<br>
that fails on a certain compute node due to the scheduling decision<br>
being made with data stale at the moment of build, by default we will<br>
retry 3 times before giving up.<br>
* When running multiple instances, decisions are made in a loop, and<br>
internal in-memory view of the resources gets updated (the widely<br>
misunderstood consume_from_instance method is used for this), so as to<br>
keep subsequent decisions as accurate as possible. As was described<br>
above, this is all thrown away once the request is finished.<br>
<br>
Now that we understand the above, we can start to consider what changes<br>
when we introduce several concurrent scheduler processes.<br>
<br>
Several cases come to mind:<br>
* Concurrent requests will no longer be serialized on reading the state<br>
of all hosts (due to how eventlet interacts with mysql driver).<br>
* In the presence of a single request for a large number of instances<br>
there is going to be a drift in accuracy of the decisions made by other<br>
schedulers as they will not have the accounted for any of the instances<br>
until they actually get claimed on their respective hosts.<br>
<br>
All of the above limitations will likely not pose a problem under normal<br>
load and usage and can cause issues to start appearing when nodes are<br>
close to full or when there is heavy load. Also this changes drastically<br>
based on how we actually chose to utilize hosts (see a very interesting<br>
Ironic bug [1])<br>
<br>
Weather any of the above matters to users is dependant heavily on their<br>
use-case though. This is why I feel we should be providing more information.<br>
<br>
Finally - I think it is important to accept that the scheduler service<br>
will always have to operate under the assumptions of stale data, and<br>
build for that. Based on that I'd be happy to see real work go into<br>
making multiple schedulers work well enough for most common use-cases<br>
while providing a way forward for people who need tighter bounds on the<br>
feedback loop.<br>
<br>
N.<br>
</blockquote>
<br></div></div>
Agreed 100% with all your above email. Thanks Nikola for giving time on explaining how the Scheduler is working, that's (btw.) something I hope to be presenting for the Vancouver Summit if my proposal is accepted.<br>
<br>
That said, I hope my reviewers will understand that I would want to see first the Scheduler being splitted and being on a separate repo before working on fixing the race conditions you mentioned above. Yes, I know, it's difficult to accept some limitations on the Nova scheduler while many customers would want them to be fixed, but here we have so many technical debt issues that I think we should really work on the split itself (like we did for Kilo and what we'll hopefully work for Liberty) and then discuss on the new design once after that.<span class="HOEnZb"><font color="#888888"><br>
<br>
-Sylvain</font></span><div class="HOEnZb"><div class="h5"><br>
<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
[1] <a href="https://bugs.launchpad.net/nova/+bug/1341420" target="_blank">https://bugs.launchpad.net/<u></u>nova/+bug/1341420</a><br>
<br>
______________________________<u></u>______________________________<u></u>______________<br>
OpenStack Development Mailing List (not for usage questions)<br>
Unsubscribe: <a href="http://OpenStack-dev-request@lists.openstack.org?subject:unsubscribe" target="_blank">OpenStack-dev-request@lists.<u></u>openstack.org?subject:<u></u>unsubscribe</a><br>
<a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" target="_blank">http://lists.openstack.org/<u></u>cgi-bin/mailman/listinfo/<u></u>openstack-dev</a><br>
</blockquote>
<br>
<br>
______________________________<u></u>______________________________<u></u>______________<br>
OpenStack Development Mailing List (not for usage questions)<br>
Unsubscribe: <a href="http://OpenStack-dev-request@lists.openstack.org?subject:unsubscribe" target="_blank">OpenStack-dev-request@lists.<u></u>openstack.org?subject:<u></u>unsubscribe</a><br>
<a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" target="_blank">http://lists.openstack.org/<u></u>cgi-bin/mailman/listinfo/<u></u>openstack-dev</a><br>
</div></div></blockquote></div><br></div>