Skip to content

Commit 37926e4

Browse files
cheniujhchejingebrother-jinvacheliVachel
committed
feat: Add support for dynamicaly reconfig rsync-timeout-ms and throttle-bytes-per-second (OpenAtomFoundation#2633)
* 1 added conf item rsync-timeout-ms 2 add support for dynamically modify throttle-bytes-per-second and rsync-timeout-ms ps: some debug output is waiting to be removed * remove the debug info in start_master_and_slave.sh * feat: Add a feature that is IO speed limiting (OpenAtomFoundation#2599) * add a feature that support IO rate * update IO rate limit mode * Name of variable change to rate-limiter-mode from rate_limiter_mode --------- Co-authored-by: Vachel <vachel@example.com> * feat: Add a feature which support partitioned index filter (OpenAtomFoundation#2601) * add a feature which support partitioned index filter * Name of variable change to enable-partitioned-index-filters from enable_partitioned_index_filters --------- Co-authored-by: Vachel <vachel@example.com> * chore(deps): bump golang.org/x/net from 0.17.0 to 0.23.0 in /codis (OpenAtomFoundation#2619) Bumps [golang.org/x/net](https://github.com/golang/net) from 0.17.0 to 0.23.0. - [Commits](golang/net@v0.17.0...v0.23.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix: Revised CI start script to remove invalid cp command (OpenAtomFoundation#2615) * revised CI start script to remove invalid cp operation and throw from sed command * use sed -i.bak instead of two scripts --------- Co-authored-by: cjh <1271435567@qq.com> * Update Manual compilation in README (OpenAtomFoundation#2617) * enable tests * revised go test * revised go test2 * add flush db operation for test * add Ping operation when get conn from poll to clear unread data in the conn(if the conn has) * 1 reduce the amount of filling data to avoid disk run out * Revert "add Ping operation when get conn from poll to clear unread data in the conn(if the conn has)" This reverts commit ca6c40a. * removed an debug log * add an comment in pika.conf * simplify the calling chain * revised some logic * fix compile error * get timeout value before enter into lock --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: cjh <1271435567@qq.com> Co-authored-by: chejinge <945997690@qq.com> Co-authored-by: chejinge <chejinge@360.cn> Co-authored-by: vacheli <vachelwh@gmail.com> Co-authored-by: Vachel <vachel@example.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: chenbt <34958405+chenbt-hz@users.noreply.github.com>
1 parent 2675904 commit 37926e4

11 files changed

Lines changed: 250 additions & 34 deletions

File tree

conf/pika.conf

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -431,9 +431,14 @@ default-slot-num : 1024
431431
# The cache will be sharded into 2^blob-num-shard-bits shards.
432432
# blob-num-shard-bits : -1
433433

434-
# Rsync Rate limiting configuration 200MB/s
434+
# Rsync Rate limiting configuration [Default value is 200MB/s]
435+
# [USED BY SLAVE] The transmitting speed(Rsync Rate) In full replication is controlled BY SLAVE NODE, You should modify the throttle-bytes-per-second in slave's pika.conf if you wanna change the rsync rate limit.
436+
# [Dynamic Change Supported] send command 'config set throttle-bytes-per-second new_value' to SLAVE NODE can dynamically adjust rsync rate during full sync(use config rewrite can persist the changes).
435437
throttle-bytes-per-second : 207200000
436-
438+
# Rsync timeout in full sync stage[Default value is 1000 ms], unnecessary retries will happen if this value is too small.
439+
# [Dynamic Change Supported] similar to throttle-bytes-per-second, rsync-timeout-ms can be dynamically changed by configset command
440+
# [USED BY SLAVE] Similar to throttle-bytes-per-second, you should change rsync-timeout-ms's value in slave's conf file if it is needed to adjust.
441+
rsync-timeout-ms : 1000
437442
# The valid range for max-rsync-parallel-num is [1, 4].
438443
# If an invalid value is provided, max-rsync-parallel-num will automatically be reset to 4.
439444
max-rsync-parallel-num : 4

include/pika_conf.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,9 @@ class PikaConf : public pstd::BaseConf {
372372
std::shared_lock l(rwlock_);
373373
return max_rsync_parallel_num_;
374374
}
375-
375+
int64_t rsync_timeout_ms() {
376+
return rsync_timeout_ms_.load(std::memory_order::memory_order_relaxed);
377+
}
376378
// Slow Commands configuration
377379
const std::string GetSlowCmd() {
378380
std::shared_lock l(rwlock_);
@@ -655,6 +657,13 @@ class PikaConf : public pstd::BaseConf {
655657
TryPushDiffCommands("max-rsync-parallel-num", std::to_string(value));
656658
max_rsync_parallel_num_ = value;
657659
}
660+
661+
void SetRsyncTimeoutMs(int64_t value){
662+
std::lock_guard l(rwlock_);
663+
TryPushDiffCommands("rsync-timeout-ms", std::to_string(value));
664+
rsync_timeout_ms_.store(value);
665+
}
666+
658667
void SetAclPubsubDefault(const std::string& value) {
659668
std::lock_guard l(rwlock_);
660669
TryPushDiffCommands("acl-pubsub-default", value);
@@ -837,6 +846,7 @@ class PikaConf : public pstd::BaseConf {
837846
// Rsync Rate limiting configuration
838847
int throttle_bytes_per_second_ = 207200000;
839848
int max_rsync_parallel_num_ = kMaxRsyncParallelNum;
849+
std::atomic_int64_t rsync_timeout_ms_ = 1000;
840850
};
841851

842852
#endif

include/pika_rm.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ class SyncSlaveDB : public SyncDB {
116116
void SetLocalIp(const std::string& local_ip);
117117
void StopRsync();
118118
pstd::Status ActivateRsync();
119-
bool IsRsyncRunning() {return rsync_cli_->IsRunning();}
119+
bool IsRsyncRunning() { return rsync_cli_->IsRunning(); }
120120

121121
private:
122122
std::unique_ptr<rsync::RsyncClient> rsync_cli_;

include/rsync_client.h

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ class RsyncClient : public net::Thread {
6767
}
6868
bool IsIdle() { return state_.load() == IDLE;}
6969
void OnReceive(RsyncService::RsyncResponse* resp);
70-
7170
private:
7271
bool ComparisonUpdate();
7372
Status CopyRemoteFile(const std::string& filename, int index);
@@ -98,6 +97,7 @@ class RsyncClient : public net::Thread {
9897
std::condition_variable cond_;
9998
std::mutex mu_;
10099

100+
101101
std::string master_ip_;
102102
int master_port_;
103103
int parallel_num_;
@@ -157,19 +157,18 @@ class WaitObject {
157157
}
158158

159159
pstd::Status Wait(ResponseSPtr& resp) {
160-
pstd::Status s = Status::Timeout("rsync timeout", "timeout");
161-
{
162-
std::unique_lock<std::mutex> lock(mu_);
163-
auto cv_s = cond_.wait_for(lock, std::chrono::seconds(1), [this] {
164-
return resp_.get() != nullptr;
165-
});
166-
if (!cv_s) {
167-
return s;
168-
}
169-
resp = resp_;
170-
s = Status::OK();
160+
auto timeout = g_pika_conf->rsync_timeout_ms();
161+
std::unique_lock<std::mutex> lock(mu_);
162+
auto cv_s = cond_.wait_for(lock, std::chrono::milliseconds(timeout), [this] {
163+
return resp_.get() != nullptr;
164+
});
165+
if (!cv_s) {
166+
std::string timout_info("timeout during(in ms) is ");
167+
timout_info.append(std::to_string(timeout));
168+
return pstd::Status::Timeout("rsync timeout", timout_info);
171169
}
172-
return s;
170+
resp = resp_;
171+
return pstd::Status::OK();
173172
}
174173

175174
void WakeUp(RsyncService::RsyncResponse* resp) {
@@ -234,12 +233,10 @@ class WaitObjectManager {
234233
}
235234
wo_vec_[index]->WakeUp(resp);
236235
}
237-
238236
private:
239237
std::vector<WaitObject*> wo_vec_;
240238
std::mutex mu_;
241239
};
242240

243241
} // end namespace rsync
244242
#endif
245-

include/throttle.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,21 @@ class Throttle {
1818
Throttle() {}
1919
Throttle(size_t throttle_throughput_bytes, size_t check_cycle);
2020
~Throttle();
21+
22+
void ResetThrottleThroughputBytes(size_t new_throughput_bytes_per_s) {
23+
throttle_throughput_bytes_.store(new_throughput_bytes_per_s);
24+
};
2125
size_t ThrottledByThroughput(size_t bytes);
2226
void ReturnUnusedThroughput(size_t acquired, size_t consumed, size_t elaspe_time_us);
2327
static Throttle& GetInstance() {
2428
static Throttle instance(g_pika_conf->throttle_bytes_per_second(), 10);
2529
return instance;
2630
}
27-
28-
private:
31+
private:
2932
std::atomic<size_t> throttle_throughput_bytes_ = 100 * 1024 * 1024;
30-
// the num of tasks doing install_snapshot
3133
std::atomic<size_t> last_throughput_check_time_us_;
3234
std::atomic<size_t> cur_throughput_bytes_;
33-
// user defined check cycles of throughput per second
35+
// check cycles of throughput per second
3436
size_t check_cycle_ = 10;
3537
pstd::Mutex keys_mutex_;
3638
size_t caculate_check_time_us_(int64_t current_time_us, int64_t check_cycle) {

src/pika_admin.cc

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
#include "include/pika_server.h"
2121
#include "include/pika_version.h"
2222
#include "pstd/include/rsync.h"
23-
23+
#include "include/throttle.h"
2424
using pstd::Status;
2525

2626
extern PikaServer* g_pika_server;
@@ -2492,7 +2492,22 @@ void ConfigCmd::ConfigSet(std::shared_ptr<DB> db) {
24922492
res_.AppendStringRaw("-ERR Invalid argument \'" + value + "\' for CONFIG SET 'throttle-bytes-per-second'\r\n");
24932493
return;
24942494
}
2495-
g_pika_conf->SetThrottleBytesPerSecond(static_cast<int>(ival));
2495+
int32_t new_throughput_limit = static_cast<int>(ival);
2496+
g_pika_conf->SetThrottleBytesPerSecond(new_throughput_limit);
2497+
//The rate limiter of rsync(Throttle) is used in singleton mode, all db shares the same rate limiter
2498+
rsync::Throttle::GetInstance().ResetThrottleThroughputBytes(new_throughput_limit);
2499+
LOG(INFO) << "The conf item [throttle-bytes-per-second] is changed by Config Set command. "
2500+
"The rsync rate limit now is "
2501+
<< new_throughput_limit << "(Which Is Around " << (new_throughput_limit >> 20) << " MB/s)";
2502+
res_.AppendStringRaw("+OK\r\n");
2503+
} else if(set_item == "rsync-timeout-ms"){
2504+
if(pstd::string2int(value.data(), value.size(), &ival) == 0 || ival <= 0){
2505+
res_.AppendStringRaw("-ERR Invalid argument \'" + value + "\' for CONFIG SET 'rsync-timeout-ms'\r\n");
2506+
return;
2507+
}
2508+
g_pika_conf->SetRsyncTimeoutMs(ival);
2509+
LOG(INFO) << "The conf item [rsync-timeout-ms] is changed by Config Set command. "
2510+
"The rsync-timeout-ms now is " << ival << " ms";
24962511
res_.AppendStringRaw("+OK\r\n");
24972512
} else if (set_item == "max-rsync-parallel-num") {
24982513
if ((pstd::string2int(value.data(), value.size(), &ival) == 0) || ival > kMaxRsyncParallelNum || ival <= 0) {

src/pika_conf.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,13 @@ int PikaConf::Load() {
606606
max_rsync_parallel_num_ = kMaxRsyncParallelNum;
607607
}
608608

609+
int64_t tmp_rsync_timeout_ms = -1;
610+
GetConfInt64("rsync-timeout-ms", &tmp_rsync_timeout_ms);
611+
if(tmp_rsync_timeout_ms <= 0){
612+
rsync_timeout_ms_.store(1000);
613+
} else {
614+
rsync_timeout_ms_.store(tmp_rsync_timeout_ms);
615+
}
609616
return ret;
610617
}
611618

src/pika_rm.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -966,7 +966,7 @@ Status PikaReplicaManager::RunSyncSlaveDBStateMachine() {
966966
Status s = s_db->ActivateRsync();
967967
if (!s.ok()) {
968968
g_pika_server->SetForceFullSync(true);
969-
LOG(WARNING) << "Slave DB: " << s_db->DBName() << " rsync failed! full synchronization will be retried later";
969+
LOG(WARNING) << "Slave DB: " << s_db->DBName() << " rsync failed! full synchronization will be retried later, error info:" << s.ToString();
970970
continue;
971971
}
972972

src/rsync_client.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ Status RsyncClient::CopyRemoteFile(const std::string& filename, int index) {
201201
std::shared_ptr<RsyncResponse> resp = nullptr;
202202
s = wo->Wait(resp);
203203
if (s.IsTimeout() || resp == nullptr) {
204-
LOG(WARNING) << "rsync request timeout";
204+
LOG(WARNING) << s.ToString();
205205
retries++;
206206
continue;
207207
}
@@ -360,6 +360,7 @@ Status RsyncClient::PullRemoteMeta(std::string* snapshot_uuid, std::set<std::str
360360

361361
if (resp.get() == nullptr || resp->code() != RsyncService::kOk) {
362362
s = Status::IOError("kRsyncMeta request failed! db is not exist or doing bgsave");
363+
LOG(WARNING) << s.ToString() << ", retries:" << retries;
363364
sleep(1);
364365
retries++;
365366
continue;

src/throttle.cc

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@
88
#include <algorithm>
99
#include "pstd/include/env.h"
1010

11-
DEFINE_uint64(raft_minimal_throttle_threshold_mb, 0, "minimal throttle throughput threshold per second");
12-
namespace rsync{
11+
namespace rsync {
1312

1413
Throttle::Throttle(size_t throttle_throughput_bytes, size_t check_cycle)
1514
: throttle_throughput_bytes_(throttle_throughput_bytes),
@@ -21,9 +20,7 @@ Throttle::~Throttle() {}
2120
size_t Throttle::ThrottledByThroughput(size_t bytes) {
2221
size_t available_size = bytes;
2322
size_t now = pstd::NowMicros();
24-
size_t limit_throughput_bytes_s = std::max(static_cast<uint64_t>(throttle_throughput_bytes_),
25-
FLAGS_raft_minimal_throttle_threshold_mb * 1024 * 1024);
26-
size_t limit_per_cycle = limit_throughput_bytes_s / check_cycle_;
23+
size_t limit_per_cycle = throttle_throughput_bytes_.load() / check_cycle_;
2724
std::unique_lock lock(keys_mutex_);
2825
if (cur_throughput_bytes_ + bytes > limit_per_cycle) {
2926
// reading another |bytes| excceds the limit
@@ -57,5 +54,4 @@ void Throttle::ReturnUnusedThroughput(size_t acquired, size_t consumed, size_t e
5754
}
5855
cur_throughput_bytes_ = std::max(cur_throughput_bytes_ - (acquired - consumed), size_t(0));
5956
}
60-
}
61-
57+
} // namespace rsync

0 commit comments

Comments
 (0)