You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by bm...@apache.org on 2016/03/26 01:12:19 UTC
[2/2] mesos git commit: Added a metric for the number of per-role
active offer filters.
Added a metric for the number of per-role active offer filters.
Review: https://reviews.apache.org/r/43883/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/08c68dc7
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/08c68dc7
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/08c68dc7
Branch: refs/heads/master
Commit: 08c68dc7ec1149649339b6bd0733e4c658ef1183
Parents: 2309ae9
Author: Benjamin Bannier <be...@mesosphere.io>
Authored: Thu Mar 24 16:55:30 2016 -0700
Committer: Benjamin Mahler <bm...@apache.org>
Committed: Fri Mar 25 17:10:00 2016 -0700
----------------------------------------------------------------------
docs/monitoring.md | 7 ++
src/master/allocator/mesos/hierarchical.cpp | 22 +++++
src/master/allocator/mesos/hierarchical.hpp | 3 +
src/master/allocator/mesos/metrics.cpp | 32 +++++++
src/master/allocator/mesos/metrics.hpp | 6 ++
src/tests/hierarchical_allocator_tests.cpp | 102 +++++++++++++++++++++++
6 files changed, 172 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/08c68dc7/docs/monitoring.md
----------------------------------------------------------------------
diff --git a/docs/monitoring.md b/docs/monitoring.md
index dcf19e6..76be328 100644
--- a/docs/monitoring.md
+++ b/docs/monitoring.md
@@ -952,6 +952,13 @@ and resource allocations in the allocator.
</tr>
<tr>
<td>
+ <code>allocator/mesos/offer_filters/roles/<role>/active</code>
+ </td>
+ <td>Number of active offer filters for all frameworks within the role</td>
+ <td>Gauge</td>
+</tr>
+<tr>
+ <td>
<code>allocator/mesos/quota/roles/<role>/resources/<resource>/offered_or_allocated</code>
</td>
<td>Amount of resources considered offered or allocated towards
http://git-wip-us.apache.org/repos/asf/mesos/blob/08c68dc7/src/master/allocator/mesos/hierarchical.cpp
----------------------------------------------------------------------
diff --git a/src/master/allocator/mesos/hierarchical.cpp b/src/master/allocator/mesos/hierarchical.cpp
index a51c723..5a5df5f 100644
--- a/src/master/allocator/mesos/hierarchical.cpp
+++ b/src/master/allocator/mesos/hierarchical.cpp
@@ -226,6 +226,7 @@ void HierarchicalAllocatorProcess::addFramework(
activeRoles[role] = 1;
roleSorter->add(role, roleWeight(role));
frameworkSorters[role] = frameworkSorterFactory();
+ metrics.addRole(role);
} else {
activeRoles[role]++;
}
@@ -315,6 +316,8 @@ void HierarchicalAllocatorProcess::removeFramework(
CHECK(frameworkSorters.contains(role));
delete frameworkSorters[role];
frameworkSorters.erase(role);
+
+ metrics.removeRole(role);
}
// Do not delete the filters contained in this
@@ -1758,6 +1761,25 @@ double HierarchicalAllocatorProcess::_quota_allocated(
return used.isSome() ? used->value() : 0;
}
+
+double HierarchicalAllocatorProcess::_offer_filters_active(
+ const string& role)
+{
+ double result = 0;
+
+ foreachvalue (const Framework& framework, frameworks) {
+ if (framework.role != role) {
+ continue;
+ }
+
+ foreachkey (const SlaveID& slaveId, framework.offerFilters) {
+ result += framework.offerFilters.get(slaveId)->size();
+ }
+ }
+
+ return result;
+}
+
} // namespace internal {
} // namespace allocator {
} // namespace master {
http://git-wip-us.apache.org/repos/asf/mesos/blob/08c68dc7/src/master/allocator/mesos/hierarchical.hpp
----------------------------------------------------------------------
diff --git a/src/master/allocator/mesos/hierarchical.hpp b/src/master/allocator/mesos/hierarchical.hpp
index e4604f4..1ba319b 100644
--- a/src/master/allocator/mesos/hierarchical.hpp
+++ b/src/master/allocator/mesos/hierarchical.hpp
@@ -295,6 +295,9 @@ protected:
const std::string& role,
const std::string& resource);
+ double _offer_filters_active(
+ const std::string& role);
+
hashmap<FrameworkID, Framework> frameworks;
struct Slave
http://git-wip-us.apache.org/repos/asf/mesos/blob/08c68dc7/src/master/allocator/mesos/metrics.cpp
----------------------------------------------------------------------
diff --git a/src/master/allocator/mesos/metrics.cpp b/src/master/allocator/mesos/metrics.cpp
index 17043d6..a36d21c 100644
--- a/src/master/allocator/mesos/metrics.cpp
+++ b/src/master/allocator/mesos/metrics.cpp
@@ -109,6 +109,10 @@ Metrics::~Metrics()
process::metrics::remove(gauge);
}
}
+
+ foreachvalue (const Gauge& gauge, offer_filters_active) {
+ process::metrics::remove(gauge);
+ }
}
@@ -163,6 +167,34 @@ void Metrics::removeQuota(const string& role)
quota_allocated.erase(role);
}
+
+void Metrics::addRole(const string& role)
+{
+ CHECK(!offer_filters_active.contains(role));
+
+ Gauge gauge(
+ "allocator/mesos/offer_filters/roles/" + role + "/active",
+ defer(allocator,
+ &HierarchicalAllocatorProcess::_offer_filters_active,
+ role));
+
+ offer_filters_active.put(role, gauge);
+
+ process::metrics::add(gauge);
+}
+
+
+void Metrics::removeRole(const string& role)
+{
+ Option<Gauge> gauge = offer_filters_active.get(role);
+
+ CHECK_SOME(gauge);
+
+ offer_filters_active.erase(role);
+
+ process::metrics::remove(gauge.get());
+}
+
} // namespace internal {
} // namespace allocator {
} // namespace master {
http://git-wip-us.apache.org/repos/asf/mesos/blob/08c68dc7/src/master/allocator/mesos/metrics.hpp
----------------------------------------------------------------------
diff --git a/src/master/allocator/mesos/metrics.hpp b/src/master/allocator/mesos/metrics.hpp
index b5f2806..06fdd16 100644
--- a/src/master/allocator/mesos/metrics.hpp
+++ b/src/master/allocator/mesos/metrics.hpp
@@ -48,6 +48,9 @@ struct Metrics
void setQuota(const std::string& role, const Quota& quota);
void removeQuota(const std::string& role);
+ void addRole(const std::string& role);
+ void removeRole(const std::string& role);
+
const process::PID<HierarchicalAllocatorProcess> allocator;
// Number of dispatch events currently waiting in the allocator process.
@@ -76,6 +79,9 @@ struct Metrics
// Gauges for the per-role quota guarantee for each resource.
hashmap<std::string, hashmap<std::string, process::metrics::Gauge>>
quota_guarantee;
+
+ // Gauges for the per-role count of active offer filters.
+ hashmap<std::string, process::metrics::Gauge> offer_filters_active;
};
} // namespace internal {
http://git-wip-us.apache.org/repos/asf/mesos/blob/08c68dc7/src/tests/hierarchical_allocator_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/hierarchical_allocator_tests.cpp b/src/tests/hierarchical_allocator_tests.cpp
index e9cfcfc..218e1b0 100644
--- a/src/tests/hierarchical_allocator_tests.cpp
+++ b/src/tests/hierarchical_allocator_tests.cpp
@@ -540,6 +540,12 @@ TEST_F(HierarchicalAllocatorTest, OfferFilter)
// Ensure the offer filter timeout is set before advancing the clock.
Clock::settle();
+ JSON::Object metrics = Metrics();
+
+ string activeOfferFilters =
+ "allocator/mesos/offer_filters/roles/" + ROLE + "/active";
+ EXPECT_EQ(1, metrics.values[activeOfferFilters]);
+
// Trigger a batch allocation.
Clock::advance(flags.allocation_interval);
Clock::settle();
@@ -557,6 +563,10 @@ TEST_F(HierarchicalAllocatorTest, OfferFilter)
AWAIT_READY(allocation);
EXPECT_EQ(framework1.id(), allocation.get().frameworkId);
EXPECT_EQ(agent1.resources(), Resources::sum(allocation.get().resources));
+
+ metrics = Metrics();
+
+ EXPECT_EQ(0, metrics.values[activeOfferFilters]);
}
@@ -2643,6 +2653,98 @@ TEST_F(HierarchicalAllocatorTest, AllocationRunTimerMetrics)
}
+// This test checks that per-role active offer filter metrics
+// are correctly reported in the metrics endpoint.
+TEST_F(HierarchicalAllocatorTest, ActiveOfferFiltersMetrics)
+{
+ // Pausing the clock is not necessary, but ensures that the test
+ // doesn't rely on the batch allocation in the allocator, which
+ // would slow down the test.
+ Clock::pause();
+
+ initialize();
+
+ SlaveInfo agent = createSlaveInfo("cpus:2;mem:1024;disk:0");
+ allocator->addSlave(agent.id(), agent, None(), agent.resources(), {});
+
+ // Register three frameworks, two of which are in the same role.
+ // For every offer the frameworks install practically indefinite
+ // offer filters.
+ Duration filterTimeout = flags.allocation_interval * 100;
+ Filters offerFilter;
+ offerFilter.set_refuse_seconds(filterTimeout.secs());
+
+ FrameworkInfo framework1 = createFrameworkInfo("roleA");
+ allocator->addFramework(framework1.id(), framework1, {});
+
+ Future<Allocation> allocation = allocations.get();
+
+ AWAIT_READY(allocation);
+ ASSERT_EQ(framework1.id(), allocation->frameworkId);
+
+ allocator->recoverResources(
+ allocation->frameworkId,
+ agent.id(),
+ allocation->resources.get(agent.id()).get(),
+ offerFilter);
+
+ JSON::Object expected;
+ expected.values = {
+ {"allocator/mesos/offer_filters/roles/roleA/active", 1},
+ };
+
+ JSON::Value metrics = Metrics();
+
+ EXPECT_TRUE(metrics.contains(expected));
+
+ FrameworkInfo framework2 = createFrameworkInfo("roleB");
+ allocator->addFramework(framework2.id(), framework2, {});
+
+ allocation = allocations.get();
+
+ AWAIT_READY(allocation);
+ ASSERT_EQ(framework2.id(), allocation->frameworkId);
+
+ allocator->recoverResources(
+ allocation->frameworkId,
+ agent.id(),
+ allocation->resources.get(agent.id()).get(),
+ offerFilter);
+
+ expected.values = {
+ {"allocator/mesos/offer_filters/roles/roleA/active", 1},
+ {"allocator/mesos/offer_filters/roles/roleB/active", 1},
+ };
+
+ metrics = Metrics();
+
+ EXPECT_TRUE(metrics.contains(expected));
+
+ FrameworkInfo framework3 = createFrameworkInfo("roleA");
+ allocator->addFramework(framework3.id(), framework3, {});
+
+ allocation = allocations.get();
+
+ AWAIT_READY(allocation);
+ ASSERT_EQ(framework3.id(), allocation->frameworkId);
+
+ allocator->recoverResources(
+ allocation->frameworkId,
+ agent.id(),
+ allocation->resources.get(agent.id()).get(),
+ offerFilter);
+
+ expected.values = {
+ {"allocator/mesos/offer_filters/roles/roleA/active", 2},
+ {"allocator/mesos/offer_filters/roles/roleB/active", 1},
+ };
+
+ metrics = Metrics();
+
+ EXPECT_TRUE(metrics.contains(expected));
+}
+
+
// This test ensures that resource allocation is done according to each role's
// weight. This is done by having six agents and three frameworks and making
// sure each framework gets the appropriate number of resources.