Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
abbfbcf1
Commit
abbfbcf1
authored
Feb 04, 2015
by
antirez
Browse files
Experimental no-sync replication mode.
parent
b1de179c
Changes
5
Hide whitespace changes
Inline
Side-by-side
src/config.c
View file @
abbfbcf1
...
@@ -276,6 +276,10 @@ void loadServerConfigFromString(char *config) {
...
@@ -276,6 +276,10 @@ void loadServerConfigFromString(char *config) {
if
((
server
.
repl_diskless_sync
=
yesnotoi
(
argv
[
1
]))
==
-
1
)
{
if
((
server
.
repl_diskless_sync
=
yesnotoi
(
argv
[
1
]))
==
-
1
)
{
err
=
"argument must be 'yes' or 'no'"
;
goto
loaderr
;
err
=
"argument must be 'yes' or 'no'"
;
goto
loaderr
;
}
}
}
else
if
(
!
strcasecmp
(
argv
[
0
],
"repl-no-sync"
)
&&
argc
==
2
)
{
if
((
server
.
repl_no_sync
=
yesnotoi
(
argv
[
1
]))
==
-
1
)
{
err
=
"argument must be 'yes' or 'no'"
;
goto
loaderr
;
}
}
else
if
(
!
strcasecmp
(
argv
[
0
],
"repl-diskless-sync-delay"
)
&&
argc
==
2
)
{
}
else
if
(
!
strcasecmp
(
argv
[
0
],
"repl-diskless-sync-delay"
)
&&
argc
==
2
)
{
server
.
repl_diskless_sync_delay
=
atoi
(
argv
[
1
]);
server
.
repl_diskless_sync_delay
=
atoi
(
argv
[
1
]);
if
(
server
.
repl_diskless_sync_delay
<
0
)
{
if
(
server
.
repl_diskless_sync_delay
<
0
)
{
...
...
src/networking.c
View file @
abbfbcf1
...
@@ -673,7 +673,10 @@ void freeClient(redisClient *c) {
...
@@ -673,7 +673,10 @@ void freeClient(redisClient *c) {
*
*
* Note that before doing this we make sure that the client is not in
* Note that before doing this we make sure that the client is not in
* some unexpected state, by checking its flags. */
* some unexpected state, by checking its flags. */
if
(
server
.
master
&&
c
->
flags
&
REDIS_MASTER
)
{
if
(
server
.
master
&&
c
->
flags
&
REDIS_MASTER
&&
server
.
repl_no_sync
==
0
)
{
redisLog
(
REDIS_WARNING
,
"Connection with master lost."
);
redisLog
(
REDIS_WARNING
,
"Connection with master lost."
);
if
(
!
(
c
->
flags
&
(
REDIS_CLOSE_AFTER_REPLY
|
if
(
!
(
c
->
flags
&
(
REDIS_CLOSE_AFTER_REPLY
|
REDIS_CLOSE_ASAP
|
REDIS_CLOSE_ASAP
|
...
...
src/redis.c
View file @
abbfbcf1
...
@@ -1496,6 +1496,7 @@ void initServerConfig(void) {
...
@@ -1496,6 +1496,7 @@ void initServerConfig(void) {
server
.
repl_disable_tcp_nodelay
=
REDIS_DEFAULT_REPL_DISABLE_TCP_NODELAY
;
server
.
repl_disable_tcp_nodelay
=
REDIS_DEFAULT_REPL_DISABLE_TCP_NODELAY
;
server
.
repl_diskless_sync
=
REDIS_DEFAULT_REPL_DISKLESS_SYNC
;
server
.
repl_diskless_sync
=
REDIS_DEFAULT_REPL_DISKLESS_SYNC
;
server
.
repl_diskless_sync_delay
=
REDIS_DEFAULT_REPL_DISKLESS_SYNC_DELAY
;
server
.
repl_diskless_sync_delay
=
REDIS_DEFAULT_REPL_DISKLESS_SYNC_DELAY
;
server
.
repl_no_sync
=
REDIS_DEFAULT_REPL_NO_SYNC
;
server
.
slave_priority
=
REDIS_DEFAULT_SLAVE_PRIORITY
;
server
.
slave_priority
=
REDIS_DEFAULT_SLAVE_PRIORITY
;
server
.
master_repl_offset
=
0
;
server
.
master_repl_offset
=
0
;
...
...
src/redis.h
View file @
abbfbcf1
...
@@ -119,6 +119,7 @@ typedef long long mstime_t; /* millisecond time type. */
...
@@ -119,6 +119,7 @@ typedef long long mstime_t; /* millisecond time type. */
#define REDIS_DEFAULT_RDB_FILENAME "dump.rdb"
#define REDIS_DEFAULT_RDB_FILENAME "dump.rdb"
#define REDIS_DEFAULT_REPL_DISKLESS_SYNC 0
#define REDIS_DEFAULT_REPL_DISKLESS_SYNC 0
#define REDIS_DEFAULT_REPL_DISKLESS_SYNC_DELAY 5
#define REDIS_DEFAULT_REPL_DISKLESS_SYNC_DELAY 5
#define REDIS_DEFAULT_REPL_NO_SYNC 0
#define REDIS_DEFAULT_SLAVE_SERVE_STALE_DATA 1
#define REDIS_DEFAULT_SLAVE_SERVE_STALE_DATA 1
#define REDIS_DEFAULT_SLAVE_READ_ONLY 1
#define REDIS_DEFAULT_SLAVE_READ_ONLY 1
#define REDIS_DEFAULT_REPL_DISABLE_TCP_NODELAY 0
#define REDIS_DEFAULT_REPL_DISABLE_TCP_NODELAY 0
...
@@ -258,6 +259,7 @@ typedef long long mstime_t; /* millisecond time type. */
...
@@ -258,6 +259,7 @@ typedef long long mstime_t; /* millisecond time type. */
#define REDIS_READONLY (1<<17)
/* Cluster client is in read-only state. */
#define REDIS_READONLY (1<<17)
/* Cluster client is in read-only state. */
#define REDIS_PUBSUB (1<<18)
/* Client is in Pub/Sub mode. */
#define REDIS_PUBSUB (1<<18)
/* Client is in Pub/Sub mode. */
#define REDIS_PREVENT_PROP (1<<19)
/* Don't propagate to AOF / Slaves. */
#define REDIS_PREVENT_PROP (1<<19)
/* Don't propagate to AOF / Slaves. */
#define REDIS_SLAVE_NO_SYNC (1<<20)
/* Result of: REPLCONF use-sync 0. */
/* Client block type (btype field in client structure)
/* Client block type (btype field in client structure)
* if REDIS_BLOCKED flag is set. */
* if REDIS_BLOCKED flag is set. */
...
@@ -853,6 +855,7 @@ struct redisServer {
...
@@ -853,6 +855,7 @@ struct redisServer {
int
slave_priority
;
/* Reported in INFO and used by Sentinel. */
int
slave_priority
;
/* Reported in INFO and used by Sentinel. */
char
repl_master_runid
[
REDIS_RUN_ID_SIZE
+
1
];
/* Master run id for PSYNC. */
char
repl_master_runid
[
REDIS_RUN_ID_SIZE
+
1
];
/* Master run id for PSYNC. */
long
long
repl_master_initial_offset
;
/* Master PSYNC offset. */
long
long
repl_master_initial_offset
;
/* Master PSYNC offset. */
int
repl_no_sync
;
/* Streaming replication, no SYNC. */
/* Replication script cache. */
/* Replication script cache. */
dict
*
repl_scriptcache_dict
;
/* SHA1 all slaves are aware of. */
dict
*
repl_scriptcache_dict
;
/* SHA1 all slaves are aware of. */
list
*
repl_scriptcache_fifo
;
/* First in, first out LRU eviction. */
list
*
repl_scriptcache_fifo
;
/* First in, first out LRU eviction. */
...
...
src/replication.c
View file @
abbfbcf1
...
@@ -480,6 +480,9 @@ void syncCommand(redisClient *c) {
...
@@ -480,6 +480,9 @@ void syncCommand(redisClient *c) {
return
;
return
;
}
}
/* Accept the slave ASAP if it is running in no-sync mode. */
goto
attach_slave
;
redisLog
(
REDIS_NOTICE
,
"Slave %s asks for synchronization"
,
redisLog
(
REDIS_NOTICE
,
"Slave %s asks for synchronization"
,
replicationGetSlaveName
(
c
));
replicationGetSlaveName
(
c
));
...
@@ -571,6 +574,8 @@ void syncCommand(redisClient *c) {
...
@@ -571,6 +574,8 @@ void syncCommand(redisClient *c) {
}
}
}
}
attach_slave:
if
(
server
.
repl_disable_tcp_nodelay
)
if
(
server
.
repl_disable_tcp_nodelay
)
anetDisableTcpNoDelay
(
NULL
,
c
->
fd
);
/* Non critical if it fails. */
anetDisableTcpNoDelay
(
NULL
,
c
->
fd
);
/* Non critical if it fails. */
c
->
repldbfd
=
-
1
;
c
->
repldbfd
=
-
1
;
...
@@ -579,6 +584,18 @@ void syncCommand(redisClient *c) {
...
@@ -579,6 +584,18 @@ void syncCommand(redisClient *c) {
listAddNodeTail
(
server
.
slaves
,
c
);
listAddNodeTail
(
server
.
slaves
,
c
);
if
(
listLength
(
server
.
slaves
)
==
1
&&
server
.
repl_backlog
==
NULL
)
if
(
listLength
(
server
.
slaves
)
==
1
&&
server
.
repl_backlog
==
NULL
)
createReplicationBacklog
();
createReplicationBacklog
();
/* Put the slave fully online right now if it is a no-sync one. */
if
(
c
->
flags
&
REDIS_SLAVE_NO_SYNC
)
{
char
buf
[
128
];
int
buflen
;
/* Inform the slave with +NOTNEEDED that the request was accepted. */
buflen
=
snprintf
(
buf
,
sizeof
(
buf
),
"+NOTNEEDED
\r\n
"
);
if
(
write
(
c
->
fd
,
buf
,
buflen
)
!=
buflen
)
freeClientAsync
(
c
);
aeDeleteFileEvent
(
server
.
el
,
c
->
fd
,
AE_WRITABLE
);
putSlaveOnline
(
c
);
}
return
;
return
;
}
}
...
@@ -613,6 +630,18 @@ void replconfCommand(redisClient *c) {
...
@@ -613,6 +630,18 @@ void replconfCommand(redisClient *c) {
&
port
,
NULL
)
!=
REDIS_OK
))
&
port
,
NULL
)
!=
REDIS_OK
))
return
;
return
;
c
->
slave_listening_port
=
port
;
c
->
slave_listening_port
=
port
;
}
else
if
(
!
strcasecmp
(
c
->
argv
[
j
]
->
ptr
,
"use-sync"
))
{
/* REPLCONF USE-SYNC is used in order for the slave to request
* synchronization-less replication, the master will just send
* new data without trying to synchronize the slave. */
long
long
val
;
if
((
getLongLongFromObject
(
c
->
argv
[
j
+
1
],
&
val
)
!=
REDIS_OK
))
return
;
if
(
val
)
c
->
flags
&=
~
REDIS_SLAVE_NO_SYNC
;
else
c
->
flags
|=
REDIS_SLAVE_NO_SYNC
;
}
else
if
(
!
strcasecmp
(
c
->
argv
[
j
]
->
ptr
,
"ack"
))
{
}
else
if
(
!
strcasecmp
(
c
->
argv
[
j
]
->
ptr
,
"ack"
))
{
/* REPLCONF ACK is used by slave to inform the master the amount
/* REPLCONF ACK is used by slave to inform the master the amount
* of replication stream that it processed so far. It is an
* of replication stream that it processed so far. It is an
...
@@ -1140,7 +1169,7 @@ int slaveTryPartialResynchronization(int fd) {
...
@@ -1140,7 +1169,7 @@ int slaveTryPartialResynchronization(int fd) {
* client structure representing the master into server.master. */
* client structure representing the master into server.master. */
server
.
repl_master_initial_offset
=
-
1
;
server
.
repl_master_initial_offset
=
-
1
;
if
(
server
.
cached_master
)
{
if
(
server
.
cached_master
&&
server
.
repl_no_sync
==
0
)
{
psync_runid
=
server
.
cached_master
->
replrunid
;
psync_runid
=
server
.
cached_master
->
replrunid
;
snprintf
(
psync_offset
,
sizeof
(
psync_offset
),
"%lld"
,
server
.
cached_master
->
reploff
+
1
);
snprintf
(
psync_offset
,
sizeof
(
psync_offset
),
"%lld"
,
server
.
cached_master
->
reploff
+
1
);
redisLog
(
REDIS_NOTICE
,
"Trying a partial resynchronization (request %s:%s)."
,
psync_runid
,
psync_offset
);
redisLog
(
REDIS_NOTICE
,
"Trying a partial resynchronization (request %s:%s)."
,
psync_runid
,
psync_offset
);
...
@@ -1186,6 +1215,14 @@ int slaveTryPartialResynchronization(int fd) {
...
@@ -1186,6 +1215,14 @@ int slaveTryPartialResynchronization(int fd) {
return
PSYNC_FULLRESYNC
;
return
PSYNC_FULLRESYNC
;
}
}
if
(
!
strncmp
(
reply
,
"+NOTNEEDED"
,
10
))
{
/* No-sync replication. */
redisLog
(
REDIS_NOTICE
,
"No-sync slave accepted without SYNC phase."
);
sdsfree
(
reply
);
replicationCreateMasterClient
(
fd
);
return
PSYNC_CONTINUE
;
}
if
(
!
strncmp
(
reply
,
"+CONTINUE"
,
9
))
{
if
(
!
strncmp
(
reply
,
"+CONTINUE"
,
9
))
{
/* Partial resync was accepted, set the replication state accordingly */
/* Partial resync was accepted, set the replication state accordingly */
redisLog
(
REDIS_NOTICE
,
redisLog
(
REDIS_NOTICE
,
...
@@ -1292,7 +1329,7 @@ void syncWithMaster(aeEventLoop *el, int fd, void *privdata, int mask) {
...
@@ -1292,7 +1329,7 @@ void syncWithMaster(aeEventLoop *el, int fd, void *privdata, int mask) {
}
}
/* AUTH with the master if required. */
/* AUTH with the master if required. */
if
(
server
.
masterauth
)
{
if
(
server
.
masterauth
)
{
err
=
sendSynchronousCommand
(
fd
,
"AUTH"
,
server
.
masterauth
,
NULL
);
err
=
sendSynchronousCommand
(
fd
,
"AUTH"
,
server
.
masterauth
,
NULL
);
if
(
err
[
0
]
==
'-'
)
{
if
(
err
[
0
]
==
'-'
)
{
redisLog
(
REDIS_WARNING
,
"Unable to AUTH to MASTER: %s"
,
err
);
redisLog
(
REDIS_WARNING
,
"Unable to AUTH to MASTER: %s"
,
err
);
...
@@ -1302,6 +1339,18 @@ void syncWithMaster(aeEventLoop *el, int fd, void *privdata, int mask) {
...
@@ -1302,6 +1339,18 @@ void syncWithMaster(aeEventLoop *el, int fd, void *privdata, int mask) {
sdsfree
(
err
);
sdsfree
(
err
);
}
}
/* Inform the master we don't want to synchronize if we are using
* repl-no-sync mode. */
if
(
server
.
repl_no_sync
)
{
err
=
sendSynchronousCommand
(
fd
,
"REPLCONF"
,
"use-sync"
,
"0"
,
NULL
);
if
(
err
[
0
]
==
'-'
)
{
redisLog
(
REDIS_WARNING
,
"Unable to enable no-sync mode: %s"
,
err
);
sdsfree
(
err
);
goto
error
;
}
sdsfree
(
err
);
}
/* Set the slave port, so that Master's INFO command can list the
/* Set the slave port, so that Master's INFO command can list the
* slave listening port correctly. */
* slave listening port correctly. */
{
{
...
@@ -1698,6 +1747,7 @@ void refreshGoodSlavesCount(void) {
...
@@ -1698,6 +1747,7 @@ void refreshGoodSlavesCount(void) {
time_t
lag
=
server
.
unixtime
-
slave
->
repl_ack_time
;
time_t
lag
=
server
.
unixtime
-
slave
->
repl_ack_time
;
if
(
slave
->
replstate
==
REDIS_REPL_ONLINE
&&
if
(
slave
->
replstate
==
REDIS_REPL_ONLINE
&&
!
(
slave
->
flags
&
REDIS_SLAVE_NO_SYNC
)
&&
lag
<=
server
.
repl_min_slaves_max_lag
)
good
++
;
lag
<=
server
.
repl_min_slaves_max_lag
)
good
++
;
}
}
server
.
repl_good_slaves_count
=
good
;
server
.
repl_good_slaves_count
=
good
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment