Search in sources :

Example 1 with WriteCallback

use of org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.WriteCallback in project bookkeeper by apache.

the class AuditorPeriodicCheckTest method replaceBookieWithWriteFailingBookie.

private BookieSocketAddress replaceBookieWithWriteFailingBookie(LedgerHandle lh) throws Exception {
    int bookieIdx = -1;
    Long entryId = LedgerHandleAdapter.getLedgerMetadata(lh).getEnsembles().firstKey();
    ArrayList<BookieSocketAddress> curEnsemble = LedgerHandleAdapter.getLedgerMetadata(lh).getEnsembles().get(entryId);
    // Identify a bookie in the current ledger ensemble to be replaced
    BookieSocketAddress replacedBookie = null;
    for (int i = 0; i < numBookies; i++) {
        if (curEnsemble.contains(bs.get(i).getLocalAddress())) {
            bookieIdx = i;
            replacedBookie = bs.get(i).getLocalAddress();
            break;
        }
    }
    assertNotEquals("Couldn't find ensemble bookie in bookie list", -1, bookieIdx);
    LOG.info("Killing bookie " + bs.get(bookieIdx).getLocalAddress());
    ServerConfiguration conf = killBookie(bookieIdx);
    Bookie writeFailingBookie = new Bookie(conf) {

        @Override
        public void addEntry(ByteBuf entry, boolean ackBeforeSync, WriteCallback cb, Object ctx, byte[] masterKey) throws IOException, BookieException {
            try {
                LOG.info("Failing write to entry ");
                // sleep a bit so that writes to other bookies succeed before
                // the client hears about the failure on this bookie. If the
                // client gets ack-quorum number of acks first, it won't care
                // about any failures and won't reform the ensemble.
                Thread.sleep(100);
                throw new IOException();
            } catch (InterruptedException ie) {
                // ignore, only interrupted if shutting down,
                // and an exception would spam the logs
                Thread.currentThread().interrupt();
            }
        }
    };
    bsConfs.add(conf);
    bs.add(startBookie(conf, writeFailingBookie));
    return replacedBookie;
}
Also used : BookieSocketAddress(org.apache.bookkeeper.net.BookieSocketAddress) Bookie(org.apache.bookkeeper.bookie.Bookie) ServerConfiguration(org.apache.bookkeeper.conf.ServerConfiguration) WriteCallback(org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.WriteCallback) IOException(java.io.IOException) ByteBuf(io.netty.buffer.ByteBuf)

Example 2 with WriteCallback

use of org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.WriteCallback in project bookkeeper by apache.

the class LedgerRecoveryTest method ledgerRecoveryWithSlowBookie.

private void ledgerRecoveryWithSlowBookie(int ensembleSize, int writeQuorumSize, int ackQuorumSize, int numEntries, int slowBookieIdx) throws Exception {
    // Create a ledger
    LedgerHandle beforelh = null;
    beforelh = bkc.createLedger(ensembleSize, writeQuorumSize, ackQuorumSize, digestType, "".getBytes());
    // kill first bookie server to start a fake one to simulate a slow bookie
    // and failed to add entry on crash
    // until write succeed
    BookieSocketAddress host = beforelh.getLedgerMetadata().currentEnsemble.get(slowBookieIdx);
    ServerConfiguration conf = killBookie(host);
    Bookie fakeBookie = new Bookie(conf) {

        @Override
        public void addEntry(ByteBuf entry, boolean ackBeforeSync, WriteCallback cb, Object ctx, byte[] masterKey) throws IOException, BookieException {
        // drop request to simulate a slow and failed bookie
        }
    };
    bsConfs.add(conf);
    bs.add(startBookie(conf, fakeBookie));
    // avoid not-enough-bookies case
    startNewBookie();
    // write would still succeed with 2 bookies ack
    String tmp = "BookKeeper is cool!";
    for (int i = 0; i < numEntries; i++) {
        beforelh.addEntry(tmp.getBytes());
    }
    conf = killBookie(host);
    bsConfs.add(conf);
    // the bookie goes normally
    bs.add(startBookie(conf));
    /*
         * Try to open ledger.
         */
    LedgerHandle afterlh = bkc.openLedger(beforelh.getId(), digestType, "".getBytes());
    /*
         * Check if has recovered properly.
         */
    assertEquals(numEntries - 1, afterlh.getLastAddConfirmed());
}
Also used : BookieSocketAddress(org.apache.bookkeeper.net.BookieSocketAddress) Bookie(org.apache.bookkeeper.bookie.Bookie) ServerConfiguration(org.apache.bookkeeper.conf.ServerConfiguration) WriteCallback(org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.WriteCallback) ByteBuf(io.netty.buffer.ByteBuf)

