You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kudu.apache.org by aw...@apache.org on 2018/01/20 01:18:47 UTC

[2/4] kudu git commit: KUDU-2238. DMS not flush under memory pressure.

KUDU-2238. DMS not flush under memory pressure.

When we choose DMS to flush, now we always pick the DMS with
highest log retention. However, as KUDU-2238 shows, in some cases
DMS with highest log retention may only consume little memory, and
other DMSs may consume much more memory, but get no chance to be
flushed, even under memory pressure.

This patch gives the ability to take memory consumption into
consideration when we choose DMS.

Change-Id: I0c04d76aa0e3888352dc56eeb493a5437ef47e42
Reviewed-on: http://gerrit.cloudera.org:8080/8904
Reviewed-by: Todd Lipcon <to...@apache.org>
Tested-by: Kudu Jenkins


Project: http://git-wip-us.apache.org/repos/asf/kudu/repo
Commit: http://git-wip-us.apache.org/repos/asf/kudu/commit/f8d18693
Tree: http://git-wip-us.apache.org/repos/asf/kudu/tree/f8d18693
Diff: http://git-wip-us.apache.org/repos/asf/kudu/diff/f8d18693

Branch: refs/heads/master
Commit: f8d18693546cd518c8873b7a5f4c08579f85199a
Parents: b6889d7
Author: zhangzhen [张震] <zh...@xiaomi.com>
Authored: Thu Dec 21 16:32:19 2017 +0800
Committer: Todd Lipcon <to...@apache.org>
Committed: Fri Jan 19 00:33:37 2018 +0000

----------------------------------------------------------------------
 src/kudu/tablet/tablet.cc                | 21 ++++++++++++++++-----
 src/kudu/tablet/tablet.h                 |  2 +-
 src/kudu/tablet/tablet_replica_mm_ops.cc |  3 +--
 3 files changed, 18 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/kudu/blob/f8d18693/src/kudu/tablet/tablet.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tablet/tablet.cc b/src/kudu/tablet/tablet.cc
index 287d64c..6812bca 100644
--- a/src/kudu/tablet/tablet.cc
+++ b/src/kudu/tablet/tablet.cc
@@ -86,6 +86,7 @@
 #include "kudu/util/maintenance_manager.h"
 #include "kudu/util/metrics.h"
 #include "kudu/util/monotime.h"
+#include "kudu/util/process_memory.h"
 #include "kudu/util/slice.h"
 #include "kudu/util/status_callback.h"
 #include "kudu/util/throttler.h"
@@ -1876,7 +1877,7 @@ void Tablet::GetInfoForBestDMSToFlush(const ReplaySizeMap& replay_size_map,
   }
 }
 
-Status Tablet::FlushDMSWithHighestRetention(const ReplaySizeMap& replay_size_map) const {
+Status Tablet::FlushBestDMS(const ReplaySizeMap &replay_size_map) const {
   RETURN_IF_STOPPED_OR_CHECK_STATE(kOpen);
   shared_ptr<RowSet> rowset = FindBestDMSToFlush(replay_size_map);
   if (rowset) {
@@ -1890,6 +1891,13 @@ shared_ptr<RowSet> Tablet::FindBestDMSToFlush(const ReplaySizeMap& replay_size_m
   GetComponents(&comps);
   int64_t mem_size = 0;
   int64_t retention_size = 0;
+  double max_score = 0;
+  double mem_weight = 0;
+  // If system is under memory pressure, we use the percentage of the hard limit consumed
+  // as mem_weight, so the tighter memory, the higher weight. Otherwise just left the
+  // mem_weight to 0.
+  process_memory::UnderMemoryPressure(&mem_weight);
+
   shared_ptr<RowSet> best_dms;
   for (const shared_ptr<RowSet> &rowset : comps->rowsets->all_rowsets()) {
     if (rowset->DeltaMemStoreEmpty()) {
@@ -1897,11 +1905,14 @@ shared_ptr<RowSet> Tablet::FindBestDMSToFlush(const ReplaySizeMap& replay_size_m
     }
     int64_t size = GetReplaySizeForIndex(rowset->MinUnflushedLogIndex(),
                                          replay_size_map);
-    if ((size > retention_size) ||
-        (size == retention_size &&
-         (rowset->DeltaMemStoreSize() > mem_size))) {
-      mem_size = rowset->DeltaMemStoreSize();
+    int64_t mem = rowset->DeltaMemStoreSize();
+    double score = mem * mem_weight + size * (100 - mem_weight);
+
+    if ((score > max_score) ||
+        (score > max_score - 1 && mem > mem_size)) {
+      max_score = score;
       retention_size = size;
+      mem_size = mem;
       best_dms = rowset;
     }
   }

http://git-wip-us.apache.org/repos/asf/kudu/blob/f8d18693/src/kudu/tablet/tablet.h
----------------------------------------------------------------------
diff --git a/src/kudu/tablet/tablet.h b/src/kudu/tablet/tablet.h
index 38638c0..ce193e5 100644
--- a/src/kudu/tablet/tablet.h
+++ b/src/kudu/tablet/tablet.h
@@ -278,7 +278,7 @@ class Tablet {
                                 int64_t* mem_size, int64_t* replay_size) const;
 
   // Flushes the DMS with the highest retention.
-  Status FlushDMSWithHighestRetention(const ReplaySizeMap& replay_size_map) const;
+  Status FlushBestDMS(const ReplaySizeMap &replay_size_map) const;
 
   // Flush only the biggest DMS
   Status FlushBiggestDMS();

http://git-wip-us.apache.org/repos/asf/kudu/blob/f8d18693/src/kudu/tablet/tablet_replica_mm_ops.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tablet/tablet_replica_mm_ops.cc b/src/kudu/tablet/tablet_replica_mm_ops.cc
index 41f04a3..d3edc70 100644
--- a/src/kudu/tablet/tablet_replica_mm_ops.cc
+++ b/src/kudu/tablet/tablet_replica_mm_ops.cc
@@ -194,14 +194,13 @@ void FlushDeltaMemStoresOp::Perform() {
     return;
   }
   Tablet* tablet = tablet_replica_->tablet();
-  Status s = tablet->FlushDMSWithHighestRetention(max_idx_to_replay_size);
+  Status s = tablet->FlushBestDMS(max_idx_to_replay_size);
   if (PREDICT_FALSE(!s.ok())) {
     LOG(WARNING) << tablet->LogPrefix() << "failed to flush DMS: " << s.ToString();
     CHECK(tablet->HasBeenStopped()) << "FlushDMS failure is only allowed if the "
                                        "tablet is stopped first";
     return;
   }
-
   {
     std::lock_guard<simple_spinlock> l(lock_);
     time_since_flush_.start();