Repository: kudu
Updated Branches:
  refs/heads/branch-1.6.x 0c5628f6b -> 8d9eff378


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 <t...@apache.org>
Tested-by: Kudu Jenkins
(cherry picked from commit f8d18693546cd518c8873b7a5f4c08579f85199a)
Reviewed-on: http://gerrit.cloudera.org:8080/9323
Reviewed-by: Will Berkeley <wdberke...@gmail.com>


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

Branch: refs/heads/branch-1.6.x
Commit: 8d9eff37809c7a21b79142b558b0d4ec9ee3fff3
Parents: 0c5628f
Author: zhangzhen [张震] <zhangz...@xiaomi.com>
Authored: Thu Dec 21 16:32:19 2017 +0800
Committer: Will Berkeley <wdberke...@gmail.com>
Committed: Thu Feb 22 21:23:14 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/8d9eff37/src/kudu/tablet/tablet.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tablet/tablet.cc b/src/kudu/tablet/tablet.cc
index 5e0c805..4f3231f 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"
@@ -1873,7 +1874,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) {
@@ -1887,6 +1888,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()) {
@@ -1894,11 +1902,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/8d9eff37/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/8d9eff37/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();

Reply via email to