Example 3 with WriteCallback

use of org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.WriteCallback in project bookkeeper by apache.

the class BookKeeperCloseTest method restartBookieSlow.

private void restartBookieSlow() throws Exception {
    ServerConfiguration conf = killBookie(0);
    Bookie delayBookie = new Bookie(conf) {

        @Override
        public void recoveryAddEntry(ByteBuf entry, WriteCallback cb, Object ctx, byte[] masterKey) throws IOException, BookieException {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException ie) {
                // ignore, only interrupted if shutting down,
                // and an exception would spam the logs
                Thread.currentThread().interrupt();
            }
            super.recoveryAddEntry(entry, cb, ctx, masterKey);
        }

        @Override
        public void addEntry(ByteBuf entry, boolean ackBeforeSync, WriteCallback cb, Object ctx, byte[] masterKey) throws IOException, BookieException {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException ie) {
                // ignore, only interrupted if shutting down,
                // and an exception would spam the logs
                Thread.currentThread().interrupt();
            }
            super.addEntry(entry, ackBeforeSync, cb, ctx, masterKey);
        }

        @Override
        public ByteBuf readEntry(long ledgerId, long entryId) throws IOException, NoLedgerException {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException ie) {
                // ignore, only interrupted if shutting down,
                // and an exception would spam the logs
                Thread.currentThread().interrupt();
            }
            return super.readEntry(ledgerId, entryId);
        }
    };
    bsConfs.add(conf);
    bs.add(startBookie(conf, delayBookie));
}
Also used : Bookie(org.apache.bookkeeper.bookie.Bookie) ServerConfiguration(org.apache.bookkeeper.conf.ServerConfiguration) WriteCallback(org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.WriteCallback) ByteBuf(io.netty.buffer.ByteBuf)

Example 4 with WriteCallback

use of org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.WriteCallback in project bookkeeper by apache.

the class LedgerCloseTest method startDeadBookie.

