]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: Expire entries in bucket info cache
authorAdam C. Emerson <aemerson@redhat.com>
Fri, 17 Nov 2017 22:15:26 +0000 (17:15 -0500)
committerAdam C. Emerson <aemerson@redhat.com>
Fri, 5 Jan 2018 15:57:49 +0000 (10:57 -0500)
To bound the degree to which an RGW instance can go out to lunch if
the watch/notify breaks down, force refresh of any cache entry over a
certain age.

Fifteen minutes by default, and expiration can be turned off entirely.

This is separate from the LRU. The LRU removes entries based on the
last time of access. This expiration patch forces refresh based on the
last time they were updated.

Signed-off-by: Adam C. Emerson <aemerson@redhat.com>
(cherry picked from commit 4489cb58a15647a31ac0546d70400af5668404cb)
Fixes: http://tracker.ceph.com/issues/22517
src/common/options.cc
src/rgw/rgw_rados.h

index 33f9205258886eab706ab0bacda697d59bed5976..e190c160cbd11966c8a612093da9563cc90500d9 100644 (file)
@@ -5042,6 +5042,26 @@ std::vector<Option> get_rgw_options() {
     Option("rgw_reshard_thread_interval", Option::TYPE_UINT, Option::LEVEL_ADVANCED)
     .set_default(60 * 10)
     .set_description(""),
+
+    Option("rgw_cache_expiry_interval", Option::TYPE_UINT,
+          Option::LEVEL_ADVANCED)
+    .set_default(900)
+    .set_description("Number of seconds before entries in the bucket info "
+                    "cache are assumed stale and re-fetched. Zero is never.")
+    .add_tag("performance")
+    .add_service("rgw")
+    .set_long_description("The Rados Gateway stores metadata about buckets in "
+                         "an internal cache. This should be kept consistent "
+                         "by the OSD's relaying notify events between "
+                         "multiple watching RGW processes. In the event "
+                         "that this notification protocol fails, bounding "
+                         "the length of time that any data in the cache will "
+                         "be assumed valid will ensure that any RGW instance "
+                         "that falls out of sync will eventually recover. "
+                         "This seems to be an issue mostly for large numbers "
+                         "of RGW instances under heavy use. If you would like "
+                         "to turn off cache expiry, set this value to zero."),
+
   });
 }
 
index 41abab17fca8f7014361f2f26c7e24f175bc05b3..24d94a7306ccaa74bb3589d75fbc6c513d941e8c 100644 (file)
@@ -3733,25 +3733,32 @@ public:
 
 template <class T>
 class RGWChainedCacheImpl : public RGWChainedCache {
+  ceph::timespan expiry;
   RWLock lock;
 
-  map<string, T> entries;
+  map<string, std::pair<T, ceph::coarse_mono_time>> entries;
 
 public:
   RGWChainedCacheImpl() : lock("RGWChainedCacheImpl::lock") {}
 
   void init(RGWRados *store) {
     store->register_chained_cache(this);
+    expiry = std::chrono::seconds(store->ctx()->_conf->get_val<uint64_t>(
+                                   "rgw_cache_expiry_interval"));
   }
 
   bool find(const string& key, T *entry) {
     RWLock::RLocker rl(lock);
-    typename map<string, T>::iterator iter = entries.find(key);
+    auto iter = entries.find(key);
     if (iter == entries.end()) {
       return false;
     }
+    if (expiry.count() &&
+       (ceph::coarse_mono_clock::now() - iter->second.second) > expiry) {
+      return false;
+    }
 
-    *entry = iter->second;
+    *entry = iter->second.first;
     return true;
   }
 
@@ -3765,7 +3772,10 @@ public:
   void chain_cb(const string& key, void *data) override {
     T *entry = static_cast<T *>(data);
     RWLock::WLocker wl(lock);
-    entries[key] = *entry;
+    entries[key].first = *entry;
+    if (expiry.count() > 0) {
+      entries[key].second = ceph::coarse_mono_clock::now();
+    }
   }
 
   void invalidate(const string& key) override {