当前位置:网站首页>ETCD数据库源码分析——从raftNode的start函数说起
ETCD数据库源码分析——从raftNode的start函数说起
2022-07-07 01:39:00 【肥叔菌】
如上图所示,raftNode是真正操纵ETCD RAFT API的模块,充当etcd-raft模块与上层模块之间交互的桥梁,其定义了如下成员。其中msgSnapC通道用于接收和发送快照、applyc通道用于发送待应用的Entry记录、readStateC用于向上层模块发送ReadState、ticker用于向raft模块发送定时脉冲tick、td用于检测发往同一节点的两次心跳消息是否超时。raftNodeConfig后续再说,该篇主要说明ticker模块。
type raftNode struct {
lg *zap.Logger
tickMu *sync.Mutex
raftNodeConfig
msgSnapC chan raftpb.Message // a chan to send/receive snapshot
applyc chan toApply // a chan to send out apply
readStateC chan raft.ReadState // a chan to send out readState
ticker *time.Ticker // utility
td *contention.TimeoutDetector // contention detectors for raft heartbeat message
stopped chan struct{
}
done chan struct{
}
}
初始化raftNode结构体的函数是newRaftNode,raftNodeConfig包含了已经初始化的网络transport、预写日志Storage、raftStorage以及最重要的raft模块,这些模块提供相应的接口给raftnode使用以协助完成raft log发送、持久化、多数复制等功能。
func newRaftNode(cfg raftNodeConfig) *raftNode {
raft.SetLogger(lg) // 初始化logger(略)
r := &raftNode{
lg: cfg.lg, tickMu: new(sync.Mutex),
raftNodeConfig: cfg, td: contention.NewTimeoutDetector(2 * cfg.heartbeat), // set up contention detectors for raft heartbeat message. expect to send a heartbeat within 2 heartbeat intervals.
readStateC: make(chan raft.ReadState, 1),
msgSnapC: make(chan raftpb.Message, maxInFlightMsgSnap),
applyc: make(chan toApply),
stopped: make(chan struct{
}), done: make(chan struct{
}),
}
// 这里是重点
if r.heartbeat == 0 {
r.ticker = &time.Ticker{
} // 如果heartbeat为零,则使用默认&time.Ticker{}
} else {
r.ticker = time.NewTicker(r.heartbeat) } // 否则,需要设定时间间隔为r.heartbeat
return r
}
start函数会启动一个协程运行主要的业务逻辑,这里我们会看到如果定时器超时时,select会检测到该通道,调用raftNode接口的tick函数。该tick函数会获取tickMu锁,然后调用Node接口提供的Tick函数,也就是图中的raft.Node提供的Tick函数。
func (r *raftNode) start(rh *raftReadyHandler) {
internalTimeout := time.Second
go func() {
defer r.onStop()
islead := false
for {
select {
case <-r.ticker.C:
r.tick()
// raft.Node does not have locks in Raft package
func (r *raftNode) tick() {
r.tickMu.Lock()
r.Tick()
r.tickMu.Unlock()
}
raft.Node提供的Tick函数会向n.tickc通道中写入struct{}{},而在raft.Node中会有协程执行run函数,如图中raft.Node的run协程所示,其会执行监听n.tickc通道的代码,然后执行n.rn.Tick()
。而这里n.rn.Tick()
执行的是rawnode所包含成员raft结构体的Tick成员函数,该函数会根据raft角色执行不同的tick函数:tickElection或tickHeartbeat。
// Tick advances the internal logical clock by a single tick.
func (rn *RawNode) Tick() {
rn.raft.tick()
}
边栏推荐
- 693. 行程排序
- 深度聚类:将深度表示学习和聚类联合优化
- Test the foundation of development, and teach you to prepare for a fully functional web platform environment
- Database notes 04
- 如何在Touch Designer 2022版中设置解决Leap Motion不识别的问题?
- go-microservice-simple(2) go-Probuffer
- If you don't know these four caching modes, dare you say you understand caching?
- 牛客小白月赛52 E.分组求对数和(二分&容斥)
- Introduction to yarn (one article is enough)
- Classic questions about data storage
猜你喜欢
PTA ladder game exercise set l2-004 search tree judgment
3531. Huffman tree
Bypass open_ basedir
Detailed explanation of platform device driver architecture in driver development
On the discrimination of "fake death" state of STC single chip microcomputer
cf:C. Column Swapping【排序 + 模拟】
A very good JVM interview question article (74 questions and answers)
搞懂fastjson 对泛型的反序列化原理
[FPGA tutorial case 14] design and implementation of FIR filter based on vivado core
[SQL practice] a SQL statistics of epidemic distribution across the country
随机推荐
rt-thread 中对 hardfault 的处理
cf:C. Column Swapping【排序 + 模拟】
一名普通学生的大一总结【不知我等是愚是狂,唯知一路向前奔驰】
CMD permanently delete specified folders and files
Ideas of high concurrency and high traffic seckill scheme
On the discrimination of "fake death" state of STC single chip microcomputer
进程间通信之共享内存
CTFshow--常用姿势
Rk3399 platform development series explanation (WiFi) 5.52. Introduction to WiFi framework composition
693. 行程排序
蚂蚁庄园安全头盔 7.8蚂蚁庄园答案
Peripheral driver library development notes 43: GPIO simulation SPI driver
Go language learning notes - Gorm use - native SQL, named parameters, rows, tosql | web framework gin (IX)
3428. 放苹果
C语言整理(待更新)
SQL Server 2008 各种DateTime的取值范围
Storage of dental stem cells (to be continued)
生活中的开销,怎么记账合适
MFC BMP sets the resolution of bitmap, DPI is 600 points, and gdiplus generates labels
JVM command - jmap: export memory image file & memory usage