Redis-cli gets RDB by RDB channel (#13809)

Now we have RDB channel in https://github.com/redis/redis/pull/13732,
child process can transfer RDB in a background method, instead of
handled by main thread. So when redis-cli gets RDB from server, we can
adopt this way to reduce the main thread load.

---------

Co-authored-by: Ozan Tezcan <ozantezcan@gmail.com>
This commit is contained in:
Yuan Wang 2025-05-08 08:47:29 +08:00 committed by GitHub
parent a46624e10e
commit 6a436b6f72
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 22 additions and 7 deletions

View File

@ -3884,7 +3884,7 @@ int rdbSaveToSlavesSockets(int req, rdbSaveInfo *rsi) {
listIter li;
pid_t childpid;
int pipefds[2], rdb_pipe_write = 0, safe_to_exit_pipe = 0;
int rdb_channel = (req & SLAVE_REQ_RDB_CHANNEL);
int rdb_channel = server.repl_rdb_channel && (req & SLAVE_REQ_RDB_CHANNEL);
if (hasActiveChildProcess()) return C_ERR;

View File

@ -782,7 +782,7 @@ int replicationSetupSlaveForFullResync(client *slave, long long offset) {
/* Don't send this reply to slaves that approached us with
* the old SYNC command. */
if (!(slave->flags & CLIENT_PRE_PSYNC)) {
if (slave->slave_req & SLAVE_REQ_RDB_CHANNEL) {
if (slave->flags & CLIENT_REPL_RDB_CHANNEL) {
/* This slave is rdbchannel. Find its associated main channel and
* change its state so we can deliver replication stream from now
* on, in parallel to rdb. */
@ -1356,8 +1356,16 @@ void replconfCommand(client *c) {
if (getRangeLongFromObjectOrReply(c,c->argv[j+1],
0,1,&rdb_only,NULL) != C_OK)
return;
if (rdb_only == 1) c->flags |= CLIENT_REPL_RDBONLY;
else c->flags &= ~CLIENT_REPL_RDBONLY;
if (rdb_only == 1) {
c->flags |= CLIENT_REPL_RDBONLY;
/* If replicas ask for RDB only, We can apply the background
* RDB transfer optimization based on the configurations. */
if (server.repl_rdb_channel && server.repl_diskless_sync)
c->slave_req |= SLAVE_REQ_RDB_CHANNEL;
} else {
c->flags &= ~CLIENT_REPL_RDBONLY;
c->slave_req &= ~SLAVE_REQ_RDB_CHANNEL;
}
} else if (!strcasecmp(c->argv[j]->ptr,"rdb-filter-only")) {
/* REPLCONFG RDB-FILTER-ONLY is used to define "include" filters
* for the RDB snapshot. Currently we only support a single
@ -1391,10 +1399,8 @@ void replconfCommand(client *c) {
return;
if (rdb_channel == 1) {
c->flags |= CLIENT_REPL_RDB_CHANNEL;
c->slave_req |= SLAVE_REQ_RDB_CHANNEL;
} else {
c->flags &= ~CLIENT_REPL_RDB_CHANNEL;
c->slave_req &= ~SLAVE_REQ_RDB_CHANNEL;
}
} else if (!strcasecmp(c->argv[j]->ptr, "main-ch-client-id")) {
/* REPLCONF main-ch-client-id <client-id> is used to identify

View File

@ -533,7 +533,7 @@ typedef enum {
#define SLAVE_REQ_NONE 0
#define SLAVE_REQ_RDB_EXCLUDE_DATA (1 << 0) /* Exclude data from RDB */
#define SLAVE_REQ_RDB_EXCLUDE_FUNCTIONS (1 << 1) /* Exclude functions from RDB */
#define SLAVE_REQ_RDB_CHANNEL (1 << 2) /* Use rdb channel replication */
#define SLAVE_REQ_RDB_CHANNEL (1 << 2) /* Use rdb channel replication, transfer RDB background */
/* Mask of all bits in the slave requirements bitfield that represent non-standard (filtered) RDB requirements */
#define SLAVE_REQ_RDB_MASK (SLAVE_REQ_RDB_EXCLUDE_DATA | SLAVE_REQ_RDB_EXCLUDE_FUNCTIONS)

View File

@ -651,6 +651,9 @@ if {!$::tls} { ;# fake_redis_node doesn't support TLS
r flushdb
r function flush
if {!$::external} {
set lines [count_log_lines 0]
}
set dir [lindex [r config get dir] 1]
assert_equal "OK" [r debug populate 100000 key 1000]
@ -663,6 +666,12 @@ if {!$::tls} { ;# fake_redis_node doesn't support TLS
catch {run_cli {*}$args} output
assert_match {*Transfer finished with success*} $output
# If server enabled diskless sync, it should transfer the RDB by RDB channel
# since server will automatically apply this optimization for rdb-only.
if {[r config get repl-diskless-sync] == "yes" && !$::external} {
verify_log_message 0 "*replicas sockets (rdb-channel)*" $lines
}
file delete "$dir/dump.rdb"
file rename "$dir/cli.rdb" "$dir/dump.rdb"

BIN
tmp Normal file

Binary file not shown.