You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by mz...@apache.org on 2019/06/15 01:12:11 UTC
[mesos] 03/06: Refactored allocator with the new quota wrapper
struct.
This is an automated email from the ASF dual-hosted git repository.
mzhu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git
commit 495162eefa12900b3a74bfbb269851473df4cce9
Author: Meng Zhu <mz...@mesosphere.io>
AuthorDate: Wed Jun 5 14:04:53 2019 -0700
Refactored allocator with the new quota wrapper struct.
This patch also introduces a constant `DEFAULT_QUOTA`.
By default, a role has no guarantees and no limits.
Review: https://reviews.apache.org/r/70801
---
src/master/allocator/mesos/hierarchical.cpp | 49 +++++++++--------------------
src/master/allocator/mesos/hierarchical.hpp | 19 ++---------
src/master/constants.hpp | 4 +++
3 files changed, 22 insertions(+), 50 deletions(-)
diff --git a/src/master/allocator/mesos/hierarchical.cpp b/src/master/allocator/mesos/hierarchical.cpp
index ad0bcca..a7c237e 100644
--- a/src/master/allocator/mesos/hierarchical.cpp
+++ b/src/master/allocator/mesos/hierarchical.cpp
@@ -1410,21 +1410,12 @@ void HierarchicalAllocatorProcess::setQuota(
// the role is not set. Setting quota differs from updating it because
// the former moves the role to a different allocation group with a
// dedicated sorter, while the later just updates the actual quota.
- CHECK(getGuarantees(role).empty() && getLimits(role).empty());
+ CHECK(getQuota(role) == DEFAULT_QUOTA);
// In the legacy `SetQuota` call, quota guarantee also acts as quota limits.
//
// Note, quota has been validated to have no duplicate resource names.
- roles[role].quotaLimits = [&]() {
- google::protobuf::Map<string, Value::Scalar> limits;
- foreach (const Resource& r, quota.info.guarantee()) {
- limits[r.name()] = r.scalar();
- }
- return ResourceLimits(limits);
- }();
-
- roles[role].quotaGuarantees =
- ResourceQuantities::fromScalarResources(quota.info.guarantee());
+ roles[role].quota = Quota2(quota.info);
metrics.setQuota(role, quota);
@@ -1447,16 +1438,16 @@ void HierarchicalAllocatorProcess::removeQuota(
CHECK(initialized);
// Do not allow removing quota if it is not set.
- CHECK(!getGuarantees(role).empty() || !getLimits(role).empty());
+ // Note: it is impossible to set to default quota using the old `setQuota`.
+ CHECK(getQuota(role) != DEFAULT_QUOTA);
Role& r = roles.at(role);
// TODO(alexr): Print all quota info for the role.
- LOG(INFO) << "Removed quota " << r.quotaGuarantees
+ LOG(INFO) << "Removed quota " << r.quota.guarantees
<< " for role '" << role << "'";
- r.quotaGuarantees = ResourceQuantities();
- r.quotaLimits = ResourceLimits();
+ r.quota = DEFAULT_QUOTA;
if (r.isEmpty()) {
roles.erase(role);
}
@@ -1657,7 +1648,7 @@ void HierarchicalAllocatorProcess::__allocate()
foreachpair (const string& role, const Role& r, roles) {
// TODO(mzhu): Track all role consumed quota. We may want to expose
// these as metrics.
- if (!r.quotaGuarantees.empty() || !r.quotaLimits.empty()) {
+ if (r.quota != DEFAULT_QUOTA) {
logHeadroomInfo = true;
// Note, `reservationScalarQuantities` in `struct role`
// is hierarchical aware, thus it also includes subrole reservations.
@@ -1674,8 +1665,7 @@ void HierarchicalAllocatorProcess::__allocate()
const string& topLevelRole = strings::contains(role, "/") ?
role.substr(0, role.find('/')) : role;
- if (getGuarantees(topLevelRole).empty() &&
- getLimits(topLevelRole).empty()) {
+ if (getQuota(topLevelRole) == DEFAULT_QUOTA) {
continue;
}
@@ -1701,7 +1691,7 @@ void HierarchicalAllocatorProcess::__allocate()
ResourceQuantities requiredHeadroom;
foreachpair (const string& role, const Role& r, roles) {
requiredHeadroom +=
- r.quotaGuarantees -
+ r.quota.guarantees -
rolesConsumedQuota.get(role).getOrElse(ResourceQuantities());
}
@@ -1788,8 +1778,8 @@ void HierarchicalAllocatorProcess::__allocate()
Slave& slave = slaves.at(slaveId);
foreach (const string& role, roleSorter->sort()) {
- const ResourceQuantities& quotaGuarantees = getGuarantees(role);
- const ResourceLimits& quotaLimits = getLimits(role);
+ const ResourceQuantities& quotaGuarantees = getQuota(role).guarantees;
+ const ResourceLimits& quotaLimits = getQuota(role).limits;
// We only allocate to roles with non-default guarantees
// in the first stage.
@@ -2039,7 +2029,7 @@ void HierarchicalAllocatorProcess::__allocate()
break; // Nothing left on this agent.
}
- const ResourceLimits& quotaLimits = getLimits(role);
+ const ResourceLimits& quotaLimits = getQuota(role).limits;
// NOTE: Suppressed frameworks are not included in the sort.
CHECK_CONTAINS(frameworkSorters, role);
@@ -2137,7 +2127,7 @@ void HierarchicalAllocatorProcess::__allocate()
ResourceQuantities increasedQuotaConsumption =
ResourceQuantities::fromScalarResources(additionalScalarAllocation);
- if (!getGuarantees(role).empty() || !getLimits(role).empty()) {
+ if (getQuota(role) != DEFAULT_QUOTA) {
rolesConsumedQuota[role] += increasedQuotaConsumption;
for (const string& ancestor : roles::ancestors(role)) {
rolesConsumedQuota[ancestor] += increasedQuotaConsumption;
@@ -2557,18 +2547,9 @@ bool HierarchicalAllocatorProcess::isFrameworkTrackedUnderRole(
}
-const ResourceQuantities& HierarchicalAllocatorProcess::getGuarantees(
- const string& role) const
-{
- return roles.contains(role) ? roles.at(role).quotaGuarantees
- : defaultQuotaGuarantees;
-}
-
-
-const ResourceLimits& HierarchicalAllocatorProcess::getLimits(
- const string& role) const
+const Quota2& HierarchicalAllocatorProcess::getQuota(const string& role) const
{
- return roles.contains(role) ? roles.at(role).quotaLimits : defaultQuotaLimits;
+ return roles.contains(role) ? roles.at(role).quota : DEFAULT_QUOTA;
}
diff --git a/src/master/allocator/mesos/hierarchical.hpp b/src/master/allocator/mesos/hierarchical.hpp
index 1a3329d..0a6482a 100644
--- a/src/master/allocator/mesos/hierarchical.hpp
+++ b/src/master/allocator/mesos/hierarchical.hpp
@@ -119,15 +119,13 @@ struct Role
// Configured guaranteed resource quantities and resource limits for
// this role. By default, a role has no guarantee and no limit.
- ResourceQuantities quotaGuarantees;
- ResourceLimits quotaLimits;
+ Quota2 quota;
bool isEmpty() const
{
return frameworks.empty() &&
reservationScalarQuantities.empty() &&
- quotaGuarantees.empty() &&
- quotaLimits.empty();
+ quota == DEFAULT_QUOTA;
}
};
@@ -619,23 +617,12 @@ protected:
// Factory function for framework sorters.
const std::function<Sorter*()> frameworkSorterFactory;
- // By default, roles have empty quota guarantees and limits.
- //
- // We keep this in memory so that roles that are absent in the `roles` map
- // could also keep their quota state in memory.
- //
- // TODO(mzhu): remove this once we have proper role life cycle management
- // such that every role would have an entry in the `roles` map.
- const ResourceQuantities defaultQuotaGuarantees;
- const ResourceLimits defaultQuotaLimits;
-
private:
bool isFrameworkTrackedUnderRole(
const FrameworkID& frameworkId,
const std::string& role) const;
- const ResourceQuantities& getGuarantees(const std::string& role) const;
- const ResourceLimits& getLimits(const std::string& role) const;
+ const Quota2& getQuota(const std::string& role) const;
void trackFrameworkUnderRole(
const FrameworkID& frameworkId,
diff --git a/src/master/constants.hpp b/src/master/constants.hpp
index 8f729d1..8502240 100644
--- a/src/master/constants.hpp
+++ b/src/master/constants.hpp
@@ -20,6 +20,7 @@
#include <stdint.h>
#include <mesos/mesos.hpp>
+#include <mesos/quota/quota.hpp>
#include <stout/bytes.hpp>
#include <stout/duration.hpp>
@@ -172,6 +173,9 @@ const Version MINIMUM_AGENT_VERSION = Version(1, 0, 0);
std::vector<MasterInfo::Capability> MASTER_CAPABILITIES();
+// A role's default quota: no guarantees and no limits.
+const Quota2 DEFAULT_QUOTA;
+
} // namespace master {
} // namespace internal {
} // namespace mesos {