]> git.apps.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)
committerRobert LeBlanc <rdleblanc@bluehost.com>
Fri, 29 Jan 2016 16:28:57 +0000 (09:28 -0700)
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>
(cherry picked from commit 180c8743addc5ae2f1db9c58cd2996ca6e7ac18b)

Conflicts:
src/osd/ReplicatedPG.cc
                    code section was moved to ReplicatedPG::maybe_promote
                    in master.
Signed-off-by: Robert LeBlanc <robert.leblanc@endurance.com>
src/osd/ReplicatedPG.cc

index b255b9fa6aaa0399755e5c859871d7dc67a565f3..bfaa16bb9b404a7f18a0137da70d1215c04ee3b8 100644 (file)
@@ -1856,23 +1856,27 @@ bool ReplicatedPG::maybe_handle_cache(OpRequestRef op,
       }
       break;
     default:
-      if (in_hit_set) {
-       promote_object(obc, missing_oid, oloc, promote_op);
-      } else {
+      unsigned count = (int)in_hit_set;
+      if (count) {
        // Check if in other hit sets
-       map<time_t,HitSetRef>::iterator itor;
-       bool in_other_hit_sets = false;
-       for (itor = agent_state->hit_set_map.begin(); itor != agent_state->hit_set_map.end(); ++itor) {
-         if (itor->second->contains(missing_oid)) {
-           in_other_hit_sets = true;
+       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 >= pool.info.min_read_recency_for_promote) {
            break;
          }
        }
-       if (in_other_hit_sets) {
-         promote_object(obc, missing_oid, oloc, promote_op);
-       } else if (!can_proxy_read) {
-         do_cache_redirect(op);
-       }
+      }
+      if (count >= pool.info.min_read_recency_for_promote) {
+       promote_object(obc, missing_oid, oloc, promote_op);
+      } else {
+       // not promoting
+       return false;
       }
       break;
     }