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 <[email protected]> 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 {
