]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: add configurable max aio limit for multi-object delete requests
authorCory Snyder <csnyder@iland.com>
Fri, 4 Nov 2022 08:04:32 +0000 (08:04 +0000)
committerCory Snyder <csnyder@iland.com>
Fri, 4 Nov 2022 08:05:41 +0000 (08:05 +0000)
Adds the 'rgw_multi_obj_del_max_aio' configuration parameter to
bound aio on multi-object delete requests.

Signed-off-by: Cory Snyder <csnyder@iland.com>
src/common/options/rgw.yaml.in
src/rgw/rgw_op.cc
src/rgw/rgw_op.h

index 33fe0a607948ac2fcd3717c12edf96d74898f692..5d7a45130098b39ad19fcbfcbd1f72c0123ffb7c 100644 (file)
@@ -175,6 +175,14 @@ options:
   services:
   - rgw
   with_legacy: true
+- name: rgw_multi_obj_del_max_aio
+  type: uint
+  level: advanced
+  desc: Max number of concurrent RADOS requests per multi-object delete request.
+  default: 128
+  services:
+  - rgw
+  with_legacy: true
 # whether or not the quota/gc threads should be started
 - name: rgw_enable_quota_threads
   type: bool
index 9dba03d0ed0813392f48d13d2be684e96cdc181e..0554618ac72d08715ee8e8fd3f87c39336f450a3 100644 (file)
@@ -6839,21 +6839,14 @@ void RGWDeleteMultiObj::write_ops_log_entry(rgw_log_entry& entry) const {
   entry.delete_multi_obj_meta.objects = std::move(ops_log_entries);
 }
 
-void RGWDeleteMultiObj::wait_flush(optional_yield y, size_t n)
+void RGWDeleteMultiObj::wait_flush(optional_yield y, std::function<bool()> predicate)
 {
   if (y) {
-    if (ops_log_entries.size() == n) {
-      rgw_flush_formatter(s, s->formatter);
-      return;
-    }
     auto yc = y.get_yield_context();
-    for (;;) {
+    while (!predicate()) {
       boost::system::error_code error;
       formatter_flush_cond->async_wait(yc[error]);
       rgw_flush_formatter(s, s->formatter);
-      if (ops_log_entries.size() == n) {
-        break;
-      }
     }
   }
 }
@@ -7002,6 +6995,8 @@ void RGWDeleteMultiObj::execute(optional_yield y)
   RGWMultiDelDelete *multi_delete;
   vector<rgw_obj_key>::iterator iter;
   RGWMultiDelXMLParser parser;
+  uint32_t aio_count = 0;
+  uint32_t max_aio = s->cct->_conf->rgw_multi_obj_del_max_aio;
   char* buf;
   if (y) {
     formatter_flush_cond = std::make_unique<boost::asio::deadline_timer>(y.get_io_context());  
@@ -7067,16 +7062,22 @@ void RGWDeleteMultiObj::execute(optional_yield y)
         iter != multi_delete->objects.end();
         ++iter) {
     rgw_obj_key* obj_key = &*iter;
-    if (y) {
-      spawn::spawn(y.get_yield_context(), [this, &y, obj_key] (yield_context yield) {
+    if (y && max_aio > 1) {
+      wait_flush(y, [&aio_count, max_aio] {
+        return aio_count < max_aio;
+      });
+      aio_count++;
+      spawn::spawn(y.get_yield_context(), [this, &y, &aio_count, obj_key] (yield_context yield) {
         handle_individual_object(obj_key, optional_yield { y.get_io_context(), yield }); 
+        aio_count--;
       }); 
     } else {
       handle_individual_object(obj_key, y);
     }
   }
-
-  wait_flush(y, multi_delete->objects.size());
+  wait_flush(y, [this, n=multi_delete->objects.size()] {
+    return n == ops_log_entries.size();
+  });
 
   /*  set the return code to zero, errors at this point will be
   dumped to the response */
index e7eee104db1a1dcff99e323b57fbfeb4649c1476..692cb5c50abf31e9a16a13a998383dc9fdc05699 100644 (file)
@@ -2046,7 +2046,7 @@ class RGWDeleteMultiObj : public RGWOp {
    * and saved on the req_state vs. one that is passed on the stack.
    * This is a no-op in the case where we're not executing as a coroutine.
    */
-  void wait_flush(optional_yield y, size_t n);
+  void wait_flush(optional_yield y, std::function<bool()> predicate);
 
 protected:
   std::vector<delete_multi_obj_entry> ops_log_entries;