Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xindoo
redis
提交
7c4b8f29
R
redis
项目概览
xindoo
/
redis
通知
2
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
redis
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
7c4b8f29
编写于
9月 26, 2013
作者:
A
antirez
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Cluster: react faster when a slave wins an election.
上级
42fa46e4
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
45 addition
and
15 deletion
+45
-15
src/cluster.c
src/cluster.c
+39
-14
src/redis.c
src/redis.c
+3
-0
src/redis.h
src/redis.h
+3
-1
未找到文件。
src/cluster.c
浏览文件 @
7c4b8f29
...
...
@@ -53,6 +53,7 @@ int clusterDelSlot(int slot);
int
clusterDelNodeSlots
(
clusterNode
*
node
);
int
clusterNodeSetSlotBit
(
clusterNode
*
n
,
int
slot
);
void
clusterSetMaster
(
clusterNode
*
n
);
void
clusterHandleSlaveFailover
(
void
);
int
bitmapTestBit
(
unsigned
char
*
bitmap
,
int
pos
);
/* -----------------------------------------------------------------------------
...
...
@@ -1191,6 +1192,9 @@ int clusterProcessPacket(clusterLink *link) {
senderCurrentEpoch
==
server
.
cluster
->
currentEpoch
)
{
server
.
cluster
->
failover_auth_count
++
;
/* Maybe we reached a quorum here, set a flag to make sure
* we check ASAP. */
server
.
cluster
->
handle_slave_failover_asap
++
;
}
}
else
{
redisLog
(
REDIS_WARNING
,
"Received unknown packet type: %d"
,
type
);
...
...
@@ -1291,7 +1295,11 @@ void clusterReadHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
}
}
/* Put stuff into the send buffer. */
/* Put stuff into the send buffer.
*
* It is guaranteed that this function will never have as a side effect
* the link to be invalidated, so it is safe to call this function
* from event handlers that will do stuff with the same link later. */
void
clusterSendMessage
(
clusterLink
*
link
,
unsigned
char
*
msg
,
size_t
msglen
)
{
if
(
sdslen
(
link
->
sndbuf
)
==
0
&&
msglen
!=
0
)
aeCreateFileEvent
(
server
.
el
,
link
->
fd
,
AE_WRITABLE
,
...
...
@@ -1301,7 +1309,11 @@ void clusterSendMessage(clusterLink *link, unsigned char *msg, size_t msglen) {
}
/* Send a message to all the nodes that are part of the cluster having
* a connected link. */
* a connected link.
*
* It is guaranteed that this function will never have as a side effect
* some node->link to be invalidated, so it is safe to call this function
* from event handlers that will do stuff with node links later. */
void
clusterBroadcastMessage
(
void
*
buf
,
size_t
len
)
{
dictIterator
*
di
;
dictEntry
*
de
;
...
...
@@ -1416,10 +1428,11 @@ void clusterSendPing(clusterLink *link, int type) {
clusterSendMessage
(
link
,
buf
,
totlen
);
}
/* Send a PONG packet to every connected node that's not in handshake state.
/* Send a PONG packet to every connected node that's not in handshake state
* and for which we have a valid link.
*
* In Redis Cluster p
ings are not just used
for failure detection, but also
* to carry important configuration information
s
. So broadcasting a pong is
* In Redis Cluster p
ongs are not used just
for failure detection, but also
* to carry important configuration information. So broadcasting a pong is
* useful when something changes in the configuration and we want to make
* the cluster aware ASAP (for instance after a slave promotion). */
void
clusterBroadcastPong
(
void
)
{
...
...
@@ -1430,6 +1443,7 @@ void clusterBroadcastPong(void) {
while
((
de
=
dictNext
(
di
))
!=
NULL
)
{
clusterNode
*
node
=
dictGetVal
(
de
);
if
(
!
node
->
link
)
continue
;
if
(
node
->
flags
&
(
REDIS_NODE_MYSELF
|
REDIS_NODE_HANDSHAKE
))
continue
;
clusterSendPing
(
node
->
link
,
CLUSTERMSG_TYPE_PONG
);
}
...
...
@@ -1591,6 +1605,15 @@ void clusterHandleSlaveFailover(void) {
int
needed_quorum
=
(
server
.
cluster
->
size
/
2
)
+
1
;
int
j
;
/* Pre conditions to run the function:
* 1) We are a slave.
* 2) Our master is flagged as FAIL.
* 3) It is serving slots. */
if
(
!
(
server
.
cluster
->
myself
->
flags
&
REDIS_NODE_SLAVE
)
||
server
.
cluster
->
myself
->
slaveof
==
NULL
||
!
(
server
.
cluster
->
myself
->
slaveof
->
flags
&
REDIS_NODE_FAIL
)
||
server
.
cluster
->
myself
->
slaveof
->
numslots
==
0
)
return
;
/* Remove the node timeout from the data age as it is fine that we are
* disconnected from our master at least for the time it was down to be
* flagged as FAIL, that's the baseline. */
...
...
@@ -1834,17 +1857,19 @@ void clusterCron(void) {
server
.
cluster
->
myself
->
slaveof
->
port
);
}
/* If we are a slave and our master is down, but is serving slots,
* call the function that handles the failover. */
if
(
server
.
cluster
->
myself
->
flags
&
REDIS_NODE_SLAVE
&&
server
.
cluster
->
myself
->
slaveof
&&
server
.
cluster
->
myself
->
slaveof
->
flags
&
REDIS_NODE_FAIL
&&
server
.
cluster
->
myself
->
slaveof
->
numslots
!=
0
)
{
clusterHandleSlaveFailover
();
if
(
update_state
)
clusterUpdateState
();
}
/* This function is called before the event handler returns to sleep for
* events. It is useful to perform operations that must be done ASAP in
* reaction to events fired but that are not safe to perform inside event
* handlers. */
void
clusterBeforeSleep
(
void
)
{
if
(
server
.
cluster
->
handle_slave_failover_asap
)
{
clusterHandleSlaveFailover
();
server
.
cluster
->
handle_slave_failover_asap
=
0
;
}
if
(
update_state
)
clusterUpdateState
();
}
/* -----------------------------------------------------------------------------
...
...
src/redis.c
浏览文件 @
7c4b8f29
...
...
@@ -1203,6 +1203,9 @@ void beforeSleep(struct aeEventLoop *eventLoop) {
/* Write the AOF buffer on disk */
flushAppendOnlyFile
(
0
);
/* Call the Redis Cluster before sleep function. */
if
(
server
.
cluster_enabled
)
clusterBeforeSleep
();
}
/* =========================== Server initialization ======================== */
...
...
src/redis.h
浏览文件 @
7c4b8f29
...
...
@@ -647,12 +647,13 @@ typedef struct {
clusterNode
*
slots
[
REDIS_CLUSTER_SLOTS
];
zskiplist
*
slots_to_keys
;
/* The following fields are used to take the slave state on elections. */
mstime_t
failover_auth_time
;
/* Time at which we'll try to get elected in ms
.
*/
mstime_t
failover_auth_time
;
/* Time at which we'll try to get elected in ms*/
int
failover_auth_count
;
/* Number of votes received so far. */
int
failover_auth_sent
;
/* True if we already asked for votes. */
uint64_t
failover_auth_epoch
;
/* Epoch of the current election. */
/* The followign fields are uesd by masters to take state on elections. */
uint64_t
last_vote_epoch
;
/* Epoch of the last vote granted. */
int
handle_slave_failover_asap
;
/* Call clusterHandleSlaveFailover() ASAP. */
}
clusterState
;
/* Redis cluster messages header */
...
...
@@ -1380,6 +1381,7 @@ void clusterCron(void);
clusterNode
*
getNodeByQuery
(
redisClient
*
c
,
struct
redisCommand
*
cmd
,
robj
**
argv
,
int
argc
,
int
*
hashslot
,
int
*
ask
);
void
clusterPropagatePublish
(
robj
*
channel
,
robj
*
message
);
void
migrateCloseTimedoutSockets
(
void
);
void
clusterBeforeSleep
(
void
);
/* Sentinel */
void
initSentinelConfig
(
void
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录