IOTXING

记录技术学习之路

0%

zookeeper源码学习-QuorumVerifier

Quorum的验证器,Quorum是一种分布式的机制,用来定义在分布式系统中,某个请求是否能够被确认。

ZK默认的实现是QuorumMaj,也就是超过半数投票者的时候,认为投票通过

1
2
3
4
5
6
7
8
9
10
11
12
13
public interface QuorumVerifier {

long getWeight(long id); //权重
boolean containsQuorum(Set<Long> set); //是否实现了quorum机制
long getVersion(); //版本
void setVersion(long ver);
Map<Long, QuorumServer> getAllMembers(); //获取所有节点
Map<Long, QuorumServer> getVotingMembers(); //获取所有投票节点
Map<Long, QuorumServer> getObservingMembers();
boolean equals(Object o);
String toString();

}

QuorumMaj

QuorumMaj是默认的QuorumVerifier的实现,里面会存储一个half来表示节点的一半

1
2
3
4
5
private Map<Long, QuorumServer> allMembers = new HashMap<Long, QuorumServer>();
private Map<Long, QuorumServer> votingMembers = new HashMap<Long, QuorumServer>();
private Map<Long, QuorumServer> observingMembers = new HashMap<Long, QuorumServer>();
private long version = 0;
private int half;

在创建QuorumVerifier的时候,会传入一个节点列表,然后会根据其中的参与者的数量,确定出来投票节点的数量,进而得出half的值,如果是在启动中创建出来的,则会根据配置信息进行创建。

如果没有指定节点类型,则节点默认为参与者

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public QuorumMaj(Map<Long, QuorumServer> allMembers) {
this.allMembers = allMembers;
for (QuorumServer qs : allMembers.values()) {
if (qs.type == LearnerType.PARTICIPANT) {
votingMembers.put(Long.valueOf(qs.id), qs);
} else {
observingMembers.put(Long.valueOf(qs.id), qs);
}
}
half = votingMembers.size() / 2;
}

public QuorumMaj(Properties props) throws ConfigException {
for (Entry<Object, Object> entry : props.entrySet()) {
String key = entry.getKey().toString();
String value = entry.getValue().toString();

if (key.startsWith("server.")) {
int dot = key.indexOf('.');
long sid = Long.parseLong(key.substring(dot + 1));
QuorumServer qs = new QuorumServer(sid, value);
allMembers.put(Long.valueOf(sid), qs);
if (qs.type == LearnerType.PARTICIPANT) {
votingMembers.put(Long.valueOf(sid), qs);
} else {
observingMembers.put(Long.valueOf(sid), qs);
}
} else if (key.equals("version")) {
version = Long.parseLong(value, 16);
}
}
half = votingMembers.size() / 2;
}

containsQuorum 核心

用来判断给定的一个结合是否满足Quorum的要求,也就是说是否超过了半数。

1
2
3
public boolean containsQuorum(Set<Long> ackSet) {
return (ackSet.size() > half);
}