Skip to content

Commit 818e678

Browse files
alimarediacbodley
authored andcommitted
rgw: add labeled counters for sync deltas of shards
Signed-off-by: Ali Maredia <[email protected]>
1 parent 3fa2f0e commit 818e678

File tree

9 files changed

+131
-21
lines changed

9 files changed

+131
-21
lines changed

src/common/perf_counters.cc

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,23 @@ void PerfCounters::tset(int idx, utime_t amt)
315315
ceph_abort();
316316
}
317317

318+
void PerfCounters::tset(int idx, ceph::timespan amt)
319+
{
320+
#ifndef WITH_SEASTAR
321+
if (!m_cct->_conf->perf)
322+
return;
323+
#endif
324+
325+
ceph_assert(idx > m_lower_bound);
326+
ceph_assert(idx < m_upper_bound);
327+
perf_counter_data_any_d& data(m_data[idx - m_lower_bound - 1]);
328+
if (!(data.type & PERFCOUNTER_TIME))
329+
return;
330+
data.u64 = amt.count();
331+
if (data.type & PERFCOUNTER_LONGRUNAVG)
332+
ceph_abort();
333+
}
334+
318335
utime_t PerfCounters::tget(int idx) const
319336
{
320337
#ifndef WITH_SEASTAR

src/common/perf_counters.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@ class PerfCounters
242242
uint64_t get(int idx) const;
243243

244244
void tset(int idx, utime_t v);
245+
void tset(int idx, ceph::timespan v);
245246
void tinc(int idx, utime_t v);
246247
void tinc(int idx, ceph::timespan v);
247248
utime_t tget(int idx) const;

src/rgw/driver/rados/rgw_data_sync.cc

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "common/WorkQueue.h"
77
#include "common/Throttle.h"
88
#include "common/errno.h"
9+
#include "common/perf_counters_key.h"
910

1011
#include "rgw_common.h"
1112
#include "rgw_zone.h"
@@ -300,12 +301,14 @@ struct read_remote_data_log_response {
300301
string marker;
301302
bool truncated;
302303
vector<rgw_data_change_log_entry> entries;
304+
real_time last_update;
303305

304306
read_remote_data_log_response() : truncated(false) {}
305307

306308
void decode_json(JSONObj *obj) {
307309
JSONDecoder::decode_json("marker", marker, obj);
308310
JSONDecoder::decode_json("truncated", truncated, obj);
311+
JSONDecoder::decode_json("last_update", last_update, obj);
309312
JSONDecoder::decode_json("entries", entries, obj);
310313
};
311314
};
@@ -321,6 +324,7 @@ class RGWReadRemoteDataLogShardCR : public RGWCoroutine {
321324
string *pnext_marker;
322325
vector<rgw_data_change_log_entry> *entries;
323326
bool *truncated;
327+
real_time *last_update;
324328

325329
read_remote_data_log_response response;
326330
std::optional<TOPNSPC::common::PerfGuard> timer;
@@ -332,10 +336,10 @@ class RGWReadRemoteDataLogShardCR : public RGWCoroutine {
332336
RGWReadRemoteDataLogShardCR(RGWDataSyncCtx *_sc, int _shard_id,
333337
const std::string& marker, string *pnext_marker,
334338
vector<rgw_data_change_log_entry> *_entries,
335-
bool *_truncated)
339+
bool *_truncated, real_time *_last_update)
336340
: RGWCoroutine(_sc->cct), sc(_sc), sync_env(_sc->env),
337341
shard_id(_shard_id), marker(marker), pnext_marker(pnext_marker),
338-
entries(_entries), truncated(_truncated) {
342+
entries(_entries), truncated(_truncated), last_update(_last_update) {
339343
}
340344

341345
int operate(const DoutPrefixProvider *dpp) override {
@@ -397,6 +401,7 @@ class RGWReadRemoteDataLogShardCR : public RGWCoroutine {
397401
entries->swap(response.entries);
398402
*pnext_marker = response.marker;
399403
*truncated = response.truncated;
404+
*last_update = response.last_update;
400405
return set_cr_done();
401406
}
402407
}
@@ -1109,22 +1114,44 @@ class RGWDataSyncShardMarkerTrack : public RGWSyncShardMarkerTrack<string, strin
11091114
rgw_data_sync_marker sync_marker;
11101115
RGWSyncTraceNodeRef tn;
11111116
RGWObjVersionTracker& objv;
1117+
sync_deltas::SyncDeltaCountersManager sync_delta_counters_manager;
11121118

11131119
public:
11141120
RGWDataSyncShardMarkerTrack(RGWDataSyncCtx *_sc,
11151121
const string& _marker_oid,
11161122
const rgw_data_sync_marker& _marker,
1117-
RGWSyncTraceNodeRef& _tn, RGWObjVersionTracker& objv) : RGWSyncShardMarkerTrack(DATA_SYNC_UPDATE_MARKER_WINDOW),
1123+
RGWSyncTraceNodeRef& _tn,
1124+
RGWObjVersionTracker& objv,
1125+
const uint32_t shard_id) : RGWSyncShardMarkerTrack(DATA_SYNC_UPDATE_MARKER_WINDOW),
11181126
sc(_sc), sync_env(_sc->env),
11191127
marker_oid(_marker_oid),
11201128
sync_marker(_marker),
1121-
tn(_tn), objv(objv) {}
1129+
tn(_tn), objv(objv),
1130+
sync_delta_counters_manager(init_keys(shard_id), _sc->env->cct) {}
11221131

1123-
RGWCoroutine* store_marker(const string& new_marker, uint64_t index_pos, const real_time& timestamp) override {
1132+
std::string init_keys(const uint32_t shard_id) {
1133+
std::string sz_id = sc->source_zone.id;
1134+
std::string lz_id = sc->env->svc->zone->get_zone_params().get_id();
1135+
return ceph::perf_counters::key_create(rgw_sync_delta_counters_key,
1136+
{{"local-zone-id", lz_id},
1137+
{"source-zone-id", sz_id},
1138+
{"shard-id", std::to_string(shard_id)}});
1139+
}
1140+
1141+
RGWCoroutine* store_marker(const string& new_marker, uint64_t index_pos, const real_time& timestamp, const real_time& last_update) override {
11241142
sync_marker.marker = new_marker;
11251143
sync_marker.pos = index_pos;
11261144
sync_marker.timestamp = timestamp;
11271145

1146+
// Since store_marker() is called by full and incremental sync but
1147+
// last_update is only modified during incremental sync we only want to
1148+
// report deltas for incremental sync
1149+
real_time zero_time;
1150+
if (last_update != zero_time) {
1151+
auto delta = last_update - timestamp;
1152+
sync_delta_counters_manager.tset(sync_deltas::l_rgw_datalog_sync_delta, delta);
1153+
}
1154+
11281155
tn->log(20, SSTR("updating marker marker_oid=" << marker_oid << " marker=" << new_marker));
11291156

11301157
return new RGWSimpleRadosWriteCR<rgw_data_sync_marker>(sync_env->dpp, sync_env->driver,
@@ -1814,7 +1841,7 @@ class RGWDataFullSyncShardCR : public RGWDataBaseSyncShardCR {
18141841
reenter(this) {
18151842
tn->log(10, "start full sync");
18161843
oid = full_data_sync_index_shard_oid(sc->source_zone, shard_id);
1817-
marker_tracker.emplace(sc, status_oid, sync_marker, tn, objv);
1844+
marker_tracker.emplace(sc, status_oid, sync_marker, tn, objv, shard_id);
18181845
total_entries = sync_marker.pos;
18191846
entry_timestamp = sync_marker.timestamp; // time when full sync started
18201847
do {
@@ -1927,6 +1954,7 @@ class RGWDataIncSyncShardCR : public RGWDataBaseSyncShardCR {
19271954

19281955
string next_marker;
19291956
vector<rgw_data_change_log_entry> log_entries;
1957+
real_time last_update;
19301958
decltype(log_entries)::iterator log_iter;
19311959
bool truncated = false;
19321960
int cbret = 0;
@@ -1968,7 +1996,7 @@ class RGWDataIncSyncShardCR : public RGWDataBaseSyncShardCR {
19681996
int operate(const DoutPrefixProvider *dpp) override {
19691997
reenter(this) {
19701998
tn->log(10, "start incremental sync");
1971-
marker_tracker.emplace(sc, status_oid, sync_marker, tn, objv);
1999+
marker_tracker.emplace(sc, status_oid, sync_marker, tn, objv, shard_id);
19722000
do {
19732001
if (!lease_cr->is_locked()) {
19742002
lost_lock = true;
@@ -2073,7 +2101,7 @@ class RGWDataIncSyncShardCR : public RGWDataBaseSyncShardCR {
20732101
yield call(new RGWReadRemoteDataLogShardCR(sc, shard_id,
20742102
sync_marker.marker,
20752103
&next_marker, &log_entries,
2076-
&truncated));
2104+
&truncated, &last_update));
20772105
if (retcode < 0 && retcode != -ENOENT) {
20782106
tn->log(0, SSTR("ERROR: failed to read remote data log info: ret="
20792107
<< retcode));
@@ -2100,11 +2128,11 @@ class RGWDataIncSyncShardCR : public RGWDataBaseSyncShardCR {
21002128
tn->log(1, SSTR("failed to parse bucket shard: "
21012129
<< log_iter->entry.key));
21022130
marker_tracker->try_update_high_marker(log_iter->log_id, 0,
2103-
log_iter->log_timestamp);
2131+
log_iter->log_timestamp, last_update);
21042132
continue;
21052133
}
21062134
if (!marker_tracker->start(log_iter->log_id, 0,
2107-
log_iter->log_timestamp)) {
2135+
log_iter->log_timestamp, last_update)) {
21082136
tn->log(0, SSTR("ERROR: cannot start syncing " << log_iter->log_id
21092137
<< ". Duplicate entry?"));
21102138
} else {
@@ -3922,6 +3950,7 @@ class RGWReadPendingBucketShardsCoroutine : public RGWCoroutine {
39223950
std::string next_marker;
39233951
vector<rgw_data_change_log_entry> log_entries;
39243952
bool truncated;
3953+
real_time last_update;
39253954

39263955
public:
39273956
RGWReadPendingBucketShardsCoroutine(RGWDataSyncCtx *_sc, const int _shard_id,
@@ -3956,7 +3985,7 @@ int RGWReadPendingBucketShardsCoroutine::operate(const DoutPrefixProvider *dpp)
39563985
count = 0;
39573986
do{
39583987
yield call(new RGWReadRemoteDataLogShardCR(sc, shard_id, marker,
3959-
&next_marker, &log_entries, &truncated));
3988+
&next_marker, &log_entries, &truncated, &last_update));
39603989

39613990
if (retcode == -ENOENT) {
39623991
break;
@@ -4223,7 +4252,7 @@ class RGWBucketFullSyncMarkerTrack : public RGWSyncShardMarkerTrack<rgw_obj_key,
42234252
{}
42244253

42254254

4226-
RGWCoroutine *store_marker(const rgw_obj_key& new_marker, uint64_t index_pos, const real_time& timestamp) override {
4255+
RGWCoroutine *store_marker(const rgw_obj_key& new_marker, uint64_t index_pos, const real_time& timestamp, const real_time& last_update) override {
42274256
sync_status.full.position = new_marker;
42284257
sync_status.full.count = index_pos;
42294258

@@ -4324,7 +4353,7 @@ class RGWBucketIncSyncShardMarkerTrack : public RGWSyncShardMarkerTrack<string,
43244353

43254354
const rgw_raw_obj& get_obj() const { return obj; }
43264355

4327-
RGWCoroutine* store_marker(const string& new_marker, uint64_t index_pos, const real_time& timestamp) override {
4356+
RGWCoroutine* store_marker(const string& new_marker, uint64_t index_pos, const real_time& timestamp, const real_time& last_update) override {
43284357
sync_marker.position = new_marker;
43294358
sync_marker.timestamp = timestamp;
43304359

src/rgw/driver/rados/rgw_rest_log.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,12 @@ void RGWOp_DATALog_List::execute(optional_yield y) {
691691
op_ret = static_cast<rgw::sal::RadosStore*>(driver)->svc()->
692692
datalog_rados->list_entries(this, shard_id, max_entries, entries,
693693
marker, &last_marker, &truncated, y);
694+
695+
RGWDataChangesLogInfo info;
696+
op_ret = static_cast<rgw::sal::RadosStore*>(driver)->svc()->
697+
datalog_rados->get_info(this, shard_id, &info, y);
698+
699+
last_update = info.last_update;
694700
}
695701

696702
void RGWOp_DATALog_List::send_response() {
@@ -703,6 +709,8 @@ void RGWOp_DATALog_List::send_response() {
703709

704710
s->formatter->open_object_section("log_entries");
705711
s->formatter->dump_string("marker", last_marker);
712+
utime_t lu(last_update);
713+
encode_json("last_update", lu, s->formatter);
706714
s->formatter->dump_bool("truncated", truncated);
707715
{
708716
s->formatter->open_array_section("entries");

src/rgw/driver/rados/rgw_rest_log.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ class RGWOp_DATALog_List : public RGWRESTOp {
209209
std::string last_marker;
210210
bool truncated;
211211
bool extra_info;
212+
ceph::real_time last_update;
212213
public:
213214
RGWOp_DATALog_List() : truncated(false), extra_info(false) {}
214215
~RGWOp_DATALog_List() override {}

src/rgw/driver/rados/rgw_sync.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1256,7 +1256,7 @@ class RGWMetaSyncShardMarkerTrack : public RGWSyncShardMarkerTrack<string, strin
12561256
sync_marker(_marker),
12571257
tn(_tn){}
12581258

1259-
RGWCoroutine *store_marker(const string& new_marker, uint64_t index_pos, const real_time& timestamp) override {
1259+
RGWCoroutine *store_marker(const string& new_marker, uint64_t index_pos, const real_time& timestamp, const real_time& last_update) override {
12601260
sync_marker.marker = new_marker;
12611261
if (index_pos > 0) {
12621262
sync_marker.pos = index_pos;

src/rgw/driver/rados/rgw_sync.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -343,9 +343,10 @@ class RGWSyncShardMarkerTrack {
343343
struct marker_entry {
344344
uint64_t pos;
345345
real_time timestamp;
346+
real_time last_update;
346347

347348
marker_entry() : pos(0) {}
348-
marker_entry(uint64_t _p, const real_time& _ts) : pos(_p), timestamp(_ts) {}
349+
marker_entry(uint64_t _p, const real_time& _ts, const real_time& _lu = {}) : pos(_p), timestamp(_ts), last_update(_lu) {}
349350
};
350351
typename std::map<T, marker_entry> pending;
351352

@@ -359,7 +360,7 @@ class RGWSyncShardMarkerTrack {
359360
protected:
360361
typename std::set<K> need_retry_set;
361362

362-
virtual RGWCoroutine *store_marker(const T& new_marker, uint64_t index_pos, const real_time& timestamp) = 0;
363+
virtual RGWCoroutine *store_marker(const T& new_marker, uint64_t index_pos, const real_time& timestamp, const real_time& last_update) = 0;
363364
virtual RGWOrderCallCR *allocate_order_control_cr() = 0;
364365
virtual void handle_finish(const T& marker) { }
365366

@@ -371,16 +372,16 @@ class RGWSyncShardMarkerTrack {
371372
}
372373
}
373374

374-
bool start(const T& pos, int index_pos, const real_time& timestamp) {
375+
bool start(const T& pos, int index_pos, const real_time& timestamp, const real_time& last_update = {}) {
375376
if (pending.find(pos) != pending.end()) {
376377
return false;
377378
}
378-
pending[pos] = marker_entry(index_pos, timestamp);
379+
pending[pos] = marker_entry(index_pos, timestamp, last_update);
379380
return true;
380381
}
381382

382-
void try_update_high_marker(const T& pos, int index_pos, const real_time& timestamp) {
383-
finish_markers[pos] = marker_entry(index_pos, timestamp);
383+
void try_update_high_marker(const T& pos, int index_pos, const real_time& timestamp, const real_time& last_update = {}) {
384+
finish_markers[pos] = marker_entry(index_pos, timestamp, last_update);
384385
}
385386

386387
RGWCoroutine *finish(const T& pos) {
@@ -436,7 +437,7 @@ class RGWSyncShardMarkerTrack {
436437
--i;
437438
const T& high_marker = i->first;
438439
marker_entry& high_entry = i->second;
439-
RGWCoroutine *cr = order(store_marker(high_marker, high_entry.pos, high_entry.timestamp));
440+
RGWCoroutine *cr = order(store_marker(high_marker, high_entry.pos, high_entry.timestamp, high_entry.last_update));
440441
finish_markers.erase(finish_markers.begin(), last);
441442
return cr;
442443
}

src/rgw/driver/rados/rgw_sync_counters.cc

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include "common/ceph_context.h"
55
#include "rgw_sync_counters.h"
6+
#include "common/perf_counters_key.h"
67

78
namespace sync_counters {
89

@@ -26,3 +27,31 @@ PerfCountersRef build(CephContext *cct, const std::string& name)
2627
}
2728

2829
} // namespace sync_counters
30+
31+
namespace sync_deltas {
32+
33+
void add_rgw_sync_delta_counters(PerfCountersBuilder *lpcb) {
34+
lpcb->set_prio_default(PerfCountersBuilder::PRIO_USEFUL);
35+
lpcb->add_time(l_rgw_datalog_sync_delta, "sync_delta", "Sync delta between data log shard in seconds");
36+
}
37+
38+
SyncDeltaCountersManager::SyncDeltaCountersManager(const std::string& name, CephContext *cct)
39+
: cct(cct)
40+
{
41+
std::string_view key = ceph::perf_counters::key_name(name);
42+
ceph_assert(rgw_sync_delta_counters_key == key);
43+
PerfCountersBuilder pcb(cct, name, l_rgw_sync_delta_first, l_rgw_sync_delta_last);
44+
add_rgw_sync_delta_counters(&pcb);
45+
sync_delta_counters = std::unique_ptr<PerfCounters>(pcb.create_perf_counters());
46+
cct->get_perfcounters_collection()->add(sync_delta_counters.get());
47+
}
48+
49+
void SyncDeltaCountersManager::tset(int idx, ceph::timespan v) {
50+
sync_delta_counters->tset(idx, v);
51+
}
52+
53+
SyncDeltaCountersManager::~SyncDeltaCountersManager() {
54+
cct->get_perfcounters_collection()->remove(sync_delta_counters.get());
55+
}
56+
57+
} // namespace sync_deltas

src/rgw/driver/rados/rgw_sync_counters.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,27 @@ enum {
2323
PerfCountersRef build(CephContext *cct, const std::string& name);
2424

2525
} // namespace sync_counters
26+
27+
const std::string rgw_sync_delta_counters_key = "rgw_sync_delta";
28+
29+
namespace sync_deltas {
30+
31+
enum {
32+
l_rgw_sync_delta_first = 806000,
33+
l_rgw_datalog_sync_delta,
34+
l_rgw_sync_delta_last,
35+
};
36+
37+
class SyncDeltaCountersManager {
38+
std::unique_ptr<PerfCounters> sync_delta_counters;
39+
CephContext *cct;
40+
41+
public:
42+
SyncDeltaCountersManager(const std::string& name, CephContext *cct);
43+
44+
void tset(int idx, ceph::timespan v);
45+
46+
~SyncDeltaCountersManager();
47+
};
48+
49+
} // namespace sync_deltas

0 commit comments

Comments
 (0)