]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
Add header cache to DBObjectMap 1582/head
authorHaomai Wang <haomaiwang@gmail.com>
Sat, 17 May 2014 05:41:58 +0000 (13:41 +0800)
committerHaomai Wang <haomaiwang@gmail.com>
Sat, 17 May 2014 05:41:58 +0000 (13:41 +0800)
OMap is used by PG to store PGLog, so it's called by each write operations.
Because leveldb don't play well in random read and "header_lock" limit the
concurrence. Add a LRU cache to avoid too much overload on seeking header.

Signed-off-by: Haomai Wang <haomaiwang@gmail.com>
src/common/config_opts.h
src/common/simple_cache.hpp
src/os/DBObjectMap.cc
src/os/DBObjectMap.h

index ee5d39598aa11c40fc4d560c01f36aab0db3a524..360f2ff511c9c7214bc37a17aaf92e3ea8c3280a 100644 (file)
@@ -631,6 +631,7 @@ OPTION(filestore_index_retry_probability, OPT_DOUBLE, 0)
 OPTION(filestore_debug_inject_read_err, OPT_BOOL, false)
 
 OPTION(filestore_debug_omap_check, OPT_BOOL, 0) // Expensive debugging check on sync
+OPTION(filestore_omap_header_cache_size, OPT_INT, 1024) 
 
 // Use omap for xattrs for attrs over
 // filestore_max_inline_xattr_size or
index 60919fd97319ec83398a535a95503e179ec0e96c..30abd0a3ad8d23807e00bc2c54e67107b78f9ded 100644 (file)
@@ -62,6 +62,16 @@ public:
     }
   }
 
+  void clear(K key) {
+    Mutex::Locker l(lock);
+    typename map<K, typename list<pair<K, V> >::iterator>::iterator i =
+      contents.find(key);
+    if (i == contents.end())
+      return;
+    lru.erase(i->second);
+    contents.erase(i);
+  }
+
   void set_size(size_t new_size) {
     Mutex::Locker l(lock);
     max_size = new_size;
index 5d2a2e616242c0f67224febae08b87b06c9d9927..176e1dc34675d3a7daef44600b860c56a00db58e 100644 (file)
@@ -1114,18 +1114,31 @@ DBObjectMap::Header DBObjectMap::_lookup_map_header(const ghobject_t &oid)
   while (map_header_in_use.count(oid))
     header_cond.Wait(header_lock);
 
+  _Header *header = new _Header();
+  {
+    Mutex::Locker l(cache_lock);
+    if (caches.lookup(oid, header)) {
+      return Header(header, RemoveMapHeaderOnDelete(this, oid));
+    }
+  }
+
   map<string, bufferlist> out;
   set<string> to_get;
   to_get.insert(map_header_key(oid));
   int r = db->get(HOBJECT_TO_SEQ, to_get, &out);
-  if (r < 0)
-    return Header();
-  if (out.empty())
+  if (r < 0 || out.empty()) {
+    delete header;
     return Header();
-  
-  Header ret(new _Header(), RemoveMapHeaderOnDelete(this, oid));
+  }
+
+  Header ret(header, RemoveMapHeaderOnDelete(this, oid));
   bufferlist::iterator iter = out.begin()->second.begin();
   ret->decode(iter);
+  {
+    Mutex::Locker l(cache_lock);
+    caches.add(oid, *ret);
+  }
+
   return ret;
 }
 
@@ -1220,6 +1233,10 @@ void DBObjectMap::remove_map_header(const ghobject_t &oid,
   set<string> to_remove;
   to_remove.insert(map_header_key(oid));
   t->rmkeys(HOBJECT_TO_SEQ, to_remove);
+  {
+    Mutex::Locker l(cache_lock);
+    caches.clear(oid);
+  }
 }
 
 void DBObjectMap::set_map_header(const ghobject_t &oid, _Header header,
@@ -1231,6 +1248,10 @@ void DBObjectMap::set_map_header(const ghobject_t &oid, _Header header,
   map<string, bufferlist> to_set;
   header.encode(to_set[map_header_key(oid)]);
   t->set(HOBJECT_TO_SEQ, to_set);
+  {
+    Mutex::Locker l(cache_lock);
+    caches.add(oid, header);
+  }
 }
 
 bool DBObjectMap::check_spos(const ghobject_t &oid,
index a71c369fc028ed1cf66fda87c181739334df57b1..410a3439fec9786d01cc676e5fb1f1ee4f561d8e 100644 (file)
@@ -16,6 +16,7 @@
 #include "osd/osd_types.h"
 #include "common/Mutex.h"
 #include "common/Cond.h"
+#include "common/simple_cache.hpp"
 
 /**
  * DBObjectMap: Implements ObjectMap in terms of KeyValueDB
@@ -68,8 +69,9 @@ public:
   set<uint64_t> in_use;
   set<ghobject_t> map_header_in_use;
 
-  DBObjectMap(KeyValueDB *db) : db(db),
-                               header_lock("DBOBjectMap")
+  DBObjectMap(KeyValueDB *db) : db(db), header_lock("DBOBjectMap"),
+                                cache_lock("DBObjectMap::CacheLock"),
+                                caches(g_conf->filestore_omap_header_cache_size)
     {}
 
   int set_keys(
@@ -281,6 +283,8 @@ public:
 private:
   /// Implicit lock on Header->seq
   typedef ceph::shared_ptr<_Header> Header;
+  Mutex cache_lock;
+  SimpleLRU<ghobject_t, _Header> caches;
 
   string map_header_key(const ghobject_t &oid);
   string header_key(uint64_t seq);