]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
tools/ceph-objectstore-tool: split filestore directories offline to target hash level 23418/head
authorZhi Zhang <willzzhang@tencent.com>
Tue, 12 Sep 2017 06:49:31 +0000 (14:49 +0800)
committerDavid Zafman <dzafman@redhat.com>
Tue, 31 Jul 2018 22:18:07 +0000 (15:18 -0700)
Currently ceph-objectstore-tool can only split dirs that already
meet the usual object number criteria. It won't reduce the cost of
online split for those dirs that would meet the criteria online.

This change uses 'arg1' option for apply-layout-settings to specify
the target hash level wants to split to. Then dirs will be split
offline no matters how many objects they have. This also helps
those pools that forgot to do pre-splitting at their creation time.

Signed-off-by: Zhi Zhang <zhangz.david@outlook.com>
(cherry picked from commit e71659b11a54ea3abdb047d2ec480bd855acee4a)

src/os/filestore/CollectionIndex.h
src/os/filestore/FileStore.cc
src/os/filestore/FileStore.h
src/os/filestore/HashIndex.cc
src/os/filestore/HashIndex.h
src/tools/ceph_objectstore_tool.cc

index 7c57a38b564744a6b01751871429d06fbc699c0f..c5d120e1accc30a1f22d504e39307049f7e776a6 100644 (file)
@@ -191,7 +191,7 @@ protected:
       uint64_t expected_num_objs  ///< [in] expected number of objects this collection has
       ) { ceph_abort(); return 0; }
 
-  virtual int apply_layout_settings() { ceph_abort(); return 0; }
+  virtual int apply_layout_settings(int target_level) { ceph_abort(); return 0; }
 
   /// Read index-wide settings (should be called after construction)
   virtual int read_settings() { return 0; }
index c3c9e3759c4ef968e28df15a8fcaa58ed44b22d0..fd7f1cc3812cbc1f2590ca7802f4ef52d572ea74 100644 (file)
@@ -5974,9 +5974,10 @@ uint64_t FileStore::estimate_objects_overhead(uint64_t num_objects)
   return res;
 }
 
-int FileStore::apply_layout_settings(const coll_t &cid)
+int FileStore::apply_layout_settings(const coll_t &cid, int target_level)
 {
-  dout(20) << __FUNC__ << ": " << cid << dendl;
+  dout(20) << __FUNC__ << ": " << cid << " target level: " 
+           << target_level << dendl;
   Index index;
   int r = get_index(cid, &index);
   if (r < 0) {
@@ -5985,7 +5986,7 @@ int FileStore::apply_layout_settings(const coll_t &cid)
     return r;
   }
 
-  return index->apply_layout_settings();
+  return index->apply_layout_settings(target_level);
 }
 
 
index 1b725676a6ca8f97ab808f306687bc13dc08282f..cde43d7003105614e1bd950b75bcec23b142fc7e 100644 (file)
@@ -739,7 +739,7 @@ public:
   void dump_stop();
   void dump_transactions(vector<Transaction>& ls, uint64_t seq, OpSequencer *osr);
 
-  virtual int apply_layout_settings(const coll_t &cid);
+  virtual int apply_layout_settings(const coll_t &cid, int target_level);
 
 private:
   void _inject_failure();
index e0d38f4bdc2a904152990afdcde97584c8b081d1..a36a164b03a641ea443639371eea23532a2b7baf 100644 (file)
@@ -307,8 +307,9 @@ int HashIndex::_split(
     &mkdirred);
 }
 
