Repository: mesos Updated Branches: refs/heads/master aded41aec -> 9e2f9a240
Added an performance benchmark for master `GetState` v1 api. This test is based on the master failover benchmark. Note that it does not include executors for now. Review: https://reviews.apache.org/r/64969/ Project: http://git-wip-us.apache.org/repos/asf/mesos/repo Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/9e2f9a24 Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/9e2f9a24 Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/9e2f9a24 Branch: refs/heads/master Commit: 9e2f9a2401a7665872f9cb2d994ca5013cd852c9 Parents: aded41a Author: Meng Zhu <[email protected]> Authored: Tue Jan 16 17:19:53 2018 -0800 Committer: Benjamin Mahler <[email protected]> Committed: Tue Jan 16 17:37:21 2018 -0800 ---------------------------------------------------------------------- src/tests/master_benchmarks.cpp | 151 ++++++++++++++++++++++++++++++++++- 1 file changed, 149 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mesos/blob/9e2f9a24/src/tests/master_benchmarks.cpp ---------------------------------------------------------------------- diff --git a/src/tests/master_benchmarks.cpp b/src/tests/master_benchmarks.cpp index 7d69588..80de24d 100644 --- a/src/tests/master_benchmarks.cpp +++ b/src/tests/master_benchmarks.cpp @@ -17,6 +17,7 @@ #include <list> #include <string> #include <tuple> +#include <vector> #include <mesos/resources.hpp> #include <mesos/version.hpp> @@ -34,6 +35,8 @@ #include "tests/mesos.hpp" +namespace http = process::http; + using process::await; using process::Clock; using process::Failure; @@ -53,6 +56,7 @@ using std::make_tuple; using std::string; using std::tie; using std::tuple; +using std::vector; using testing::WithParamInterface; @@ -315,8 +319,6 @@ TEST_P(MasterFailover_BENCHMARK_Test, AgentReregistrationDelay) list<Future<Nothing>> reregistered; - cout << "Starting reregistration for all agents" << endl; - // Measure the time for all agents to receive `SlaveReregisteredMessage`. Stopwatch watch; watch.start(); @@ -337,6 +339,151 @@ TEST_P(MasterFailover_BENCHMARK_Test, AgentReregistrationDelay) << watch.elapsed() << endl; } + +class MasterStateQuery_BENCHMARK_Test + : public MesosTest, + public WithParamInterface<tuple< + size_t, size_t, size_t, size_t, size_t>> {}; + + +INSTANTIATE_TEST_CASE_P( + AgentFrameworkTaskCountContentType, + MasterStateQuery_BENCHMARK_Test, + ::testing::Values( + make_tuple(1000, 5, 2, 5, 2), + make_tuple(10000, 5, 2, 5, 2), + make_tuple(20000, 5, 2, 5, 2), + make_tuple(40000, 5, 2, 5, 2))); + + +// This test measures the performance of the `master::call::GetState` +// v1 api (and also measures master v0 '/state' endpoint as the +// baseline). We set up a lot of master state from artificial agents +// similar to the master failover benchmark. +TEST_P(MasterStateQuery_BENCHMARK_Test, GetState) +{ + size_t agentCount; + size_t frameworksPerAgent; + size_t tasksPerFramework; + size_t completedFrameworksPerAgent; + size_t tasksPerCompletedFramework; + + tie(agentCount, + frameworksPerAgent, + tasksPerFramework, + completedFrameworksPerAgent, + tasksPerCompletedFramework) = GetParam(); + + // Disable authentication to avoid the overhead, since we don't care about + // it in this test. + master::Flags masterFlags = CreateMasterFlags(); + masterFlags.authenticate_agents = false; + + Try<Owned<cluster::Master>> master = StartMaster(masterFlags); + ASSERT_SOME(master); + + vector<Owned<TestSlave>> slaves; + + for (size_t i = 0; i < agentCount; i++) { + SlaveID slaveId; + slaveId.set_value("agent" + stringify(i)); + + slaves.push_back(Owned<TestSlave>(new TestSlave( + master.get()->pid, + slaveId, + frameworksPerAgent, + tasksPerFramework, + completedFrameworksPerAgent, + tasksPerCompletedFramework))); + } + + cout << "Test setup: " + << agentCount << " agents with a total of " + << frameworksPerAgent * tasksPerFramework * agentCount + << " running tasks and " + << completedFrameworksPerAgent * tasksPerCompletedFramework * agentCount + << " completed tasks" << endl; + + list<Future<Nothing>> reregistered; + + foreach (const Owned<TestSlave>& slave, slaves) { + reregistered.push_back(slave->reregister()); + } + + // Wait all agents to finish reregistration. + await(reregistered).await(); + + Clock::pause(); + Clock::settle(); + Clock::resume(); + + Stopwatch watch; + watch.start(); + + // We first measure v0 "state" endpoint performance as the baseline. + Future<http::Response> v0Response = http::get( + master.get()->pid, + "state", + None(), + createBasicAuthHeaders(DEFAULT_CREDENTIAL)); + + v0Response.await(); + + watch.stop(); + + ASSERT_EQ(v0Response->status, http::OK().status); + + cout << "v0 '/state' response took " << watch.elapsed() << endl; + + // Helper function to post a request to '/api/v1' master endpoint + // and return the response. + auto post = []( + const process::PID<master::Master>& pid, + const v1::master::Call& call, + const ContentType& contentType) + { + http::Headers headers = createBasicAuthHeaders(DEFAULT_CREDENTIAL); + headers["Accept"] = stringify(contentType); + + return http::post( + pid, + "api/v1", + headers, + serialize(contentType, call), + stringify(contentType)); + }; + + // We measure both JSON and protobuf formats. + const ContentType contentTypes[] = + { ContentType::PROTOBUF, ContentType::JSON }; + + for (ContentType contentType : contentTypes){ + v1::master::Call v1Call; + v1Call.set_type(v1::master::Call::GET_STATE); + + watch.start(); + + Future<http::Response> response = + post(master.get()->pid, v1Call, contentType); + + response.await(); + + watch.stop(); + + ASSERT_EQ(response->status, http::OK().status); + + Future<v1::master::Response> v1Response = + deserialize<v1::master::Response>(contentType, response->body); + + ASSERT_TRUE(v1Response->IsInitialized()); + EXPECT_EQ(v1::master::Response::GET_STATE, v1Response->type()); + + cout << "v1 'master::call::GetState' " + << contentType << " response took " << watch.elapsed() << endl; + } +} + + } // namespace tests { } // namespace internal { } // namespace mesos {
