kudu-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From aw...@apache.org
Subject [kudu] branch master updated: KUDU-2711 (part 1): add a benchmark for GetTableLocations
Date Thu, 07 Mar 2019 23:15:19 GMT
This is an automated email from the ASF dual-hosted git repository.

awong pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/kudu.git


The following commit(s) were added to refs/heads/master by this push:
     new c74e678  KUDU-2711 (part 1): add a benchmark for GetTableLocations
c74e678 is described below

commit c74e67830ea88942029433aa6ebacc45b924369d
Author: Todd Lipcon <todd@apache.org>
AuthorDate: Tue Feb 26 12:25:12 2019 -0800

    KUDU-2711 (part 1): add a benchmark for GetTableLocations
    
    This adds a simple benchmark which spawns a bunch of threads which
    hammer GetTableLocations in a loop. Upon completion, it dumps out
    a histogram.
    
    Change-Id: Ic1643638d82b7697d20ea960592c8b70c30ac7bd
    Reviewed-on: http://gerrit.cloudera.org:8080/12613
    Reviewed-by: Adar Dembo <adar@cloudera.com>
    Tested-by: Will Berkeley <wdberkeley@gmail.com>
---
 src/kudu/integration-tests/CMakeLists.txt          |  2 +-
 src/kudu/integration-tests/linked_list-test-util.h | 16 +----
 .../integration-tests/table_locations-itest.cc     | 82 ++++++++++++++++++++++
 src/kudu/rpc/rpc-bench.cc                          | 13 ++--
 src/kudu/util/hdr_histogram.cc                     | 19 +++++
 src/kudu/util/hdr_histogram.h                      |  9 ++-
 6 files changed, 113 insertions(+), 28 deletions(-)

diff --git a/src/kudu/integration-tests/CMakeLists.txt b/src/kudu/integration-tests/CMakeLists.txt
index 63452cc..18d7db4 100644
--- a/src/kudu/integration-tests/CMakeLists.txt
+++ b/src/kudu/integration-tests/CMakeLists.txt
@@ -106,7 +106,7 @@ ADD_KUDU_TEST(security-itest)
 ADD_KUDU_TEST(security-master-auth-itest)
 ADD_KUDU_TEST(security-unknown-tsk-itest PROCESSORS 4)
 ADD_KUDU_TEST(stop_tablet-itest PROCESSORS 4)
-ADD_KUDU_TEST(table_locations-itest
+ADD_KUDU_TEST(table_locations-itest RUN_SERIAL true
   DATA_FILES ../scripts/first_argument.sh)
 ADD_KUDU_TEST(tablet_copy-itest NUM_SHARDS 6 PROCESSORS 4)
 ADD_KUDU_TEST(tablet_copy_client_session-itest)
diff --git a/src/kudu/integration-tests/linked_list-test-util.h b/src/kudu/integration-tests/linked_list-test-util.h
index 1fb71fa..e51fc27 100644
--- a/src/kudu/integration-tests/linked_list-test-util.h
+++ b/src/kudu/integration-tests/linked_list-test-util.h
@@ -572,21 +572,7 @@ void LinkedListTester::DumpInsertHistogram(bool print_flags) {
   }
   cout << "Note: each insert is a batch of " << num_chains_ << " rows."
<< endl;
   cout << "------------------------------------------------------------" << endl;
-  cout << "Count: " << h->TotalCount() << endl;
-  cout << "Mean: " << h->MeanValue() << endl;
-  cout << "Percentiles:" << endl;
-  cout << "   0%  (min) = " << h->MinValue() << endl;
-  cout << "  25%        = " << h->ValueAtPercentile(25) << endl;
-  cout << "  50%  (med) = " << h->ValueAtPercentile(50) << endl;
-  cout << "  75%        = " << h->ValueAtPercentile(75) << endl;
-  cout << "  95%        = " << h->ValueAtPercentile(95) << endl;
-  cout << "  99%        = " << h->ValueAtPercentile(99) << endl;
-  cout << "  99.9%      = " << h->ValueAtPercentile(99.9) << endl;
-  cout << "  99.99%     = " << h->ValueAtPercentile(99.99) << endl;
-  cout << "  100% (max) = " << h->MaxValue() << endl;
-  if (h->MaxValue() >= h->highest_trackable_value()) {
-    cout << "*NOTE: some values were greater than highest trackable value" <<
endl;
-  }
+  h->DumpHumanReadable(&std::cout);
 }
 
 // Verify that the given sorted vector does not contain any duplicate entries.
diff --git a/src/kudu/integration-tests/table_locations-itest.cc b/src/kudu/integration-tests/table_locations-itest.cc
index 13a516a..1ec6126 100644
--- a/src/kudu/integration-tests/table_locations-itest.cc
+++ b/src/kudu/integration-tests/table_locations-itest.cc
@@ -15,12 +15,16 @@
 // specific language governing permissions and limitations
 // under the License.
 
+#include <atomic>
 #include <memory>
 #include <string>
+#include <thread>
 #include <utility>
 #include <vector>
 
