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); 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); }
|