Quorum的验证器,Quorum是一种分布式的机制,用来定义在分布式系统中,某个请求是否能够被确认。
ZK默认的实现是QuorumMaj,也就是超过半数投票者的时候,认为投票通过
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来表示节点的一半
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的值,如果是在启动中创建出来的,则会根据配置信息进行创建。
如果没有指定节点类型,则节点默认为参与者
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的要求,也就是说是否超过了半数。
public boolean containsQuorum(Set<Long> ackSet) {
return (ackSet.size() > half);
}