Currently quorums are majorities of processes. There are some cases, however, in which a system designer might want more flexibility to specify quorums. For example, applications running across data centers or even inside a data center when servers are spread across racks or simply different subnets. In such cases, we might want to perhaps split the set of servers into sub-groups and assign weights to the sub-groups.
The main property that a majority of servers satisfy that matters for the correctness of ZooKeeper is the intersection property of such subsets. As long as subsets of servers intersect, they can be used as a quorum system for ZooKeeper.
In the current code, whenever we need a quorum, we just check if the number is greater than n/2, where n is the total number of servers configured. My initial proposal is to move such a computation to a separate class, call it QuorumSpec for now, that reads a quorum configuration from a configuration file, and provides a method to check if a set of elements contains a quorum, call it "containsQuorum". For example, if we want to check whether a set of votes when electing a leader contains a quorum, then we invoke "containsQuorum" on an instance of "QuorumSpec".
With respect to configuration, the most flexible way would be to enumerate all possible subsets. Such an option is tedious and prone to configuration errors, though. Instead, I thought of providing for splitting the servers into groups, and assigning weights to the groups. The semantics would the following. We have a quorum if we have votes from a subset of groups such that the sum of the weights of such groups is more than half of the total sum of weights. Also, we include a group in the previous computation only if we have a majority of votes from such a group.
To illustrate, consider the following example. Suppose that we have 4 groups of servers with weights in parenthesis: A (2), B (1), C (1), and D (1). Now suppose that we have 3 servers in each group. We have a quorum if, for example, we have votes from two processes from each one of A and B. As another example, we have a quorum if we have two votes from processes in each one of B, C, and D.