Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
68e6b82a
T
TDengine
项目概览
taosdata
/
TDengine
1 年多 前同步成功
通知
1185
Star
22016
Fork
4786
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
68e6b82a
编写于
11月 19, 2021
作者:
L
lichuang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[TD-10645][raft]<feature>add vote resp process
上级
ce654f83
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
60 addition
and
30 deletion
+60
-30
source/libs/sync/inc/raft_replication.h
source/libs/sync/inc/raft_replication.h
+2
-2
source/libs/sync/inc/sync_raft_impl.h
source/libs/sync/inc/sync_raft_impl.h
+2
-0
source/libs/sync/src/raft.c
source/libs/sync/src/raft.c
+1
-1
source/libs/sync/src/raft_handle_vote_message.c
source/libs/sync/src/raft_handle_vote_message.c
+10
-8
source/libs/sync/src/raft_handle_vote_resp_message.c
source/libs/sync/src/raft_handle_vote_resp_message.c
+4
-2
source/libs/sync/src/raft_replication.c
source/libs/sync/src/raft_replication.c
+2
-2
source/libs/sync/src/sync_raft_election.c
source/libs/sync/src/sync_raft_election.c
+5
-7
source/libs/sync/src/sync_raft_impl.c
source/libs/sync/src/sync_raft_impl.c
+34
-8
未找到文件。
source/libs/sync/inc/raft_replication.h
浏览文件 @
68e6b82a
...
...
@@ -20,11 +20,11 @@
#include "syncInt.h"
#include "sync_type.h"
// syncRaft
Replicate
sends an append RPC with new entries to the given peer,
// syncRaft
MaybeSendAppend
sends an append RPC with new entries to the given peer,
// if necessary. Returns true if a message was sent. The sendIfEmpty
// argument controls whether messages with no entries will be sent
// ("empty" messages are useful to convey updated Commit indexes, but
// are undesirable when we're sending multiple messages in a batch).
bool
syncRaft
Replicate
(
SSyncRaft
*
pRaft
,
SSyncRaftProgress
*
progress
,
bool
sendIfEmpty
);
bool
syncRaft
MaybeSendAppend
(
SSyncRaft
*
pRaft
,
SSyncRaftProgress
*
progress
,
bool
sendIfEmpty
);
#endif
/* TD_SYNC_RAFT_REPLICATION_H */
source/libs/sync/inc/sync_raft_impl.h
浏览文件 @
68e6b82a
...
...
@@ -28,6 +28,8 @@ void syncRaftBecomeLeader(SSyncRaft* pRaft);
void
syncRaftStartElection
(
SSyncRaft
*
pRaft
,
ESyncRaftElectionType
cType
);
void
syncRaftCampaign
(
SSyncRaft
*
pRaft
,
ESyncRaftElectionType
cType
);
void
syncRaftTriggerHeartbeat
(
SSyncRaft
*
pRaft
);
void
syncRaftRandomizedElectionTimeout
(
SSyncRaft
*
pRaft
);
...
...
source/libs/sync/src/raft.c
浏览文件 @
68e6b82a
...
...
@@ -169,7 +169,7 @@ static int deserializeClusterStateFromBuffer(SSyncConfigState* cluster, const ch
}
static
void
visitProgressMaybeSendAppend
(
SSyncRaftProgress
*
progress
,
void
*
arg
)
{
syncRaft
Replicate
(
arg
,
progress
,
false
);
syncRaft
MaybeSendAppend
(
arg
,
progress
,
false
);
}
// switchToConfig reconfigures this node to use the provided configuration. It
...
...
source/libs/sync/src/raft_handle_vote_message.c
浏览文件 @
68e6b82a
...
...
@@ -48,12 +48,14 @@ int syncRaftHandleVoteMessage(SSyncRaft* pRaft, const SSyncMessage* pMsg) {
}
static
bool
canGrantVoteMessage
(
SSyncRaft
*
pRaft
,
const
SSyncMessage
*
pMsg
)
{
if
(
!
(
pRaft
->
voteFor
==
SYNC_NON_NODE_ID
||
pMsg
->
term
>
pRaft
->
term
||
pRaft
->
voteFor
==
pMsg
->
from
))
{
return
false
;
}
if
(
!
syncRaftLogIsUptodate
(
pRaft
->
log
,
pMsg
->
vote
.
lastIndex
,
pMsg
->
vote
.
lastTerm
))
{
return
false
;
}
return
true
;
bool
canVote
=
// We can vote if this is a repeat of a vote we've already cast...
pRaft
->
voteFor
==
pMsg
->
from
||
// ...we haven't voted and we don't think there's a leader yet in this term...
(
pRaft
->
voteFor
==
SYNC_NON_NODE_ID
&&
pRaft
->
leaderId
==
SYNC_NON_NODE_ID
)
||
// ...or this is a PreVote for a future term...
(
pMsg
->
vote
.
cType
==
SYNC_RAFT_CAMPAIGN_PRE_ELECTION
&&
pMsg
->
term
>
pRaft
->
term
);
// ...and we believe the candidate is up to date.
return
canVote
&&
syncRaftLogIsUptodate
(
pRaft
->
log
,
pMsg
->
vote
.
lastIndex
,
pMsg
->
vote
.
lastTerm
);
}
\ No newline at end of file
source/libs/sync/src/raft_handle_vote_resp_message.c
浏览文件 @
68e6b82a
...
...
@@ -45,12 +45,14 @@ int syncRaftHandleVoteRespMessage(SSyncRaft* pRaft, const SSyncMessage* pMsg) {
if
(
result
==
SYNC_RAFT_VOTE_WON
)
{
if
(
pRaft
->
candidateState
.
inPreVote
)
{
syncRaft
StartElectio
n
(
pRaft
,
SYNC_RAFT_CAMPAIGN_ELECTION
);
syncRaft
Campaig
n
(
pRaft
,
SYNC_RAFT_CAMPAIGN_ELECTION
);
}
else
{
syncRaftBecomeLeader
(
pRaft
);
syncRaftBroadcastAppend
(
pRaft
);
}
}
else
if
(
result
==
SYNC_RAFT_VOTE_LOST
)
{
// pb.MsgPreVoteResp contains future term of pre-candidate
// m.Term > r.Term; reuse r.Term
syncRaftBecomeFollower
(
pRaft
,
pRaft
->
term
,
SYNC_NON_NODE_ID
);
}
...
...
source/libs/sync/src/raft_replication.c
浏览文件 @
68e6b82a
...
...
@@ -24,12 +24,12 @@ static bool sendAppendEntries(SSyncRaft* pRaft, SSyncRaftProgress* progress,
SyncIndex
prevIndex
,
SyncTerm
prevTerm
,
SSyncRaftEntry
*
entries
,
int
nEntry
);
//
syncRaftReplicate
sends an append RPC with new entries to the given peer,
//
maybeSendAppend
sends an append RPC with new entries to the given peer,
// if necessary. Returns true if a message was sent. The sendIfEmpty
// argument controls whether messages with no entries will be sent
// ("empty" messages are useful to convey updated Commit indexes, but
// are undesirable when we're sending multiple messages in a batch).
bool
syncRaft
Replicate
(
SSyncRaft
*
pRaft
,
SSyncRaftProgress
*
progress
,
bool
sendIfEmpty
)
{
bool
syncRaft
MaybeSendAppend
(
SSyncRaft
*
pRaft
,
SSyncRaftProgress
*
progress
,
bool
sendIfEmpty
)
{
assert
(
pRaft
->
state
==
TAOS_SYNC_STATE_LEADER
);
SyncNodeId
nodeId
=
progress
->
id
;
...
...
source/libs/sync/src/sync_raft_election.c
浏览文件 @
68e6b82a
...
...
@@ -19,8 +19,6 @@
#include "raft_message.h"
#include "sync_raft_progress_tracker.h"
static
void
campaign
(
SSyncRaft
*
pRaft
,
ESyncRaftElectionType
cType
);
void
syncRaftStartElection
(
SSyncRaft
*
pRaft
,
ESyncRaftElectionType
cType
)
{
if
(
pRaft
->
state
==
TAOS_SYNC_STATE_LEADER
)
{
syncDebug
(
"[%d:%d] ignoring RAFT_MSG_INTERNAL_ELECTION because already leader"
,
pRaft
->
selfGroupId
,
pRaft
->
selfId
);
...
...
@@ -28,7 +26,7 @@ void syncRaftStartElection(SSyncRaft* pRaft, ESyncRaftElectionType cType) {
}
if
(
!
syncRaftIsPromotable
(
pRaft
))
{
syncWarn
(
"[%d:%d] is unpromotable and can not
c
ampaign"
,
pRaft
->
selfGroupId
,
pRaft
->
selfId
);
syncWarn
(
"[%d:%d] is unpromotable and can not
syncRaftC
ampaign"
,
pRaft
->
selfGroupId
,
pRaft
->
selfId
);
return
;
}
...
...
@@ -41,17 +39,17 @@ void syncRaftStartElection(SSyncRaft* pRaft, ESyncRaftElectionType cType) {
syncInfo
(
"[%d:%d] is starting a new election at term %"
PRId64
""
,
pRaft
->
selfGroupId
,
pRaft
->
selfId
,
pRaft
->
term
);
c
ampaign
(
pRaft
,
cType
);
syncRaftC
ampaign
(
pRaft
,
cType
);
}
//
c
ampaign transitions the raft instance to candidate state. This must only be
//
syncRaftC
ampaign transitions the raft instance to candidate state. This must only be
// called after verifying that this is a legitimate transition.
static
void
c
ampaign
(
SSyncRaft
*
pRaft
,
ESyncRaftElectionType
cType
)
{
void
syncRaftC
ampaign
(
SSyncRaft
*
pRaft
,
ESyncRaftElectionType
cType
)
{
bool
preVote
;
SyncTerm
term
;
if
(
syncRaftIsPromotable
(
pRaft
))
{
syncDebug
(
"[%d:%d] is unpromotable;
c
ampaign() should have been called"
,
pRaft
->
selfGroupId
,
pRaft
->
selfId
);
syncDebug
(
"[%d:%d] is unpromotable;
syncRaftC
ampaign() should have been called"
,
pRaft
->
selfGroupId
,
pRaft
->
selfId
);
return
;
}
...
...
source/libs/sync/src/sync_raft_impl.c
浏览文件 @
68e6b82a
...
...
@@ -25,6 +25,8 @@ static int stepFollower(SSyncRaft* pRaft, const SSyncMessage* pMsg);
static
int
stepCandidate
(
SSyncRaft
*
pRaft
,
const
SSyncMessage
*
pMsg
);
static
int
stepLeader
(
SSyncRaft
*
pRaft
,
const
SSyncMessage
*
pMsg
);
static
bool
increaseUncommittedSize
(
SSyncRaft
*
pRaft
,
SSyncRaftEntry
*
entries
,
int
n
);
static
int
triggerAll
(
SSyncRaft
*
pRaft
);
static
void
tickElection
(
SSyncRaft
*
pRaft
);
...
...
@@ -82,13 +84,22 @@ void syncRaftBecomeLeader(SSyncRaft* pRaft) {
resetRaft
(
pRaft
,
pRaft
->
term
);
pRaft
->
leaderId
=
pRaft
->
leaderId
;
pRaft
->
state
=
TAOS_SYNC_STATE_LEADER
;
// TODO: check if there is pending config log
int
nPendingConf
=
syncRaftLogNumOfPendingConf
(
pRaft
->
log
);
if
(
nPendingConf
>
1
)
{
syncFatal
(
"unexpected multiple uncommitted config entry"
);
}
syncInfo
(
"[%d:%d] became leader at term %"
PRId64
""
,
pRaft
->
selfGroupId
,
pRaft
->
selfId
,
pRaft
->
term
);
SSyncRaftProgress
*
progress
=
syncRaftFindProgressByNodeId
(
&
pRaft
->
tracker
->
progressMap
,
pRaft
->
selfId
);
assert
(
progress
!=
NULL
);
// Followers enter replicate mode when they've been successfully probed
// (perhaps after having received a snapshot as a result). The leader is
// trivially in this state. Note that r.reset() has initialized this
// progress with the last index already.
syncRaftProgressBecomeReplicate
(
progress
);
// Conservatively set the pendingConfIndex to the last index in the
// log. There may or may not be a pending config change, but it's
// safe to delay any future proposals until we commit all our
// pending log entries, and scanning the entire tail of the log
// could be expensive.
SyncIndex
lastIndex
=
syncRaftLogLastIndex
(
pRaft
->
log
);
pRaft
->
pendingConfigIndex
=
lastIndex
;
// after become leader, send a no-op log
SSyncRaftEntry
*
entry
=
(
SSyncRaftEntry
*
)
malloc
(
sizeof
(
SSyncRaftEntry
));
...
...
@@ -103,6 +114,7 @@ void syncRaftBecomeLeader(SSyncRaft* pRaft) {
};
appendEntries
(
pRaft
,
entry
,
1
);
//syncRaftTriggerHeartbeat(pRaft);
syncInfo
(
"[%d:%d] became leader at term %"
PRId64
""
,
pRaft
->
selfGroupId
,
pRaft
->
selfId
,
pRaft
->
term
);
}
void
syncRaftTriggerHeartbeat
(
SSyncRaft
*
pRaft
)
{
...
...
@@ -192,9 +204,11 @@ static void visitProgressSendAppend(SSyncRaftProgress* progress, void* arg) {
return
;
}
syncRaft
Replicate
(
arg
,
progress
,
true
);
syncRaft
MaybeSendAppend
(
arg
,
progress
,
true
);
}
// bcastAppend sends RPC, with entries to all peers that are not up-to-date
// according to the progress recorded in r.prs.
void
syncRaftBroadcastAppend
(
SSyncRaft
*
pRaft
)
{
syncRaftProgressVisit
(
pRaft
->
tracker
,
visitProgressSendAppend
,
pRaft
);
}
...
...
@@ -267,6 +281,11 @@ static void tickHeartbeat(SSyncRaft* pRaft) {
}
// TODO
static
bool
increaseUncommittedSize
(
SSyncRaft
*
pRaft
,
SSyncRaftEntry
*
entries
,
int
n
)
{
return
false
;
}
static
void
appendEntries
(
SSyncRaft
*
pRaft
,
SSyncRaftEntry
*
entries
,
int
n
)
{
SyncIndex
lastIndex
=
syncRaftLogLastIndex
(
pRaft
->
log
);
SyncTerm
term
=
pRaft
->
term
;
...
...
@@ -277,9 +296,16 @@ static void appendEntries(SSyncRaft* pRaft, SSyncRaftEntry* entries, int n) {
entries
[
i
].
index
=
lastIndex
+
1
+
i
;
}
// Track the size of this uncommitted proposal.
if
(
!
increaseUncommittedSize
(
pRaft
,
entries
,
n
))
{
// Drop the proposal.
return
;
}
syncRaftLogAppend
(
pRaft
->
log
,
entries
,
n
);
SSyncRaftProgress
*
progress
=
syncRaftFindProgressByNodeId
(
&
pRaft
->
tracker
->
progressMap
,
pRaft
->
selfId
);
assert
(
progress
!=
NULL
);
syncRaftProgressMaybeUpdate
(
progress
,
lastIndex
);
// Regardless of syncRaftMaybeCommit's return, our caller will call bcastAppend.
syncRaftMaybeCommit
(
pRaft
);
...
...
@@ -306,7 +332,7 @@ static int triggerAll(SSyncRaft* pRaft) {
continue;
}
syncRaft
Replicate
(pRaft, pRaft->tracker->progressMap.progress[i], true);
syncRaft
MaybeSendAppend
(pRaft, pRaft->tracker->progressMap.progress[i], true);
}
#endif
return
0
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录