2525#include " rgw_perf_counters.h"
2626#include " rgw_common.h"
2727#include " rgw_bucket.h"
28+ #include " rgw_bucket_layout.h"
2829#include " rgw_lc.h"
2930#include " rgw_zone.h"
3031#include " rgw_string.h"
@@ -348,6 +349,19 @@ static bool pass_object_lock_check(rgw::sal::Driver* driver, rgw::sal::Object* o
348349 }
349350}
350351
352+ /* *
353+ * Determines whether to use unordered listing for lifecycle processing.
354+ *
355+ * For buckets with low shard counts, ordered listing is preferred due to better
356+ * performance
357+ *
358+ * For buckets with high shard counts, unordered listing is preferred to avoid
359+ * excess OSD requests
360+ */
361+ static bool should_list_unordered (const rgw::bucket_index_layout_generation& current_index, uint64_t threshold) {
362+ return current_index.layout .type == rgw::BucketIndexType::Normal
363+ && rgw::num_shards (current_index.layout .normal ) > threshold;
364+ }
351365class LCObjsLister {
352366 rgw::sal::Driver* driver;
353367 rgw::sal::Bucket* bucket;
@@ -363,7 +377,13 @@ class LCObjsLister {
363377 LCObjsLister (rgw::sal::Driver* _driver, rgw::sal::Bucket* _bucket) :
364378 driver (_driver), bucket(_bucket) {
365379 list_params.list_versions = bucket->versioned ();
366- list_params.allow_unordered = true ; // XXX can be unconditionally true, so long as all versions of one object are assured to be on one shard and always ordered on that shard (true today in RADOS)
380+
381+ CephContext* cct = driver->ctx ();
382+ uint64_t threshold = cct->_conf .get_val <uint64_t >(" rgw_lc_ordered_list_threshold" );
383+
384+ const auto & current_index = bucket->get_info ().layout .current_index ;
385+ list_params.allow_unordered = should_list_unordered (current_index, threshold);
386+
367387 delay_ms = driver->ctx ()->_conf .get_val <int64_t >(" rgw_lc_thread_delay" );
368388 }
369389
@@ -377,7 +397,9 @@ class LCObjsLister {
377397 }
378398
379399 int fetch (const DoutPrefixProvider *dpp) {
380- int ret = bucket->list (dpp, list_params, 1000 , list_results, null_yield);
400+ CephContext* cct = dpp->get_cct ();
401+ int cnt = cct->_conf .get_val <uint64_t >(" rgw_lc_list_cnt" );
402+ int ret = bucket->list (dpp, list_params, cnt, list_results, null_yield);
381403 if (ret < 0 ) {
382404 return ret;
383405 }
@@ -908,7 +930,12 @@ int RGWLC::handle_multipart_expiration(rgw::sal::Bucket* target,
908930 /* lifecycle processing does not depend on total order, so can
909931 * take advantage of unordered listing optimizations--such as
910932 * operating on one shard at a time */
911- params.allow_unordered = true ;
933+
934+ uint64_t threshold = cct->_conf .get_val <uint64_t >(" rgw_lc_ordered_list_threshold" );
935+
936+ const auto & current_index = target->get_info ().layout .current_index ;
937+ params.allow_unordered = should_list_unordered (current_index, threshold);
938+
912939 params.ns = RGW_OBJ_NS_MULTIPART;
913940 params.access_list_filter = MultipartMetaFilter;
914941
0 commit comments