+#include <gflags/gflags.h>
 #include <gflags/gflags_declare.h>
+#include <glog/logging.h>
 #include <gtest/gtest.h>
 
 #include "kudu/common/common.pb.h"
@@ -29,13 +33,17 @@
 #include "kudu/common/schema.h"
 #include "kudu/common/wire_protocol.h"
 #include "kudu/common/wire_protocol.pb.h"
+#include "kudu/gutil/ref_counted.h"
 #include "kudu/gutil/strings/substitute.h"
+#include "kudu/master/master.h"
 #include "kudu/master/master.pb.h"
 #include "kudu/master/master.proxy.h"
 #include "kudu/master/mini_master.h"
 #include "kudu/mini-cluster/internal_mini_cluster.h"
 #include "kudu/rpc/messenger.h"
 #include "kudu/rpc/rpc_controller.h"
+#include "kudu/util/hdr_histogram.h"
+#include "kudu/util/metrics.h"
 #include "kudu/util/monotime.h"
 #include "kudu/util/net/sockaddr.h"
 #include "kudu/util/path_util.h"
@@ -57,6 +65,12 @@ using std::unique_ptr;
 using std::vector;
 
 DECLARE_string(location_mapping_cmd);
+DECLARE_int32(max_create_tablets_per_ts);
+METRIC_DECLARE_histogram(handler_latency_kudu_master_MasterService_GetTableLocations);
+
+DEFINE_int32(benchmark_runtime_secs, 5, "Number of seconds to run the benchmark");
+DEFINE_int32(benchmark_num_threads, 16, "Number of threads to run the benchmark");
+DEFINE_int32(benchmark_num_tablets, 60, "Number of tablets to create");
 
 namespace kudu {
 namespace master {
@@ -72,6 +86,7 @@ class TableLocationsTest : public KuduTest {
   void SetUp() override {
     KuduTest::SetUp();
 
+    FLAGS_max_create_tablets_per_ts = 1000;
     SetUpConfig();
 
     InternalMiniClusterOptions opts;
@@ -139,6 +154,7 @@ void TableLocationsTest::CheckMasterTableCreation(const string &table_name,
   GetTableLocationsRequestPB req;
   GetTableLocationsResponsePB resp;
   RpcController controller;
+  req.set_max_returned_locations(1000);
   req.mutable_table()->set_table_name(table_name);
 
   for (int i = 1; ; i++) {
@@ -306,5 +322,71 @@ TEST_F(TableLocationsWithTSLocationTest, TestGetTSLocation) {
   }
 }
 
+TEST_F(TableLocationsTest, GetTableLocationsBenchmark) {
+  const int kNumSplits = FLAGS_benchmark_num_tablets - 1;
+  const int kNumThreads = FLAGS_benchmark_num_threads;
+  const auto kRuntime = MonoDelta::FromSeconds(FLAGS_benchmark_runtime_secs);
+
+  const string table_name = "test";
+  Schema schema({ ColumnSchema("key", INT32) }, 1);
+  KuduPartialRow row(&schema);
+
+  vector<KuduPartialRow> splits(kNumSplits, row);
+  for (int i = 0; i < kNumSplits; i++) {
+    ASSERT_OK(splits[i].SetInt32(0, i*1000));
+  }
+
+  ASSERT_OK(CreateTable(table_name, schema, splits));
+
+  NO_FATALS(CheckMasterTableCreation(table_name, kNumSplits + 1));
+
+  // Make one proxy per thread, so each thread gets its own messenger and
+  // reactor. If there were only one messenger, then only one reactor thread
+  // would be used for the connection to the master, so this benchmark would
+  // probably be testing the serialization and network code rather than the
+  // master GTL code.
+  vector<unique_ptr<MasterServiceProxy>> proxies;
+  proxies.reserve(kNumThreads);
+  for (int i = 0; i < kNumThreads; i++) {
+    MessengerBuilder bld("Client");
+    bld.set_num_reactors(1);
+    shared_ptr<Messenger> msg;
+    ASSERT_OK(bld.Build(&msg));
+    const auto& addr = cluster_->mini_master()->bound_rpc_addr();
+    proxies.emplace_back(new MasterServiceProxy(std::move(msg), addr, addr.host()));
+  }
+
+  std::atomic<bool> stop { false };
+  vector<std::thread> threads;
+  threads.reserve(kNumThreads);
+  for (int i = 0; i < kNumThreads; i++) {
+    threads.emplace_back([&, i]() {
+        while (!stop) {
+          GetTableLocationsRequestPB req;
+          GetTableLocationsResponsePB resp;
+          RpcController controller;
+          req.mutable_table()->set_table_name(table_name);
+          req.set_max_returned_locations(1000);
+          CHECK_OK(proxies[i]->GetTableLocations(req, &resp, &controller));
+          CHECK_EQ(resp.tablet_locations_size(), kNumSplits + 1);
+        }
+      });
+  }
+
+  SleepFor(kRuntime);
+  stop = true;
+  for (auto& t : threads) {
+    t.join();
+  }
+
+  const auto& ent = cluster_->mini_master()->master()->metric_entity();
+  auto hist = METRIC_handler_latency_kudu_master_MasterService_GetTableLocations
+      .Instantiate(ent);
+
+  cluster_->Shutdown();
+
+  hist->histogram()->DumpHumanReadable(&LOG(INFO));
+}
+
 } // namespace master
 } // namespace kudu
diff --git a/src/kudu/rpc/rpc-bench.cc b/src/kudu/rpc/rpc-bench.cc
index 0331e8b..a825900 100644
--- a/src/kudu/rpc/rpc-bench.cc
+++ b/src/kudu/rpc/rpc-bench.cc
@@ -126,15 +126,10 @@ class RpcBench : public RpcTestBase {
     LOG(INFO) << "User CPU per req: " << user_cpu_micros_per_req << "us";
     LOG(INFO) << "Sys CPU per req:  " << sys_cpu_micros_per_req << "us";
     LOG(INFO) << "Ctx Sw. per req:  " << csw_per_req;
-    LOG(INFO) << "Server Reactor load (mean):     "
-              << reactor_load.MeanValue() << "%";
-    LOG(INFO) << "Server Reactor load (95p):      "
-              << reactor_load.ValueAtPercentile(95) << "%";
-    LOG(INFO) << "Server Reactor Latency (mean):  "
-              << reactor_latency.MeanValue() << "us";
-    LOG(INFO) << "Server Reactor Latency (95p):   "
-              << reactor_latency.ValueAtPercentile(95) << "us";
-
+    LOG(INFO) << "Server reactor load histogram";
+    reactor_load.DumpHumanReadable(&LOG(INFO));
+    LOG(INFO) << "Server reactor latency histogram";
+    reactor_latency.DumpHumanReadable(&LOG(INFO));
   }
 
  protected:
diff --git a/src/kudu/util/hdr_histogram.cc b/src/kudu/util/hdr_histogram.cc
index 4907444..7e1f1ff 100644
--- a/src/kudu/util/hdr_histogram.cc
+++ b/src/kudu/util/hdr_histogram.cc
@@ -42,6 +42,7 @@ using base::subtle::NoBarrier_Store;
 using base::subtle::NoBarrier_Load;
 using base::subtle::NoBarrier_CompareAndSwap;
 using strings::Substitute;
+using std::endl;
 
 namespace kudu {
 
@@ -324,6 +325,24 @@ uint64_t HdrHistogram::ValueAtPercentile(double percentile) const {
   return 0;
 }
 
+void HdrHistogram::DumpHumanReadable(std::ostream* out) const {
+  *out << "Count: " << TotalCount() << endl;
+  *out << "Mean: " << MeanValue() << endl;
+  *out << "Percentiles:" << endl;
+  *out << "   0%  (min) = " << MinValue() << endl;
+  *out << "  25%        = " << ValueAtPercentile(25) << endl;
+  *out << "  50%  (med) = " << ValueAtPercentile(50) << endl;
+  *out << "  75%        = " << ValueAtPercentile(75) << endl;
+  *out << "  95%        = " << ValueAtPercentile(95) << endl;
+  *out << "  99%        = " << ValueAtPercentile(99) << endl;
+  *out << "  99.9%      = " << ValueAtPercentile(99.9) << endl;
+  *out << "  99.99%     = " << ValueAtPercentile(99.99) << endl;
+  *out << "  100% (max) = " << MaxValue() << endl;
+  if (MaxValue() >= highest_trackable_value()) {
+    *out << "*NOTE: some values were greater than highest trackable value" <<
endl;
+  }
+}
+
 ///////////////////////////////////////////////////////////////////////
 // AbstractHistogramIterator
 ///////////////////////////////////////////////////////////////////////
diff --git a/src/kudu/util/hdr_histogram.h b/src/kudu/util/hdr_histogram.h
index 14b5e95..934875b 100644
--- a/src/kudu/util/hdr_histogram.h
+++ b/src/kudu/util/hdr_histogram.h
@@ -48,7 +48,8 @@
 // tracked value (1 hour), it would still maintain a resolution of 3.6 seconds
 // (or better).
 
-#include <stdint.h>
+#include <cstdint>
+#include <iosfwd>
 
 #include "kudu/gutil/atomicops.h"
 #include "kudu/gutil/gscoped_ptr.h"
@@ -159,14 +160,16 @@ class HdrHistogram {
   uint64_t ValueAtPercentile(double percentile) const;
 
   // Get the percentile at a given value
-  // TODO: implement
+  // TODO(mpercy): implement
   // double PercentileAtOrBelowValue(uint64_t value) const;
 
   // Get the count of recorded values within a range of value levels.
   // (inclusive to within the histogram's resolution)
-  // TODO: implement
+  // TODO(mpercy): implement
   //uint64_t CountBetweenValues(uint64_t low_value, uint64_t high_value) const;
 
+  // Dump a formatted, multiline string describing this histogram to 'out'.
+  void DumpHumanReadable(std::ostream* out) const;
  private:
   friend class AbstractHistogramIterator;
 


Mime
View raw message