You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by ji...@apache.org on 2015/06/20 00:44:17 UTC
[1/3] mesos git commit: Improved the performance of DRF sorter by
caching the scalars.
Repository: mesos
Updated Branches:
refs/heads/master e02ae0b4e -> 68505cd0a
Improved the performance of DRF sorter by caching the scalars.
Review: https://reviews.apache.org/r/35664
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/ce1c6e2a
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/ce1c6e2a
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/ce1c6e2a
Branch: refs/heads/master
Commit: ce1c6e2aad748d9f999c09b9bb4897e19fc18175
Parents: 114d2aa
Author: Jie Yu <yu...@gmail.com>
Authored: Fri Jun 19 12:38:24 2015 -0700
Committer: Jie Yu <yu...@gmail.com>
Committed: Fri Jun 19 15:43:59 2015 -0700
----------------------------------------------------------------------
src/master/allocator/sorter/drf/sorter.cpp | 112 +++++++++++++-----------
src/master/allocator/sorter/drf/sorter.hpp | 23 ++++-
src/tests/sorter_tests.cpp | 55 ++++++++++--
3 files changed, 128 insertions(+), 62 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/ce1c6e2a/src/master/allocator/sorter/drf/sorter.cpp
----------------------------------------------------------------------
diff --git a/src/master/allocator/sorter/drf/sorter.cpp b/src/master/allocator/sorter/drf/sorter.cpp
index c5f4caf..12434a0 100644
--- a/src/master/allocator/sorter/drf/sorter.cpp
+++ b/src/master/allocator/sorter/drf/sorter.cpp
@@ -24,7 +24,6 @@ using std::list;
using std::set;
using std::string;
-
namespace mesos {
namespace internal {
namespace master {
@@ -47,7 +46,7 @@ void DRFSorter::add(const string& name, double weight)
Client client(name, 0, 0);
clients.insert(client);
- allocations[name] = hashmap<SlaveID, Resources>();
+ allocations[name] = Allocation();
weights[name] = weight;
}
@@ -107,7 +106,8 @@ void DRFSorter::allocated(
clients.insert(client);
}
- allocations[name][slaveId] += resources;
+ allocations[name].resources[slaveId] += resources;
+ allocations[name].scalars += resources.scalars();
// If the total resources have changed, we're going to
// recalculate all the shares, so don't bother just
@@ -131,19 +131,23 @@ void DRFSorter::update(
// Otherwise, we need to ensure we re-calculate the shares, as
// is being currently done, for safety.
- CHECK(resources[slaveId].contains(oldAllocation));
+ CHECK(total.resources[slaveId].contains(oldAllocation));
+ CHECK(total.scalars.contains(oldAllocation.scalars()));
- resources[slaveId] -= oldAllocation;
- resources[slaveId] += newAllocation;
+ total.resources[slaveId] -= oldAllocation;
+ total.resources[slaveId] += newAllocation;
- CHECK(allocations[name][slaveId].contains(oldAllocation));
+ total.scalars -= oldAllocation.scalars();
+ total.scalars += newAllocation.scalars();
- allocations[name][slaveId] -= oldAllocation;
- if (allocations[name][slaveId].empty()) {
- allocations[name].erase(slaveId);
- }
+ CHECK(allocations[name].resources[slaveId].contains(oldAllocation));
+ CHECK(allocations[name].scalars.contains(oldAllocation.scalars()));
+
+ allocations[name].resources[slaveId] -= oldAllocation;
+ allocations[name].resources[slaveId] += newAllocation;
- allocations[name][slaveId] += newAllocation;
+ allocations[name].scalars -= oldAllocation.scalars();
+ allocations[name].scalars += newAllocation.scalars();
// Just assume the total has changed, per the TODO above.
dirty = true;
@@ -152,7 +156,7 @@ void DRFSorter::update(
hashmap<SlaveID, Resources> DRFSorter::allocation(const string& name)
{
- return allocations[name];
+ return allocations[name].resources;
}
@@ -161,9 +165,11 @@ void DRFSorter::unallocated(
const SlaveID& slaveId,
const Resources& resources)
{
- allocations[name][slaveId] -= resources;
- if (allocations[name][slaveId].empty()) {
- allocations[name].erase(slaveId);
+ allocations[name].resources[slaveId] -= resources;
+ allocations[name].scalars -= resources.scalars();
+
+ if (allocations[name].resources[slaveId].empty()) {
+ allocations[name].resources.erase(slaveId);
}
if (!dirty) {
@@ -172,10 +178,11 @@ void DRFSorter::unallocated(
}
-void DRFSorter::add(const SlaveID& slaveId, const Resources& _resources)
+void DRFSorter::add(const SlaveID& slaveId, const Resources& resources)
{
- if (!_resources.empty()) {
- resources[slaveId] += _resources;
+ if (!resources.empty()) {
+ total.resources[slaveId] += resources;
+ total.scalars += resources.scalars();
// We have to recalculate all shares when the total resources
// change, but we put it off until sort is called so that if
@@ -186,15 +193,16 @@ void DRFSorter::add(const SlaveID& slaveId, const Resources& _resources)
}
-void DRFSorter::remove(const SlaveID& slaveId, const Resources& _resources)
+void DRFSorter::remove(const SlaveID& slaveId, const Resources& resources)
{
- if (!_resources.empty()) {
- CHECK(resources.contains(slaveId));
+ if (!resources.empty()) {
+ CHECK(total.resources.contains(slaveId));
- resources[slaveId] -= _resources;
+ total.resources[slaveId] -= resources;
+ total.scalars -= resources.scalars();
- if (resources[slaveId].empty()) {
- resources.erase(slaveId);
+ if (total.resources[slaveId].empty()) {
+ total.resources.erase(slaveId);
}
dirty = true;
@@ -202,12 +210,17 @@ void DRFSorter::remove(const SlaveID& slaveId, const Resources& _resources)
}
-void DRFSorter::update(const SlaveID& slaveId, const Resources& _resources)
+void DRFSorter::update(const SlaveID& slaveId, const Resources& resources)
{
- resources[slaveId] = _resources;
+ CHECK(total.scalars.contains(total.resources[slaveId].scalars()));
+
+ total.scalars -= total.resources[slaveId].scalars();
+ total.scalars += resources.scalars();
- if (resources[slaveId].empty()) {
- resources.erase(slaveId);
+ total.resources[slaveId] = resources;
+
+ if (total.resources[slaveId].empty()) {
+ total.resources.erase(slaveId);
}
dirty = true;
@@ -274,39 +287,34 @@ void DRFSorter::update(const string& name)
double DRFSorter::calculateShare(const string& name)
{
- double share = 0;
+ double share = 0.0;
// TODO(benh): This implementation of "dominant resource fairness"
// currently does not take into account resources that are not
// scalars.
- // NOTE: Summation is incorrect for non-scalars, but since we
- // only care about scalar resources, this is safe.
- Resources totalResources = Resources::sum(resources);
- Resources clientAllocation = Resources::sum(allocations[name]);
-
- // Scalar resources may be spread across multiple 'Resource'
- // objects. E.g. persistent volumes. So we first collect the names
- // of the scalar resources, before computing the totals.
- hashset<string> scalars;
- foreach (const Resource& resource, totalResources) {
- if (resource.type() == Value::SCALAR) {
- scalars.insert(resource.name());
- }
- }
+ foreach (const string& scalar, total.scalars.names()) {
+ double _total = 0.0;
- foreach (const string& scalar, scalars) {
- Option<Value::Scalar> total = totalResources.get<Value::Scalar>(scalar);
+ // NOTE: Scalar resources may be spread across multiple
+ // 'Resource' objects. E.g. persistent volumes.
+ foreach (const Resource& resource, total.scalars.get(scalar)) {
+ CHECK_EQ(resource.type(), Value::SCALAR);
+ _total += resource.scalar().value();
+ }
- if (total.isSome() && total.get().value() > 0) {
- Option<Value::Scalar> allocation =
- clientAllocation.get<Value::Scalar>(scalar);
+ if (_total > 0.0) {
+ double allocation = 0.0;
- if (allocation.isNone()) {
- allocation = Value::Scalar();
+ // NOTE: Scalar resources may be spread across multiple
+ // 'Resource' objects. E.g. persistent volumes.
+ foreach (const Resource& resource,
+ allocations[name].scalars.get(scalar)) {
+ CHECK_EQ(resource.type(), Value::SCALAR);
+ allocation += resource.scalar().value();
}
- share = std::max(share, allocation.get().value() / total.get().value());
+ share = std::max(share, allocation / _total);
}
}
http://git-wip-us.apache.org/repos/asf/mesos/blob/ce1c6e2a/src/master/allocator/sorter/drf/sorter.hpp
----------------------------------------------------------------------
diff --git a/src/master/allocator/sorter/drf/sorter.hpp b/src/master/allocator/sorter/drf/sorter.hpp
index 35dc1a4..d38925e 100644
--- a/src/master/allocator/sorter/drf/sorter.hpp
+++ b/src/master/allocator/sorter/drf/sorter.hpp
@@ -121,14 +121,29 @@ private:
// A set of Clients (names and shares) sorted by share.
std::set<Client, DRFComparator> clients;
- // Maps client names to the resources they have been allocated.
- hashmap<std::string, hashmap<SlaveID, Resources>> allocations;
-
// Maps client names to the weights that should be applied to their shares.
hashmap<std::string, double> weights;
// Total resources.
- hashmap<SlaveID, Resources> resources;
+ struct Total {
+ hashmap<SlaveID, Resources> resources;
+
+ // NOTE: Scalars can be safely aggregated across slaves. We keep
+ // that to speed up the calculation of shares. See MESOS-2891 for
+ // the reasons why we want to do that.
+ Resources scalars;
+ } total;
+
+ // Allocation for a client.
+ struct Allocation {
+ hashmap<SlaveID, Resources> resources;
+
+ // Similarly, we aggregated scalars across slaves. See note above.
+ Resources scalars;
+ };
+
+ // Maps client names to the resources they have been allocated.
+ hashmap<std::string, Allocation> allocations;
};
} // namespace allocator {
http://git-wip-us.apache.org/repos/asf/mesos/blob/ce1c6e2a/src/tests/sorter_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/sorter_tests.cpp b/src/tests/sorter_tests.cpp
index 435e0bf..4013886 100644
--- a/src/tests/sorter_tests.cpp
+++ b/src/tests/sorter_tests.cpp
@@ -281,12 +281,12 @@ TEST(SorterTest, MultipleSlaves)
}
-// We aggregate resources from multiple slaves into the sorter.
-// Since non-scalar resources don't aggregate well across slaves,
-// we need to keep track of the SlaveIDs of the resources.
-// This tests that no resources vanish in the process of aggregation
-// by performing a updates from unreserved to reserved resources.
-TEST(SorterTest, MultipleSlaveUpdates)
+// We aggregate resources from multiple slaves into the sorter. Since
+// non-scalar resources don't aggregate well across slaves, we need to
+// keep track of the SlaveIDs of the resources. This tests that no
+// resources vanish in the process of aggregation by performing update
+// allocations from unreserved to reserved resources.
+TEST(SorterTest, MultipleSlavesUpdateAllocation)
{
DRFSorter sorter;
@@ -366,6 +366,49 @@ TEST(SorterTest, UpdateTotal)
}
+// Similar to the above 'UpdateTotal' test, but tests the scenario
+// when there are multiple slaves.
+TEST(SorterTest, MultipleSlavesUpdateTotal)
+{
+ DRFSorter sorter;
+
+ SlaveID slaveA;
+ slaveA.set_value("slaveA");
+
+ SlaveID slaveB;
+ slaveB.set_value("slaveB");
+
+ sorter.add("a");
+ sorter.add("b");
+
+ sorter.add(slaveA, Resources::parse("cpus:5;mem:50").get());
+ sorter.add(slaveB, Resources::parse("cpus:5;mem:50").get());
+
+ // Dominant share of "a" is 0.2 (cpus).
+ sorter.allocated(
+ "a", slaveA, Resources::parse("cpus:2;mem:1").get());
+
+ // Dominant share of "b" is 0.1 (cpus).
+ sorter.allocated(
+ "b", slaveB, Resources::parse("cpus:1;mem:3").get());
+
+ list<string> sorted = sorter.sort();
+ ASSERT_EQ(2u, sorted.size());
+ EXPECT_EQ("b", sorted.front());
+ EXPECT_EQ("a", sorted.back());
+
+ // Update the total resources of slaveA.
+ sorter.update(slaveA, Resources::parse("cpus:95;mem:50").get());
+
+ // Now the dominant share of "a" is 0.02 (cpus) and "b" is 0.03
+ // (mem), which should change the sort order.
+ sorted = sorter.sort();
+ ASSERT_EQ(2u, sorted.size());
+ EXPECT_EQ("a", sorted.front());
+ EXPECT_EQ("b", sorted.back());
+}
+
+
// This test verifies that revocable resources are properly accounted
// for in the DRF sorter.
TEST(SorterTest, RevocableResources)
[2/3] mesos git commit: Added a helper in Resources to get all scalar
resources.
Posted by ji...@apache.org.
Added a helper in Resources to get all scalar resources.
Review: https://reviews.apache.org/r/35663
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/114d2aa5
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/114d2aa5
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/114d2aa5
Branch: refs/heads/master
Commit: 114d2aa568284eba98dad60f8265c573112bad49
Parents: e02ae0b
Author: Jie Yu <yu...@gmail.com>
Authored: Fri Jun 19 12:37:27 2015 -0700
Committer: Jie Yu <yu...@gmail.com>
Committed: Fri Jun 19 15:43:59 2015 -0700
----------------------------------------------------------------------
include/mesos/resources.hpp | 3 +++
src/common/resources.cpp | 8 ++++++++
2 files changed, 11 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/114d2aa5/include/mesos/resources.hpp
----------------------------------------------------------------------
diff --git a/include/mesos/resources.hpp b/include/mesos/resources.hpp
index 0ccc337..d4d5caf 100644
--- a/include/mesos/resources.hpp
+++ b/include/mesos/resources.hpp
@@ -248,6 +248,9 @@ public:
// Get resources of the given name.
Resources get(const std::string& name) const;
+ // Get all the resources that are scalars.
+ Resources scalars() const;
+
// Get the set of unique resource names.
std::set<std::string> names() const;
http://git-wip-us.apache.org/repos/asf/mesos/blob/114d2aa5/src/common/resources.cpp
----------------------------------------------------------------------
diff --git a/src/common/resources.cpp b/src/common/resources.cpp
index 3b79243..eb5476a 100644
--- a/src/common/resources.cpp
+++ b/src/common/resources.cpp
@@ -949,6 +949,14 @@ Resources Resources::get(const string& name) const
}
+Resources Resources::scalars() const
+{
+ return filter([=](const Resource& resource) {
+ return resource.type() == Value::SCALAR;
+ });
+}
+
+
set<string> Resources::names() const
{
set<string> result;
[3/3] mesos git commit: Fixed a bug in test filter that prevent some
tests from being launched.
Posted by ji...@apache.org.
Fixed a bug in test filter that prevent some tests from being launched.
Review: https://reviews.apache.org/r/35671
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/68505cd0
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/68505cd0
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/68505cd0
Branch: refs/heads/master
Commit: 68505cd0a478a96393ca988e74f99460333f5e45
Parents: ce1c6e2
Author: Jie Yu <yu...@gmail.com>
Authored: Fri Jun 19 15:20:07 2015 -0700
Committer: Jie Yu <yu...@gmail.com>
Committed: Fri Jun 19 15:44:00 2015 -0700
----------------------------------------------------------------------
src/tests/environment.cpp | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/68505cd0/src/tests/environment.cpp
----------------------------------------------------------------------
diff --git a/src/tests/environment.cpp b/src/tests/environment.cpp
index 2b6bc0c..f111a77 100644
--- a/src/tests/environment.cpp
+++ b/src/tests/environment.cpp
@@ -236,8 +236,10 @@ public:
bool disable(const ::testing::TestInfo* test) const
{
#ifdef WITH_NETWORK_ISOLATOR
- // PortMappingIsolatorProcess doesn't suport multiple slaves.
- if (matches(test, "MultipleSlaves")) {
+ // PortMappingIsolatorProcess doesn't suport test
+ // 'SlaveRecoveryTest.MultipleSlaves'.
+ if (matches(test, "SlaveRecoveryTest") &&
+ matches(test, "MultipleSlaves")) {
return true;
}
#endif