]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
osd/ReplicatedPG: fix promotion recency logic
authorSage Weil <sage@redhat.com>
Wed, 25 Nov 2015 19:39:08 +0000 (14:39 -0500)
committerSage Weil <sage@redhat.com>
Wed, 25 Nov 2015 19:40:36 +0000 (14:40 -0500)
Recency is defined as how many of the last N hitsets an object
must appear in in order to be promoted.  The previous logic did
nothing of the sort... it checked for the object in any one of
the last N hitsets, which led to way to many promotions and killed
any chance of the cache performing properly.

While we are here, we can simplify the code to drop the max_in_*
fields (no longer necessary).

Note that we may still want a notion of 'temperature' that does
tolerate the object missing in one of the recent hitsets.. but
that would be different than recency, and should probably be
modeled after the eviction temperature model.

Backport: infernalis, hammer
Reported-by: Nick Fisk <nick@fisk.me.uk>
Signed-off-by: Sage Weil <sage@redhat.com>
src/osd/ReplicatedPG.cc

index 64c77a4850b7e0d651c22e1d2798588f0bac715e..1b1f5c5df832e9bc8d915f09fd6e878d98dac019 100644 (file)
@@ -2254,33 +2254,28 @@ bool ReplicatedPG::maybe_promote(ObjectContextRef obc,
     }
     break;
   default:
-    if (in_hit_set) {
-      promote_object(obc, missing_oid, oloc, promote_op);
-    } else {
-      // Check if in other hit sets
-      map<time_t,HitSetRef>::iterator itor;
-      bool in_other_hit_sets = false;
-      unsigned max_in_memory_read = pool.info.min_read_recency_for_promote > 0 ? pool.info.min_read_recency_for_promote - 1 : 0;
-      unsigned max_in_memory_write = pool.info.min_write_recency_for_promote > 0 ? pool.info.min_write_recency_for_promote - 1 : 0;
-      unsigned max_in_memory = MAX(max_in_memory_read, max_in_memory_write);
-      for (itor = agent_state->hit_set_map.begin(); itor != agent_state->hit_set_map.end() && max_in_memory--; ++itor) {
-        if (obc.get()) {
-          if (obc->obs.oi.soid != hobject_t() && itor->second->contains(obc->obs.oi.soid)) {
-            in_other_hit_sets = true;
-            break;
-          }
-        } else {
-          if (missing_oid != hobject_t() && itor->second->contains(missing_oid)) {
-            in_other_hit_sets = true;
-            break;
-          }
-        }
+    {
+      unsigned count = (int)in_hit_set;
+      if (count) {
+       // Check if in other hit sets
+       const hobject_t& oid = obc.get() ? obc->obs.oi.soid : missing_oid;
+       for (map<time_t,HitSetRef>::iterator itor = agent_state->hit_set_map.begin();
+            itor != agent_state->hit_set_map.end();
+            ++itor) {
+         if (!itor->second->contains(oid)) {
+           break;
+         }
+         ++count;
+         if (count >= recency) {
+           break;
+         }
+       }
       }
-      if (in_other_hit_sets) {
-        promote_object(obc, missing_oid, oloc, promote_op);
+      if (count >= recency) {
+       promote_object(obc, missing_oid, oloc, promote_op);
       } else {
        // not promoting
-        return false;
+       return false;
       }
     }
     break;