-int HashIndex::split_dirs(const vector<string> &path) {
-  dout(20) << __func__ << " " << path << dendl;
+int HashIndex::split_dirs(const vector<string> &path, int target_level) {
+  dout(20) << __func__ << " " << path << " target level: " 
+           << target_level << dendl;
   subdir_info_s info;
   int r = get_info(path, &info);
   if (r < 0) {
@@ -317,9 +318,10 @@ int HashIndex::split_dirs(const vector<string> &path) {
     return r;
   }
 
-  if (must_split(info)) {
+  if (must_split(info, target_level)) {
     dout(1) << __func__ << " " << path << " has " << info.objs
-            << " objects, starting split." << dendl;
+            << " objects, " << info.hash_level 
+            << " level, starting split." << dendl;
     r = initiate_split(path, info);
     if (r < 0) {
       dout(10) << "error initiating split on " << path << ": "
@@ -348,7 +350,7 @@ int HashIndex::split_dirs(const vector<string> &path) {
        it != subdirs.end(); ++it) {
     vector<string> subdir_path(path);
     subdir_path.push_back(*it);
-    r = split_dirs(subdir_path);
+    r = split_dirs(subdir_path, target_level);
     if (r < 0) {
       return r;
     }
@@ -357,16 +359,17 @@ int HashIndex::split_dirs(const vector<string> &path) {
   return r;
 }
 
-int HashIndex::apply_layout_settings() {
+int HashIndex::apply_layout_settings(int target_level) {
   vector<string> path;
   dout(10) << __func__ << " split multiple = " << split_multiplier
           << " merge threshold = " << merge_threshold
           << " split rand factor = " << cct->_conf->filestore_split_rand_factor
+          << " target level = " << target_level
           << dendl;
   int r = write_settings();
   if (r < 0)
     return r;
-  return split_dirs(path);
+  return split_dirs(path, target_level);
 }
 
 int HashIndex::_init() {
@@ -741,10 +744,13 @@ bool HashIndex::must_merge(const subdir_info_s &info) {
          info.subdirs == 0);
 }
 
-bool HashIndex::must_split(const subdir_info_s &info) {
+bool HashIndex::must_split(const subdir_info_s &info, int target_level) {
+  // target_level is used for ceph-objectstore-tool to split dirs offline.
+  // if it is set (defalult is 0) and current hash level < target_level, 
+  // this dir would be split no matters how many objects it has.
   return (info.hash_level < (unsigned)MAX_HASH_LEVEL &&
-         info.objs > ((unsigned)(abs(merge_threshold) * split_multiplier + settings.split_rand_factor) * 16));
-
+         ((target_level > 0 && info.hash_level < (unsigned)target_level) ||
+         (info.objs > ((unsigned)(abs(merge_threshold) * split_multiplier + settings.split_rand_factor) * 16))));
 }
 
 int HashIndex::initiate_merge(const vector<string> &path, subdir_info_s info) {
index 216659bff4d9601848273811728461c5704a8a91..db76abbb4d41272bb4eee10c1243b74d2f92d4b7 100644 (file)
@@ -189,7 +189,7 @@ public:
     ) override;
 
   /// @see CollectionIndex
-  int apply_layout_settings() override;
+  int apply_layout_settings(int target_level) override;
 
 protected:
   int _init() override;
@@ -272,7 +272,8 @@ private:
 
   /// Encapsulates logic for when to merge.
   bool must_split(
-    const subdir_info_s &info ///< [in] Info to check
+    const subdir_info_s &info, ///< [in] Info to check
+    int target_level = 0
     ); /// @return True if info must be split, False otherwise
 
   /// Initiates merge
@@ -436,7 +437,7 @@ private:
   int recursive_create_path(vector<string>& path, int level);
 
   /// split each dir below the given path
-  int split_dirs(const vector<string> &path);
+  int split_dirs(const vector<string> &path, int target_level = 0);
 
   int write_settings();
 };
index c640ec50e5f71ab74cce447f323297324f21b399..89af05b4fb0310df4bccbfb41f52142d72e01891 100644 (file)
@@ -2910,7 +2910,8 @@ int mydump_journal(Formatter *f, string journalpath, bool m_journal_dio)
 }
 
 int apply_layout_settings(ObjectStore *os, const OSDSuperblock &superblock,
-                         const string &pool_name, const spg_t &pgid, bool dry_run)
+                         const string &pool_name, const spg_t &pgid, bool dry_run,
+                          int target_level)
 {
   int r = 0;
 
@@ -2960,7 +2961,7 @@ int apply_layout_settings(ObjectStore *os, const OSDSuperblock &superblock,
       cerr << "Would apply layout settings to " << coll << std::endl;
     } else {
       cerr << "Finished " << done << "/" << total << " collections" << "\r";
-      r = fs->apply_layout_settings(coll);
+      r = fs->apply_layout_settings(coll, target_level);
       if (r < 0) {
        cerr << "Error applying layout settings to " << coll << std::endl;
        return r;
@@ -3030,7 +3031,8 @@ int main(int argc, char **argv)
   positional.add_options()
     ("object", po::value<string>(&object), "'' for pgmeta_oid, object name or ghobject in json")
     ("objcmd", po::value<string>(&objcmd), "command [(get|set)-bytes, (get|set|rm)-(attr|omap), (get|set)-omaphdr, list-attrs, list-omap, remove]")
-    ("arg1", po::value<string>(&arg1), "arg1 based on cmd")
+    ("arg1", po::value<string>(&arg1), "arg1 based on cmd, "
+     "for apply-layout-settings: target hash level split to")
     ("arg2", po::value<string>(&arg2), "arg2 based on cmd")
     ;
 
@@ -3401,7 +3403,11 @@ int main(int argc, char **argv)
   }
 
   if (op == "apply-layout-settings") {
-    ret = apply_layout_settings(fs, superblock, pool, pgid, dry_run);
+    int target_level = 0;
+    if (vm.count("arg1") && isdigit(arg1[0])) {
+      target_level = atoi(arg1.c_str());
+    }
+    ret = apply_layout_settings(fs, superblock, pool, pgid, dry_run, target_level);
     goto out;
   }