Skip to content

Commit ab97b38

Browse files
cheniujhchejingebrother-jinvacheliVachel
authored
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 --------- Co-authored-by: chejinge <chejinge@360.cn> * 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 00cd79d commit ab97b38

11 files changed

Lines changed: 251 additions & 35 deletions

File tree

conf/pika.conf

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

469-
# Rsync Rate limiting configuration 200MB/s
469+
# Rsync Rate limiting configuration [Default value is 200MB/s]
470+
# [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.
471+
# [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).
470472
throttle-bytes-per-second : 207200000
471-
473+
# Rsync timeout in full sync stage[Default value is 1000 ms], unnecessary retries will happen if this value is too small.
474+
# [Dynamic Change Supported] similar to throttle-bytes-per-second, rsync-timeout-ms can be dynamically changed by configset command
475+
# [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.
476+
rsync-timeout-ms : 1000
472477
# The valid range for max-rsync-parallel-num is [1, 4].
473478
# If an invalid value is provided, max-rsync-parallel-num will automatically be reset to 4.
474479
max-rsync-parallel-num : 4

include/pika_conf.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ class PikaConf : public pstd::BaseConf {
165165
uint64_t MaxTotalWalSize() {
166166
std::shared_lock l(rwlock_);
167167
return max_total_wal_size_;
168-
}
168+
}
169169
int64_t max_client_response_size() {
170170
std::shared_lock l(rwlock_);
171171
return max_client_response_size_;
@@ -414,7 +414,9 @@ class PikaConf : public pstd::BaseConf {
414414
std::shared_lock l(rwlock_);
415415
return max_rsync_parallel_num_;
416416
}
417-
417+
int64_t rsync_timeout_ms() {
418+
return rsync_timeout_ms_.load(std::memory_order::memory_order_relaxed);
419+
}
418420
// Slow Commands configuration
419421
const std::string GetSlowCmd() {
420422
std::shared_lock l(rwlock_);
@@ -735,6 +737,13 @@ class PikaConf : public pstd::BaseConf {
735737
TryPushDiffCommands("max-rsync-parallel-num", std::to_string(value));
736738
max_rsync_parallel_num_ = value;
737739
}
740+
741+
void SetRsyncTimeoutMs(int64_t value){
742+
std::lock_guard l(rwlock_);
743+
TryPushDiffCommands("rsync-timeout-ms", std::to_string(value));
744+
rsync_timeout_ms_.store(value);
745+
}
746+
738747
void SetAclPubsubDefault(const std::string& value) {
739748
std::lock_guard l(rwlock_);
740749
TryPushDiffCommands("acl-pubsub-default", value);
@@ -930,6 +939,7 @@ class PikaConf : public pstd::BaseConf {
930939
// Rsync Rate limiting configuration
931940
int throttle_bytes_per_second_ = 207200000;
932941
int max_rsync_parallel_num_ = kMaxRsyncParallelNum;
942+
std::atomic_int64_t rsync_timeout_ms_ = 1000;
933943
};
934944

935945
#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
@@ -21,7 +21,7 @@
2121
#include "include/pika_version.h"
2222
#include "include/pika_conf.h"
2323
#include "pstd/include/rsync.h"
24-
24+
#include "include/throttle.h"
2525
using pstd::Status;
2626

2727
extern PikaServer* g_pika_server;
@@ -2620,7 +2620,22 @@ void ConfigCmd::ConfigSet(std::shared_ptr<DB> db) {
26202620
res_.AppendStringRaw("-ERR Invalid argument \'" + value + "\' for CONFIG SET 'throttle-bytes-per-second'\r\n");
26212621
return;
26222622
}
2623-
g_pika_conf->SetThrottleBytesPerSecond(static_cast<int>(ival));
2623+
int32_t new_throughput_limit = static_cast<int>(ival);
2624+
g_pika_conf->SetThrottleBytesPerSecond(new_throughput_limit);
2625+
//The rate limiter of rsync(Throttle) is used in singleton mode, all db shares the same rate limiter
2626+
rsync::Throttle::GetInstance().ResetThrottleThroughputBytes(new_throughput_limit);
2627+
LOG(INFO) << "The conf item [throttle-bytes-per-second] is changed by Config Set command. "
2628+
"The rsync rate limit now is "
2629+
<< new_throughput_limit << "(Which Is Around " << (new_throughput_limit >> 20) << " MB/s)";
2630+
res_.AppendStringRaw("+OK\r\n");
2631+
} else if(set_item == "rsync-timeout-ms"){
2632+
if(pstd::string2int(value.data(), value.size(), &ival) == 0 || ival <= 0){
2633+
res_.AppendStringRaw("-ERR Invalid argument \'" + value + "\' for CONFIG SET 'rsync-timeout-ms'\r\n");
2634+
return;
2635+
}
2636+
g_pika_conf->SetRsyncTimeoutMs(ival);
2637+
LOG(INFO) << "The conf item [rsync-timeout-ms] is changed by Config Set command. "
2638+
"The rsync-timeout-ms now is " << ival << " ms";
26242639
res_.AppendStringRaw("+OK\r\n");
26252640
} else if (set_item == "max-rsync-parallel-num") {
26262641
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
@@ -641,6 +641,13 @@ int PikaConf::Load() {
641641
max_rsync_parallel_num_ = kMaxRsyncParallelNum;
642642
}
643643

644+
int64_t tmp_rsync_timeout_ms = -1;
645+
GetConfInt64("rsync-timeout-ms", &tmp_rsync_timeout_ms);
646+
if(tmp_rsync_timeout_ms <= 0){
647+
rsync_timeout_ms_.store(1000);
648+
} else {
649+
rsync_timeout_ms_.store(tmp_rsync_timeout_ms);
650+
}
644651
return ret;
645652
}
646653

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)