Review Board 1.7.22


ZOOKEEPER-1413: Use on-disk transaction log for learner sync up

Review Request #11231 - Created May 20, 2013 and updated

Thawan Kooburat
https://issues.apache.org/jira/browse/ZOOKEEPER-1413
Reviewers
zookeeper
zookeeper
ZOOKEEPER-1413: Use on-disk transaction log for learner sync up

- Use txnlog for learner synchronization if learner fall too far behind
- Refactoring LearnerHandler to deal with different cases of handling learner synchronization  
- unit tests
- ran in prod for more than half a year
/src/java/main/org/apache/zookeeper/server/TxnLogProposalIterator.java
New File

    
   
1
package org.apache.zookeeper.server;

    
   
2

   

    
   
3
import java.io.ByteArrayOutputStream;

    
   
4
import java.io.IOException;

    
   
5
import java.util.Iterator;

    
   
6

   

    
   
7
import org.apache.jute.BinaryOutputArchive;

    
   
8
import org.apache.jute.Record;

    
   
9
import org.apache.zookeeper.server.persistence.TxnLog.TxnIterator;

    
   
10
import org.apache.zookeeper.server.quorum.Leader;

    
   
11
import org.apache.zookeeper.server.quorum.Leader.Proposal;

    
   
12
import org.apache.zookeeper.server.quorum.QuorumPacket;

    
   
13
import org.apache.zookeeper.txn.TxnHeader;

    
   
14
import org.slf4j.Logger;

    
   
15
import org.slf4j.LoggerFactory;

    
   
16

   

    
   
17
/**

    
   
18
 * This class provide iterator interface to access Proposal deserialized

    
   
19
 * from on-disk txnlog. The iterator deserializes one proposal at a time

    
   
20
 * to reduce memory footprint. Note that the request part of the proposal

    
   
21
 * is not initialized and set to null since we don't need it during

    
   
22
 * follower sync-up.

    
   
23
 *

    
   
24
 */

    
   
25
public class TxnLogProposalIterator implements Iterator<Proposal> {

    
   
26
    private static final Logger LOG = LoggerFactory

    
   
27
            .getLogger(TxnLogProposalIterator.class);

    
   
28

   

    
   
29
    public static final TxnLogProposalIterator EMPTY_ITERATOR = new TxnLogProposalIterator();

    
   
30

   

    
   
31
    private boolean hasNext = false;

    
   
32

   

    
   
33
    private TxnIterator itr;

    
   
34

   

    
   
35
    @Override

    
   
36
    public boolean hasNext() {

    
   
37
        return hasNext;

    
   
38
    }

    
   
39

   

    
   
40
    /**

    
   
41
     * Proposal returned by this iterator has request part set to null, since

    
   
42
     * it is not used for follower sync-up.

    
   
43
     */

    
   
44
    @Override

    
   
45
    public Proposal next() {

    
   
46

   

    
   
47
        ByteArrayOutputStream baos = new ByteArrayOutputStream();

    
   
48
        BinaryOutputArchive boa = BinaryOutputArchive.getArchive(baos);

    
   
49
        Proposal p = new Proposal();

    
   
50
        try {

    
   
51
            TxnHeader hdr = itr.getHeader();

    
   
52
            Record txn = itr.getTxn();

    
   
53
            hdr.serialize(boa, "hdr");

    
   
54
            if (txn != null) {

    
   
55
                txn.serialize(boa, "txn");

    
   
56
            }

    
   
57
            baos.close();

    
   
58

   

    
   
59
            QuorumPacket pp = new QuorumPacket(Leader.PROPOSAL, itr.getHeader()

    
   
60
                    .getZxid(), baos.toByteArray(), null);

    
   
61
            p.packet = pp;

    
   
62
            p.request = null;

    
   
63

   

    
   
64
            hasNext = itr.next();

    
   
65

   

    
   
66
        } catch (IOException e) {

    
   
67
            LOG.error("Unable to read txnlog from disk", e);

    
   
68
        }

    
   
69

   

    
   
70
        return p;

    
   
71
    }

    
   
72

   

    
   
73
    @Override

    
   
74
    public void remove() {

    
   
75
        throw new UnsupportedOperationException();

    
   
76
    }

    
   
77

   

    
   
78
    private TxnLogProposalIterator() {

    
   
79
    }

    
   
80

   

    
   
81
    public TxnLogProposalIterator(TxnIterator itr) {

    
   
82
        if (itr != null) {

    
   
83
            this.itr = itr;

    
   
84
            hasNext = (itr.getHeader() != null);

    
   
85
        }

    
   
86
    }

    
   
87

   

    
   
88
}
/src/java/main/org/apache/zookeeper/server/ZKDatabase.java
Revision 1483440 New Change
 
/src/java/main/org/apache/zookeeper/server/persistence/FileTxnLog.java
Revision 1483440 New Change
 
/src/java/main/org/apache/zookeeper/server/persistence/FileTxnSnapLog.java
Revision 1483440 New Change
 
/src/java/main/org/apache/zookeeper/server/persistence/TxnLog.java
Revision 1483440 New Change
 
/src/java/main/org/apache/zookeeper/server/quorum/LearnerHandler.java
Revision 1483440 New Change
 
/src/java/test/org/apache/zookeeper/server/quorum/LearnerHandlerTest.java
New File
 
/src/java/test/org/apache/zookeeper/test/FollowerResyncConcurrencyTest.java
Revision 1483440 New Change
 
/src/java/test/org/apache/zookeeper/test/GetProposalFromTxnTest.java
New File
 
/src/java/test/org/apache/zookeeper/test/LoadFromLogTest.java
Revision 1483440 New Change
 
  1. /src/java/main/org/apache/zookeeper/server/TxnLogProposalIterator.java: Loading...
  2. /src/java/main/org/apache/zookeeper/server/ZKDatabase.java: Loading...
  3. /src/java/main/org/apache/zookeeper/server/persistence/FileTxnLog.java: Loading...
  4. /src/java/main/org/apache/zookeeper/server/persistence/FileTxnSnapLog.java: Loading...
  5. /src/java/main/org/apache/zookeeper/server/persistence/TxnLog.java: Loading...
  6. /src/java/main/org/apache/zookeeper/server/quorum/LearnerHandler.java: Loading...
  7. /src/java/test/org/apache/zookeeper/server/quorum/LearnerHandlerTest.java: Loading...
  8. /src/java/test/org/apache/zookeeper/test/FollowerResyncConcurrencyTest.java: Loading...
  9. /src/java/test/org/apache/zookeeper/test/GetProposalFromTxnTest.java: Loading...
  10. /src/java/test/org/apache/zookeeper/test/LoadFromLogTest.java: Loading...