etcd-raft的这个地方还是挺有意思的,也体现出了golang的channel使用技巧
对于一个raft集群
- 无主期间拒绝客户端写请求
- 为了保证集群一致性,整个集群对外接收客户端写请求的有且只能有Leader
上面这两点在raft中是怎么实现控制的呢
1 处理客户端写请求
1 2 3 4 5 6 7 8 9 10 11
| case pm := <-propc: m := pm.m m.From = r.id err := r.Step(m) if pm.result != nil { pm.result <- err close(pm.result) }
|
所以只要控制当前节点的内存中变量propc有没有值就行
2 控制只有Leader才有propc
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
if lead != r.lead { if r.hasLeader() { if lead == None { r.logger.Infof("raft.node: %x elected leader %x at term %d", r.id, r.lead, r.Term) } else { r.logger.Infof("raft.node: %x changed leader from %x to %x at term %d", r.id, lead, r.lead, r.Term) } propc = n.propc } else { r.logger.Infof("raft.node: %x lost leader %x at term %d", r.id, lead, r.Term) propc = nil } lead = r.lead }
|