// simulate slow adds, then become normal when recover,
// so no ensemble change when recovering ledger on this bookie.
private void startDeadBookie(ServerConfiguration conf, final CountDownLatch latch) throws Exception {
    Bookie dBookie = new Bookie(conf) {

        @Override
        public void addEntry(ByteBuf entry, boolean ackBeforeSync, WriteCallback cb, Object ctx, byte[] masterKey) throws IOException, BookieException {
            try {
                latch.await();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            // simulate slow adds.
            throw new IOException("Dead bookie");
        }
    };
    bsConfs.add(conf);
    bs.add(startBookie(conf, dBookie));
}
Also used : Bookie(org.apache.bookkeeper.bookie.Bookie) WriteCallback(org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.WriteCallback) IOException(java.io.IOException) ByteBuf(io.netty.buffer.ByteBuf)

Example 5 with WriteCallback

use of org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.WriteCallback in project bookkeeper by apache.

the class LedgerRecoveryTest method testLedgerRecoveryWithRollingRestart.

/**
 * {@link https://issues.apache.org/jira/browse/BOOKKEEPER-355}
 * A recovery during a rolling restart shouldn't affect the ability
 * to recovery the ledger later.
 * We have a ledger on ensemble B1,B2,B3.
 * The sequence of events is
 * 1. B1 brought down for maintenance
 * 2. Ledger recovery started
 * 3. B2 answers read last confirmed.
 * 4. B1 replaced in ensemble by B4
 * 5. Write to B4 fails for some reason
 * 6. B1 comes back up.
 * 7. B2 goes down for maintenance.
 * 8. Ledger recovery starts (ledger is now unavailable)
 */
@Test
public void testLedgerRecoveryWithRollingRestart() throws Exception {
    LedgerHandle lhbefore = bkc.createLedger(numBookies, 2, digestType, "".getBytes());
    for (int i = 0; i < (numBookies * 3) + 1; i++) {
        lhbefore.addEntry("data".getBytes());
    }
    // Add a dead bookie to the cluster
    ServerConfiguration conf = newServerConfiguration();
    Bookie deadBookie1 = new Bookie(conf) {

        @Override
        public void recoveryAddEntry(ByteBuf entry, WriteCallback cb, Object ctx, byte[] masterKey) throws IOException, BookieException {
            // drop request to simulate a slow and failed bookie
            throw new IOException("Couldn't write for some reason");
        }
    };
    bsConfs.add(conf);
    bs.add(startBookie(conf, deadBookie1));
    // kill first bookie server
    BookieSocketAddress bookie1 = lhbefore.getLedgerMetadata().currentEnsemble.get(0);
    ServerConfiguration conf1 = killBookie(bookie1);
    // ensemble in the ensemble, and another bookie is available in zk, but not writtable
    try {
        bkc.openLedger(lhbefore.getId(), digestType, "".getBytes());
        fail("Shouldn't be able to open ledger, there should be entries missing");
    } catch (BKException.BKLedgerRecoveryException e) {
    // expected
    }
    // restart the first server, kill the second
    bsConfs.add(conf1);
    bs.add(startBookie(conf1));
    BookieSocketAddress bookie2 = lhbefore.getLedgerMetadata().currentEnsemble.get(1);
    ServerConfiguration conf2 = killBookie(bookie2);
    // using async, because this could trigger an assertion
    final AtomicInteger returnCode = new AtomicInteger(0);
    final CountDownLatch openLatch = new CountDownLatch(1);
    bkc.asyncOpenLedger(lhbefore.getId(), digestType, "".getBytes(), new AsyncCallback.OpenCallback() {

        public void openComplete(int rc, LedgerHandle lh, Object ctx) {
            returnCode.set(rc);
            openLatch.countDown();
            if (rc == BKException.Code.OK) {
                try {
                    lh.close();
                } catch (Exception e) {
                    LOG.error("Exception closing ledger handle", e);
                }
            }
        }
    }, null);
    assertTrue("Open call should have completed", openLatch.await(5, TimeUnit.SECONDS));
    assertFalse("Open should not have succeeded", returnCode.get() == BKException.Code.OK);
    bsConfs.add(conf2);
    bs.add(startBookie(conf2));
    LedgerHandle lhafter = bkc.openLedger(lhbefore.getId(), digestType, "".getBytes());
    assertEquals("Fenced ledger should have correct lastAddConfirmed", lhbefore.getLastAddConfirmed(), lhafter.getLastAddConfirmed());
}
Also used : ServerConfiguration(org.apache.bookkeeper.conf.ServerConfiguration) WriteCallback(org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.WriteCallback) IOException(java.io.IOException) ByteBuf(io.netty.buffer.ByteBuf) CountDownLatch(java.util.concurrent.CountDownLatch) BookieException(org.apache.bookkeeper.bookie.BookieException) IOException(java.io.IOException) Bookie(org.apache.bookkeeper.bookie.Bookie) BookieSocketAddress(org.apache.bookkeeper.net.BookieSocketAddress) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Test(org.junit.Test)

Aggregations

WriteCallback (org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.WriteCallback)17 BookieSocketAddress (org.apache.bookkeeper.net.BookieSocketAddress)13 ServerConfiguration (org.apache.bookkeeper.conf.ServerConfiguration)10 ByteBuf (io.netty.buffer.ByteBuf)9 Bookie (org.apache.bookkeeper.bookie.Bookie)8 Test (org.junit.Test)8 CountDownLatch (java.util.concurrent.CountDownLatch)7 IOException (java.io.IOException)6 File (java.io.File)5 PrepareForTest (org.powermock.core.classloader.annotations.PrepareForTest)5 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)4 LastLogMark (org.apache.bookkeeper.bookie.Journal.LastLogMark)3 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)2 ClientConfiguration (org.apache.bookkeeper.conf.ClientConfiguration)2 ByteBufList (org.apache.bookkeeper.util.ByteBufList)2 EventLoopGroup (io.netty.channel.EventLoopGroup)1 NioEventLoopGroup (io.netty.channel.nio.NioEventLoopGroup)1 DefaultThreadFactory (io.netty.util.concurrent.DefaultThreadFactory)1 ByteBuffer (java.nio.ByteBuffer)1 ScheduledExecutorService (java.util.concurrent.ScheduledExecutorService)1