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
9d4ded7e
Commit
9d4ded7e
authored
Jan 29, 2014
by
antirez
Browse files
Cluster: refactoring: new macros to check node flags.
parent
099bd336
Changes
2
Hide whitespace changes
Inline
Side-by-side
src/cluster.c
View file @
9d4ded7e
...
@@ -765,13 +765,12 @@ void markNodeAsFailingIfNeeded(clusterNode *node) {
...
@@ -765,13 +765,12 @@ void markNodeAsFailingIfNeeded(clusterNode *node) {
int
failures
;
int
failures
;
int
needed_quorum
=
(
server
.
cluster
->
size
/
2
)
+
1
;
int
needed_quorum
=
(
server
.
cluster
->
size
/
2
)
+
1
;
if
(
!
(
node
->
flags
&
REDIS_NODE_PFAIL
))
return
;
/* We can reach it. */
if
(
!
node
TimedOut
(
node
))
return
;
/* We can reach it. */
if
(
node
->
flags
&
REDIS_NODE_FAIL
)
return
;
/* Already FAILing. */
if
(
node
Failed
(
node
)
)
return
;
/* Already FAILing. */
failures
=
clusterNodeFailureReportsCount
(
node
);
failures
=
clusterNodeFailureReportsCount
(
node
);
/* Also count myself as a voter if I'm a master. */
/* Also count myself as a voter if I'm a master. */
if
(
myself
->
flags
&
REDIS_NODE_MASTER
)
if
(
nodeIsMaster
(
myself
))
failures
++
;
failures
+=
1
;
if
(
failures
<
needed_quorum
)
return
;
/* No weak agreement from masters. */
if
(
failures
<
needed_quorum
)
return
;
/* No weak agreement from masters. */
redisLog
(
REDIS_NOTICE
,
redisLog
(
REDIS_NOTICE
,
...
@@ -784,7 +783,7 @@ void markNodeAsFailingIfNeeded(clusterNode *node) {
...
@@ -784,7 +783,7 @@ void markNodeAsFailingIfNeeded(clusterNode *node) {
/* Broadcast the failing node name to everybody, forcing all the other
/* Broadcast the failing node name to everybody, forcing all the other
* reachable nodes to flag the node as FAIL. */
* reachable nodes to flag the node as FAIL. */
if
(
myself
->
flags
&
REDIS_NODE_MASTER
)
clusterSendFail
(
node
->
name
);
if
(
nodeIsMaster
(
myself
)
)
clusterSendFail
(
node
->
name
);
clusterDoBeforeSleep
(
CLUSTER_TODO_UPDATE_STATE
|
CLUSTER_TODO_SAVE_CONFIG
);
clusterDoBeforeSleep
(
CLUSTER_TODO_UPDATE_STATE
|
CLUSTER_TODO_SAVE_CONFIG
);
}
}
...
@@ -794,11 +793,11 @@ void markNodeAsFailingIfNeeded(clusterNode *node) {
...
@@ -794,11 +793,11 @@ void markNodeAsFailingIfNeeded(clusterNode *node) {
void
clearNodeFailureIfNeeded
(
clusterNode
*
node
)
{
void
clearNodeFailureIfNeeded
(
clusterNode
*
node
)
{
mstime_t
now
=
mstime
();
mstime_t
now
=
mstime
();
redisAssert
(
node
->
flags
&
REDIS_NODE_FAIL
);
redisAssert
(
node
Failed
(
node
)
);
/* For slaves we always clear the FAIL flag if we can contact the
/* For slaves we always clear the FAIL flag if we can contact the
* node again. */
* node again. */
if
(
node
->
flags
&
REDIS_NODE_SLAVE
)
{
if
(
node
IsSlave
(
node
)
)
{
redisLog
(
REDIS_NOTICE
,
redisLog
(
REDIS_NOTICE
,
"Clear FAIL state for node %.40s: slave is reachable again."
,
"Clear FAIL state for node %.40s: slave is reachable again."
,
node
->
name
);
node
->
name
);
...
@@ -810,8 +809,7 @@ void clearNodeFailureIfNeeded(clusterNode *node) {
...
@@ -810,8 +809,7 @@ void clearNodeFailureIfNeeded(clusterNode *node) {
* 1) The FAIL state is old enough.
* 1) The FAIL state is old enough.
* 2) It is yet serving slots from our point of view (not failed over).
* 2) It is yet serving slots from our point of view (not failed over).
* Apparently no one is going to fix these slots, clear the FAIL flag. */
* Apparently no one is going to fix these slots, clear the FAIL flag. */
if
(
node
->
flags
&
REDIS_NODE_MASTER
&&
if
(
nodeIsMaster
(
node
)
&&
node
->
numslots
>
0
&&
node
->
numslots
>
0
&&
(
now
-
node
->
fail_time
)
>
(
now
-
node
->
fail_time
)
>
(
server
.
cluster_node_timeout
*
REDIS_CLUSTER_FAIL_UNDO_TIME_MULT
))
(
server
.
cluster_node_timeout
*
REDIS_CLUSTER_FAIL_UNDO_TIME_MULT
))
{
{
...
@@ -834,7 +832,7 @@ int clusterHandshakeInProgress(char *ip, int port) {
...
@@ -834,7 +832,7 @@ int clusterHandshakeInProgress(char *ip, int port) {
while
((
de
=
dictNext
(
di
))
!=
NULL
)
{
while
((
de
=
dictNext
(
di
))
!=
NULL
)
{
clusterNode
*
node
=
dictGetVal
(
de
);
clusterNode
*
node
=
dictGetVal
(
de
);
if
(
!
(
node
->
flags
&
REDIS_NODE_HANDSHAKE
))
continue
;
if
(
!
node
InHandshake
(
node
))
continue
;
if
(
!
strcasecmp
(
node
->
ip
,
ip
)
&&
node
->
port
==
port
)
break
;
if
(
!
strcasecmp
(
node
->
ip
,
ip
)
&&
node
->
port
==
port
)
break
;
}
}
dictReleaseIterator
(
di
);
dictReleaseIterator
(
di
);
...
@@ -935,7 +933,7 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) {
...
@@ -935,7 +933,7 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) {
if
(
node
)
{
if
(
node
)
{
/* We already know this node.
/* We already know this node.
Handle failure reports, only when the sender is a master. */
Handle failure reports, only when the sender is a master. */
if
(
sender
&&
sender
->
flags
&
REDIS_NODE_MASTER
&&
node
!=
myself
)
{
if
(
sender
&&
nodeIsMaster
(
sender
)
&&
node
!=
myself
)
{
if
(
flags
&
(
REDIS_NODE_FAIL
|
REDIS_NODE_PFAIL
))
{
if
(
flags
&
(
REDIS_NODE_FAIL
|
REDIS_NODE_PFAIL
))
{
if
(
clusterNodeAddFailureReport
(
node
,
sender
))
{
if
(
clusterNodeAddFailureReport
(
node
,
sender
))
{
redisLog
(
REDIS_VERBOSE
,
redisLog
(
REDIS_VERBOSE
,
...
@@ -1033,7 +1031,7 @@ int nodeUpdateAddressIfNeeded(clusterNode *node, clusterLink *link, int port) {
...
@@ -1033,7 +1031,7 @@ int nodeUpdateAddressIfNeeded(clusterNode *node, clusterLink *link, int port) {
/* Check if this is our master and we have to change the
/* Check if this is our master and we have to change the
* replication target as well. */
* replication target as well. */
if
(
myself
->
flags
&
REDIS_NODE_SLAVE
&&
myself
->
slaveof
==
node
)
if
(
nodeIsSlave
(
myself
)
&&
myself
->
slaveof
==
node
)
replicationSetMaster
(
node
->
ip
,
node
->
port
);
replicationSetMaster
(
node
->
ip
,
node
->
port
);
return
1
;
return
1
;
}
}
...
@@ -1042,7 +1040,7 @@ int nodeUpdateAddressIfNeeded(clusterNode *node, clusterLink *link, int port) {
...
@@ -1042,7 +1040,7 @@ int nodeUpdateAddressIfNeeded(clusterNode *node, clusterLink *link, int port) {
* a node that we believed to be a slave is now acting as master in order to
* a node that we believed to be a slave is now acting as master in order to
* update the state of the node. */
* update the state of the node. */
void
clusterSetNodeAsMaster
(
clusterNode
*
n
)
{
void
clusterSetNodeAsMaster
(
clusterNode
*
n
)
{
if
(
n
->
flags
&
REDIS_NODE_MASTER
)
return
;
if
(
n
odeIsMaster
(
n
)
)
return
;
if
(
n
->
slaveof
)
clusterNodeRemoveSlave
(
n
->
slaveof
,
n
);
if
(
n
->
slaveof
)
clusterNodeRemoveSlave
(
n
->
slaveof
,
n
);
n
->
flags
&=
~
REDIS_NODE_SLAVE
;
n
->
flags
&=
~
REDIS_NODE_SLAVE
;
...
@@ -1074,10 +1072,7 @@ void clusterUpdateSlotsConfigWith(clusterNode *sender, uint64_t senderConfigEpoc
...
@@ -1074,10 +1072,7 @@ void clusterUpdateSlotsConfigWith(clusterNode *sender, uint64_t senderConfigEpoc
/* Here we set curmaster to this node or the node this node
/* Here we set curmaster to this node or the node this node
* replicates to if it's a slave. In the for loop we are
* replicates to if it's a slave. In the for loop we are
* interested to check if slots are taken away from curmaster. */
* interested to check if slots are taken away from curmaster. */
if
(
myself
->
flags
&
REDIS_NODE_MASTER
)
curmaster
=
nodeIsMaster
(
myself
)
?
myself
:
myself
->
slaveof
;
curmaster
=
myself
;
else
curmaster
=
myself
->
slaveof
;
for
(
j
=
0
;
j
<
REDIS_CLUSTER_SLOTS
;
j
++
)
{
for
(
j
=
0
;
j
<
REDIS_CLUSTER_SLOTS
;
j
++
)
{
if
(
bitmapTestBit
(
slots
,
j
))
{
if
(
bitmapTestBit
(
slots
,
j
))
{
...
@@ -1175,7 +1170,7 @@ int clusterProcessPacket(clusterLink *link) {
...
@@ -1175,7 +1170,7 @@ int clusterProcessPacket(clusterLink *link) {
/* Check if the sender is a known node. */
/* Check if the sender is a known node. */
sender
=
clusterLookupNode
(
hdr
->
sender
);
sender
=
clusterLookupNode
(
hdr
->
sender
);
if
(
sender
&&
!
(
sender
->
flags
&
REDIS_NODE_HANDSHAKE
))
{
if
(
sender
&&
!
nodeInHandshake
(
sender
))
{
/* Update our curretEpoch if we see a newer epoch in the cluster. */
/* Update our curretEpoch if we see a newer epoch in the cluster. */
senderCurrentEpoch
=
ntohu64
(
hdr
->
currentEpoch
);
senderCurrentEpoch
=
ntohu64
(
hdr
->
currentEpoch
);
senderConfigEpoch
=
ntohu64
(
hdr
->
configEpoch
);
senderConfigEpoch
=
ntohu64
(
hdr
->
configEpoch
);
...
@@ -1221,7 +1216,7 @@ int clusterProcessPacket(clusterLink *link) {
...
@@ -1221,7 +1216,7 @@ int clusterProcessPacket(clusterLink *link) {
type
==
CLUSTERMSG_TYPE_PING
?
"ping"
:
"pong"
,
type
==
CLUSTERMSG_TYPE_PING
?
"ping"
:
"pong"
,
(
void
*
)
link
->
node
);
(
void
*
)
link
->
node
);
if
(
link
->
node
)
{
if
(
link
->
node
)
{
if
(
link
->
node
->
flags
&
REDIS_NODE_HANDSHAKE
)
{
if
(
nodeInHandshake
(
link
->
node
)
)
{
/* If we already have this node, try to change the
/* If we already have this node, try to change the
* IP/port of the node with the new one. */
* IP/port of the node with the new one. */
if
(
sender
)
{
if
(
sender
)
{
...
@@ -1264,7 +1259,7 @@ int clusterProcessPacket(clusterLink *link) {
...
@@ -1264,7 +1259,7 @@ int clusterProcessPacket(clusterLink *link) {
/* Update the node address if it changed. */
/* Update the node address if it changed. */
if
(
sender
&&
type
==
CLUSTERMSG_TYPE_PING
&&
if
(
sender
&&
type
==
CLUSTERMSG_TYPE_PING
&&
!
(
sender
->
flags
&
REDIS_NODE_HANDSHAKE
)
&&
!
nodeInHandshake
(
sender
)
&&
nodeUpdateAddressIfNeeded
(
sender
,
link
,
ntohs
(
hdr
->
port
)))
nodeUpdateAddressIfNeeded
(
sender
,
link
,
ntohs
(
hdr
->
port
)))
{
{
clusterDoBeforeSleep
(
CLUSTER_TODO_SAVE_CONFIG
|
CLUSTER_TODO_UPDATE_STATE
);
clusterDoBeforeSleep
(
CLUSTER_TODO_SAVE_CONFIG
|
CLUSTER_TODO_UPDATE_STATE
);
...
@@ -1281,11 +1276,11 @@ int clusterProcessPacket(clusterLink *link) {
...
@@ -1281,11 +1276,11 @@ int clusterProcessPacket(clusterLink *link) {
*
*
* The FAIL condition is also reversible under specific
* The FAIL condition is also reversible under specific
* conditions detected by clearNodeFailureIfNeeded(). */
* conditions detected by clearNodeFailureIfNeeded(). */
if
(
link
->
node
->
flags
&
REDIS_NODE_PFAIL
)
{
if
(
nodeTimedOut
(
link
->
node
)
)
{
link
->
node
->
flags
&=
~
REDIS_NODE_PFAIL
;
link
->
node
->
flags
&=
~
REDIS_NODE_PFAIL
;
clusterDoBeforeSleep
(
CLUSTER_TODO_SAVE_CONFIG
|
clusterDoBeforeSleep
(
CLUSTER_TODO_SAVE_CONFIG
|
CLUSTER_TODO_UPDATE_STATE
);
CLUSTER_TODO_UPDATE_STATE
);
}
else
if
(
link
->
node
->
flags
&
REDIS_NODE_FAIL
)
{
}
else
if
(
nodeFailed
(
link
->
node
)
)
{
clearNodeFailureIfNeeded
(
link
->
node
);
clearNodeFailureIfNeeded
(
link
->
node
);
}
}
}
}
...
@@ -1301,7 +1296,7 @@ int clusterProcessPacket(clusterLink *link) {
...
@@ -1301,7 +1296,7 @@ int clusterProcessPacket(clusterLink *link) {
/* Node is a slave. */
/* Node is a slave. */
clusterNode
*
master
=
clusterLookupNode
(
hdr
->
slaveof
);
clusterNode
*
master
=
clusterLookupNode
(
hdr
->
slaveof
);
if
(
sender
->
flags
&
REDIS_NODE_MASTER
)
{
if
(
nodeIsMaster
(
sender
)
)
{
/* Master turned into a slave! Reconfigure the node. */
/* Master turned into a slave! Reconfigure the node. */
clusterDelNodeSlots
(
sender
);
clusterDelNodeSlots
(
sender
);
sender
->
flags
&=
~
REDIS_NODE_MASTER
;
sender
->
flags
&=
~
REDIS_NODE_MASTER
;
...
@@ -1341,8 +1336,7 @@ int clusterProcessPacket(clusterLink *link) {
...
@@ -1341,8 +1336,7 @@ int clusterProcessPacket(clusterLink *link) {
int
dirty_slots
=
0
;
/* Sender claimed slots don't match my view? */
int
dirty_slots
=
0
;
/* Sender claimed slots don't match my view? */
if
(
sender
)
{
if
(
sender
)
{
sender_master
=
(
sender
->
flags
&
REDIS_NODE_MASTER
)
?
sender_master
=
nodeIsMaster
(
sender
)
?
sender
:
sender
->
slaveof
;
sender
:
sender
->
slaveof
;
if
(
sender_master
)
{
if
(
sender_master
)
{
dirty_slots
=
memcmp
(
sender_master
->
slots
,
dirty_slots
=
memcmp
(
sender_master
->
slots
,
hdr
->
myslots
,
sizeof
(
hdr
->
myslots
))
!=
0
;
hdr
->
myslots
,
sizeof
(
hdr
->
myslots
))
!=
0
;
...
@@ -1352,9 +1346,8 @@ int clusterProcessPacket(clusterLink *link) {
...
@@ -1352,9 +1346,8 @@ int clusterProcessPacket(clusterLink *link) {
/* 1) If the sender of the message is a master, and we detected that
/* 1) If the sender of the message is a master, and we detected that
* the set of slots it claims changed, scan the slots to see if we
* the set of slots it claims changed, scan the slots to see if we
* need to update our configuration. */
* need to update our configuration. */
if
(
sender
&&
sender
->
flags
&
REDIS_NODE_MASTER
&&
dirty_slots
)
{
if
(
sender
&&
nodeIsMaster
(
sender
)
&&
dirty_slots
)
clusterUpdateSlotsConfigWith
(
sender
,
senderConfigEpoch
,
hdr
->
myslots
);
clusterUpdateSlotsConfigWith
(
sender
,
senderConfigEpoch
,
hdr
->
myslots
);
}
/* 2) We also check for the reverse condition, that is, the sender
/* 2) We also check for the reverse condition, that is, the sender
* claims to serve slots we know are served by a master with a
* claims to serve slots we know are served by a master with a
...
@@ -1450,8 +1443,7 @@ int clusterProcessPacket(clusterLink *link) {
...
@@ -1450,8 +1443,7 @@ int clusterProcessPacket(clusterLink *link) {
/* We consider this vote only if the sender is a master serving
/* We consider this vote only if the sender is a master serving
* a non zero number of slots, and its currentEpoch is greater or
* a non zero number of slots, and its currentEpoch is greater or
* equal to epoch where this node started the election. */
* equal to epoch where this node started the election. */
if
(
sender
->
flags
&
REDIS_NODE_MASTER
&&
if
(
nodeIsMaster
(
sender
)
&&
sender
->
numslots
>
0
&&
sender
->
numslots
>
0
&&
senderCurrentEpoch
>=
server
.
cluster
->
failover_auth_epoch
)
senderCurrentEpoch
>=
server
.
cluster
->
failover_auth_epoch
)
{
{
server
.
cluster
->
failover_auth_count
++
;
server
.
cluster
->
failover_auth_count
++
;
...
@@ -1469,7 +1461,7 @@ int clusterProcessPacket(clusterLink *link) {
...
@@ -1469,7 +1461,7 @@ int clusterProcessPacket(clusterLink *link) {
if
(
n
->
configEpoch
>=
reportedConfigEpoch
)
return
1
;
/* Nothing new. */
if
(
n
->
configEpoch
>=
reportedConfigEpoch
)
return
1
;
/* Nothing new. */
/* If in our current config the node is a slave, set it as a master. */
/* If in our current config the node is a slave, set it as a master. */
if
(
n
->
flags
&
REDIS_NODE_SLAVE
)
clusterSetNodeAsMaster
(
n
);
if
(
n
odeIsSlave
(
n
)
)
clusterSetNodeAsMaster
(
n
);
/* Check the bitmap of served slots and udpate our
/* Check the bitmap of served slots and udpate our
* config accordingly. */
* config accordingly. */
...
@@ -1620,7 +1612,7 @@ void clusterBuildMessageHdr(clusterMsg *hdr, int type) {
...
@@ -1620,7 +1612,7 @@ void clusterBuildMessageHdr(clusterMsg *hdr, int type) {
* If this node is a slave we send the master's information instead (the
* If this node is a slave we send the master's information instead (the
* node is flagged as slave so the receiver knows that it is NOT really
* node is flagged as slave so the receiver knows that it is NOT really
* in charge for this slots. */
* in charge for this slots. */
master
=
(
myself
->
flags
&
REDIS_NODE_SLAVE
&&
myself
->
slaveof
)
?
master
=
(
nodeIsSlave
(
myself
)
&&
myself
->
slaveof
)
?
myself
->
slaveof
:
myself
;
myself
->
slaveof
:
myself
;
memset
(
hdr
,
0
,
sizeof
(
*
hdr
));
memset
(
hdr
,
0
,
sizeof
(
*
hdr
));
...
@@ -1640,7 +1632,7 @@ void clusterBuildMessageHdr(clusterMsg *hdr, int type) {
...
@@ -1640,7 +1632,7 @@ void clusterBuildMessageHdr(clusterMsg *hdr, int type) {
hdr
->
configEpoch
=
htonu64
(
master
->
configEpoch
);
hdr
->
configEpoch
=
htonu64
(
master
->
configEpoch
);
/* Set the replication offset. */
/* Set the replication offset. */
if
(
myself
->
flags
&
REDIS_NODE_SLAVE
)
{
if
(
nodeIsSlave
(
myself
)
)
{
if
(
server
.
master
)
if
(
server
.
master
)
offset
=
server
.
master
->
reploff
;
offset
=
server
.
master
->
reploff
;
else
if
(
server
.
cached_master
)
else
if
(
server
.
cached_master
)
...
@@ -1754,11 +1746,10 @@ void clusterBroadcastPong(int target) {
...
@@ -1754,11 +1746,10 @@ void clusterBroadcastPong(int target) {
clusterNode
*
node
=
dictGetVal
(
de
);
clusterNode
*
node
=
dictGetVal
(
de
);
if
(
!
node
->
link
)
continue
;
if
(
!
node
->
link
)
continue
;
if
(
node
->
flags
&
(
REDIS_NODE_MYSELF
|
REDIS_NODE_HANDSHAKE
))
continue
;
if
(
node
==
myself
||
nodeInHandshake
(
node
))
continue
;
if
(
target
==
CLUSTER_BROADCAST_LOCAL_SLAVES
)
{
if
(
target
==
CLUSTER_BROADCAST_LOCAL_SLAVES
)
{
int
local_slave
=
int
local_slave
=
node
->
flags
&
REDIS_NODE_SLAVE
&&
nodeIsSlave
(
node
)
&&
node
->
slaveof
&&
node
->
slaveof
&&
(
node
->
slaveof
==
myself
||
node
->
slaveof
==
myself
->
slaveof
);
(
node
->
slaveof
==
myself
||
node
->
slaveof
==
myself
->
slaveof
);
if
(
!
local_slave
)
continue
;
if
(
!
local_slave
)
continue
;
}
}
...
@@ -1897,8 +1888,7 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) {
...
@@ -1897,8 +1888,7 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) {
* right to vote, as the cluster size in Redis Cluster is the number
* right to vote, as the cluster size in Redis Cluster is the number
* of masters serving at least one slot, and quorum is the cluster
* of masters serving at least one slot, and quorum is the cluster
* size + 1 */
* size + 1 */
if
(
!
(
myself
->
flags
&
REDIS_NODE_MASTER
))
return
;
if
(
nodeIsSlave
(
myself
)
||
myself
->
numslots
==
0
)
return
;
if
(
myself
->
numslots
==
0
)
return
;
/* Request epoch must be >= our currentEpoch. */
/* Request epoch must be >= our currentEpoch. */
if
(
requestCurrentEpoch
<
server
.
cluster
->
currentEpoch
)
return
;
if
(
requestCurrentEpoch
<
server
.
cluster
->
currentEpoch
)
return
;
...
@@ -1907,9 +1897,7 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) {
...
@@ -1907,9 +1897,7 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) {
if
(
server
.
cluster
->
last_vote_epoch
==
server
.
cluster
->
currentEpoch
)
return
;
if
(
server
.
cluster
->
last_vote_epoch
==
server
.
cluster
->
currentEpoch
)
return
;
/* Node must be a slave and its master down. */
/* Node must be a slave and its master down. */
if
(
!
(
node
->
flags
&
REDIS_NODE_SLAVE
)
||
if
(
nodeIsMaster
(
node
)
||
master
==
NULL
||
!
nodeFailed
(
master
))
return
;
master
==
NULL
||
!
(
master
->
flags
&
REDIS_NODE_FAIL
))
return
;
/* We did not voted for a slave about this master for two
/* We did not voted for a slave about this master for two
* times the node timeout. This is not strictly needed for correctness
* times the node timeout. This is not strictly needed for correctness
...
@@ -1962,9 +1950,9 @@ void clusterHandleSlaveFailover(void) {
...
@@ -1962,9 +1950,9 @@ void clusterHandleSlaveFailover(void) {
* 1) We are a slave.
* 1) We are a slave.
* 2) Our master is flagged as FAIL.
* 2) Our master is flagged as FAIL.
* 3) It is serving slots. */
* 3) It is serving slots. */
if
(
!
(
myself
->
flags
&
REDIS_NODE_SLAVE
)
||
if
(
nodeIsMaster
(
myself
)
||
myself
->
slaveof
==
NULL
||
myself
->
slaveof
==
NULL
||
!
(
myself
->
slaveof
->
flags
&
REDIS_NODE_FAIL
)
||
!
nodeFailed
(
myself
->
slaveof
)
||
myself
->
slaveof
->
numslots
==
0
)
return
;
myself
->
slaveof
->
numslots
==
0
)
return
;
/* Remove the node timeout from the data age as it is fine that we are
/* Remove the node timeout from the data age as it is fine that we are
...
@@ -2086,9 +2074,7 @@ void clusterCron(void) {
...
@@ -2086,9 +2074,7 @@ void clusterCron(void) {
/* A Node in HANDSHAKE state has a limited lifespan equal to the
/* A Node in HANDSHAKE state has a limited lifespan equal to the
* configured node timeout. */
* configured node timeout. */
if
(
node
->
flags
&
REDIS_NODE_HANDSHAKE
&&
if
(
nodeInHandshake
(
node
)
&&
now
-
node
->
ctime
>
handshake_timeout
)
{
now
-
node
->
ctime
>
handshake_timeout
)
{
freeClusterNode
(
node
);
freeClusterNode
(
node
);
continue
;
continue
;
}
}
...
@@ -2217,10 +2203,10 @@ void clusterCron(void) {
...
@@ -2217,10 +2203,10 @@ void clusterCron(void) {
/* If we are a slave node but the replication is still turned off,
/* If we are a slave node but the replication is still turned off,
* enable it if we know the address of our master and it appears to
* enable it if we know the address of our master and it appears to
* be up. */
* be up. */
if
(
myself
->
flags
&
REDIS_NODE_SLAVE
&&
if
(
nodeIsSlave
(
myself
)
&&
server
.
masterhost
==
NULL
&&
server
.
masterhost
==
NULL
&&
myself
->
slaveof
&&
myself
->
slaveof
&&
!
(
myself
->
slaveof
->
flags
&
REDIS_NODE_NOADDR
))
nodeHasAddr
(
myself
->
slaveof
))
{
{
replicationSetMaster
(
myself
->
slaveof
->
ip
,
myself
->
slaveof
->
port
);
replicationSetMaster
(
myself
->
slaveof
->
ip
,
myself
->
slaveof
->
port
);
}
}
...
@@ -2366,7 +2352,7 @@ void clusterUpdateState(void) {
...
@@ -2366,7 +2352,7 @@ void clusterUpdateState(void) {
* the first call to this function and not since the server start, in order
* the first call to this function and not since the server start, in order
* to don't count the DB loading time. */
* to don't count the DB loading time. */
if
(
first_call_time
==
0
)
first_call_time
=
mstime
();
if
(
first_call_time
==
0
)
first_call_time
=
mstime
();
if
(
myself
->
flags
&
REDIS_NODE_MASTER
&&
if
(
nodeIsMaster
(
myself
)
&&
mstime
()
-
first_call_time
<
REDIS_CLUSTER_WRITABLE_DELAY
)
return
;
mstime
()
-
first_call_time
<
REDIS_CLUSTER_WRITABLE_DELAY
)
return
;
/* Start assuming the state is OK. We'll turn it into FAIL if there
/* Start assuming the state is OK. We'll turn it into FAIL if there
...
@@ -2397,7 +2383,7 @@ void clusterUpdateState(void) {
...
@@ -2397,7 +2383,7 @@ void clusterUpdateState(void) {
while
((
de
=
dictNext
(
di
))
!=
NULL
)
{
while
((
de
=
dictNext
(
di
))
!=
NULL
)
{
clusterNode
*
node
=
dictGetVal
(
de
);
clusterNode
*
node
=
dictGetVal
(
de
);
if
(
node
->
flags
&
REDIS_NODE_MASTER
&&
node
->
numslots
)
{
if
(
node
IsMaster
(
node
)
&&
node
->
numslots
)
{
server
.
cluster
->
size
++
;
server
.
cluster
->
size
++
;
if
(
node
->
flags
&
(
REDIS_NODE_FAIL
|
REDIS_NODE_PFAIL
))
if
(
node
->
flags
&
(
REDIS_NODE_FAIL
|
REDIS_NODE_PFAIL
))
unreachable_masters
++
;
unreachable_masters
++
;
...
@@ -2432,7 +2418,7 @@ void clusterUpdateState(void) {
...
@@ -2432,7 +2418,7 @@ void clusterUpdateState(void) {
rejoin_delay
=
REDIS_CLUSTER_MIN_REJOIN_DELAY
;
rejoin_delay
=
REDIS_CLUSTER_MIN_REJOIN_DELAY
;
if
(
new_state
==
REDIS_CLUSTER_OK
&&
if
(
new_state
==
REDIS_CLUSTER_OK
&&
myself
->
flags
&
REDIS_NODE_MASTER
&&
nodeIsMaster
(
myself
)
&&
mstime
()
-
among_minority_time
<
rejoin_delay
)
mstime
()
-
among_minority_time
<
rejoin_delay
)
{
{
return
;
return
;
...
@@ -2473,7 +2459,7 @@ int verifyClusterConfigWithData(void) {
...
@@ -2473,7 +2459,7 @@ int verifyClusterConfigWithData(void) {
/* If this node is a slave, don't perform the check at all as we
/* If this node is a slave, don't perform the check at all as we
* completely depend on the replication stream. */
* completely depend on the replication stream. */
if
(
myself
->
flags
&
REDIS_NODE_SLAVE
)
return
REDIS_OK
;
if
(
nodeIsSlave
(
myself
)
)
return
REDIS_OK
;
/* Make sure we only have keys in DB0. */
/* Make sure we only have keys in DB0. */
for
(
j
=
1
;
j
<
server
.
dbnum
;
j
++
)
{
for
(
j
=
1
;
j
<
server
.
dbnum
;
j
++
)
{
...
@@ -2522,7 +2508,7 @@ void clusterSetMaster(clusterNode *n) {
...
@@ -2522,7 +2508,7 @@ void clusterSetMaster(clusterNode *n) {
redisAssert
(
n
!=
myself
);
redisAssert
(
n
!=
myself
);
redisAssert
(
myself
->
numslots
==
0
);
redisAssert
(
myself
->
numslots
==
0
);
if
(
myself
->
flags
&
REDIS_NODE_MASTER
)
{
if
(
nodeIsMaster
(
myself
)
)
{
myself
->
flags
&=
~
REDIS_NODE_MASTER
;
myself
->
flags
&=
~
REDIS_NODE_MASTER
;
myself
->
flags
|=
REDIS_NODE_SLAVE
;
myself
->
flags
|=
REDIS_NODE_SLAVE
;
}
else
{
}
else
{
...
@@ -2830,9 +2816,9 @@ void clusterCommand(redisClient *c) {
...
@@ -2830,9 +2816,9 @@ void clusterCommand(redisClient *c) {
if
(
n
==
NULL
)
continue
;
if
(
n
==
NULL
)
continue
;
slots_assigned
++
;
slots_assigned
++
;
if
(
n
->
flags
&
REDIS_NODE_FAIL
)
{
if
(
n
odeFailed
(
n
)
)
{
slots_fail
++
;
slots_fail
++
;
}
else
if
(
n
->
flags
&
REDIS_NODE_PFAIL
)
{
}
else
if
(
n
odeTimedOut
(
n
)
)
{
slots_pfail
++
;
slots_pfail
++
;
}
else
{
}
else
{
slots_ok
++
;
slots_ok
++
;
...
@@ -2919,7 +2905,7 @@ void clusterCommand(redisClient *c) {
...
@@ -2919,7 +2905,7 @@ void clusterCommand(redisClient *c) {
}
else
if
(
n
==
myself
)
{
}
else
if
(
n
==
myself
)
{
addReplyError
(
c
,
"I tried hard but I can't forget myself..."
);
addReplyError
(
c
,
"I tried hard but I can't forget myself..."
);
return
;
return
;
}
else
if
(
myself
->
flags
&
REDIS_NODE_SLAVE
&&
myself
->
slaveof
==
n
)
{
}
else
if
(
nodeIsSlave
(
myself
)
&&
myself
->
slaveof
==
n
)
{
addReplyError
(
c
,
"Can't forget my master!"
);
addReplyError
(
c
,
"Can't forget my master!"
);
return
;
return
;
}
}
...
@@ -2952,10 +2938,8 @@ void clusterCommand(redisClient *c) {
...
@@ -2952,10 +2938,8 @@ void clusterCommand(redisClient *c) {
/* If the instance is currently a master, it should have no assigned
/* If the instance is currently a master, it should have no assigned
* slots nor keys to accept to replicate some other node.
* slots nor keys to accept to replicate some other node.
* Slaves can switch to another master without issues. */
* Slaves can switch to another master without issues. */
if
(
myself
->
flags
&
REDIS_NODE_MASTER
&&
if
(
nodeIsMaster
(
myself
)
&&
(
myself
->
numslots
!=
0
||
(
myself
->
numslots
!=
0
||
dictSize
(
server
.
db
[
0
].
dict
)
!=
0
))
{
dictSize
(
server
.
db
[
0
].
dict
)
!=
0
))
{
addReplyError
(
c
,
"To set a master the node must be empty and without assigned slots."
);
addReplyError
(
c
,
"To set a master the node must be empty and without assigned slots."
);
return
;
return
;
}
}
...
@@ -2975,7 +2959,7 @@ void clusterCommand(redisClient *c) {
...
@@ -2975,7 +2959,7 @@ void clusterCommand(redisClient *c) {
return
;
return
;
}
}
if
(
n
->
flags
&
REDIS_NODE_SLAVE
)
{
if
(
n
odeIsSlave
(
n
)
)
{
addReplyError
(
c
,
"The specified node is not a master"
);
addReplyError
(
c
,
"The specified node is not a master"
);
return
;
return
;
}
}
...
@@ -3521,7 +3505,7 @@ clusterNode *getNodeByQuery(redisClient *c, struct redisCommand *cmd, robj **arg
...
@@ -3521,7 +3505,7 @@ clusterNode *getNodeByQuery(redisClient *c, struct redisCommand *cmd, robj **arg
* is serving, we can reply without redirection. */
* is serving, we can reply without redirection. */
if
(
c
->
flags
&
REDIS_READONLY
&&
if
(
c
->
flags
&
REDIS_READONLY
&&
cmd
->
flags
&
REDIS_CMD_READONLY
&&
cmd
->
flags
&
REDIS_CMD_READONLY
&&
myself
->
flags
&
REDIS_NODE_SLAVE
&&
nodeIsSlave
(
myself
)
&&
myself
->
slaveof
==
n
)
myself
->
slaveof
==
n
)
{
{
return
myself
;
return
myself
;
...
...
src/cluster.h
View file @
9d4ded7e
...
@@ -33,7 +33,7 @@ typedef struct clusterLink {
...
@@ -33,7 +33,7 @@ typedef struct clusterLink {
struct
clusterNode
*
node
;
/* Node related to this link if any, or NULL */
struct
clusterNode
*
node
;
/* Node related to this link if any, or NULL */
}
clusterLink
;
}
clusterLink
;
/*
Node flags
*/
/*
Cluster node flags and macros.
*/
#define REDIS_NODE_MASTER 1
/* The node is a master */
#define REDIS_NODE_MASTER 1
/* The node is a master */
#define REDIS_NODE_SLAVE 2
/* The node is a slave */
#define REDIS_NODE_SLAVE 2
/* The node is a slave */
#define REDIS_NODE_PFAIL 4
/* Failure? Need acknowledge */
#define REDIS_NODE_PFAIL 4
/* Failure? Need acknowledge */
...
@@ -45,6 +45,14 @@ typedef struct clusterLink {
...
@@ -45,6 +45,14 @@ typedef struct clusterLink {
#define REDIS_NODE_PROMOTED 256
/* Master was a slave propoted by failover */
#define REDIS_NODE_PROMOTED 256
/* Master was a slave propoted by failover */
#define REDIS_NODE_NULL_NAME "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
#define REDIS_NODE_NULL_NAME "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
#define nodeIsMaster(n) ((n)->flags & REDIS_NODE_MASTER)
#define nodeIsSlave(n) ((n)->flags & REDIS_NODE_SLAVE)
#define nodeInHandshake(n) ((n)->flags & REDIS_NODE_HANDSHAKE)
#define nodeHasAddr(n) (!((n)->flags & REDIS_NODE_NOADDR))
#define nodeWithoutAddr(n) ((n)->flags & REDIS_NODE_NOADDR)
#define nodeTimedOut(n) ((n)->flags & REDIS_NODE_PFAIL)
#define nodeFailed(n) ((n)->flags & REDIS_NODE_FAIL)
/* This structure represent elements of node->fail_reports. */
/* This structure represent elements of node->fail_reports. */
struct
clusterNodeFailReport
{
struct
clusterNodeFailReport
{
struct
clusterNode
*
node
;
/* Node reporting the failure condition. */
struct
clusterNode
*
node
;
/* Node reporting the failure condition. */
...
...
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