From 3749b604b8a98e7fbcef300c88c803e6b6a8e0e4 Mon Sep 17 00:00:00 2001 From: Matteo Merli Date: Fri, 22 Nov 2019 09:58:06 -0800 Subject: [PATCH 1/3] Allow to bypass journal for writes --- .../main/java/org/apache/bookkeeper/bookie/Bookie.java | 8 ++++++++ .../org/apache/bookkeeper/conf/ServerConfiguration.java | 5 +++++ conf/bk_server.conf | 8 ++++++++ 3 files changed, 21 insertions(+) diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/Bookie.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/Bookie.java index 6a2209aaeee..374fa1adf89 100644 --- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/Bookie.java +++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/Bookie.java @@ -144,6 +144,8 @@ public class Bookie extends BookieCriticalThread { private final ByteBufAllocator allocator; + private final boolean writeDataToJournal; + /** * Exception is thrown when no such a ledger is found in this bookie. */ @@ -692,6 +694,7 @@ public Bookie(ServerConfiguration conf, StatsLogger statsLogger, this.ledgerDirsManager = createLedgerDirsManager(conf, diskChecker, statsLogger.scope(LD_LEDGER_SCOPE)); this.indexDirsManager = createIndexDirsManager(conf, diskChecker, statsLogger.scope(LD_INDEX_SCOPE), this.ledgerDirsManager); + this.writeDataToJournal = conf.getJournalWriteData(); this.allocator = allocator; // instantiate zookeeper client to initialize ledger manager @@ -1278,6 +1281,11 @@ private void addEntryInternal(LedgerDescriptor handle, ByteBuf entry, } } + if (!writeDataToJournal) { + cb.writeComplete(0, ledgerId, entryId, null, ctx); + return; + } + if (LOG.isTraceEnabled()) { LOG.trace("Adding {}@{}", entryId, ledgerId); } diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ServerConfiguration.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ServerConfiguration.java index 8cd3ef86640..cc20faefea5 100644 --- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ServerConfiguration.java +++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ServerConfiguration.java @@ -124,6 +124,7 @@ public class ServerConfiguration extends AbstractConfiguration Date: Fri, 7 May 2021 19:43:52 -0700 Subject: [PATCH 2/3] Added unit test to validate the new config --- .../bookkeeper/conf/ServerConfiguration.java | 12 ++ .../bookie/BookieJournalBypassTest.java | 106 ++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/BookieJournalBypassTest.java diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ServerConfiguration.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ServerConfiguration.java index 8363e1fdc7a..8d029009be2 100644 --- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ServerConfiguration.java +++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ServerConfiguration.java @@ -2085,6 +2085,18 @@ public boolean getJournalWriteData() { return getBoolean(JOURNAL_WRITE_DATA, true); } + /** + * Should the data be written to journal before acknowledgment. + * + *

Default is true + * + * @return + */ + public ServerConfiguration setJournalWriteData(boolean journalWriteData) { + setProperty(JOURNAL_WRITE_DATA, journalWriteData); + return this; + } + /** * Enable or disable journal syncs. * diff --git a/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/BookieJournalBypassTest.java b/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/BookieJournalBypassTest.java new file mode 100644 index 00000000000..5939df04178 --- /dev/null +++ b/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/BookieJournalBypassTest.java @@ -0,0 +1,106 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.bookkeeper.bookie; + +import static org.junit.Assert.assertEquals; +import lombok.Cleanup; +import lombok.extern.slf4j.Slf4j; +import org.apache.bookkeeper.client.BookKeeper; +import org.apache.bookkeeper.client.api.WriteHandle; +import org.apache.bookkeeper.conf.ClientConfiguration; +import org.apache.bookkeeper.conf.ServerConfiguration; +import org.apache.bookkeeper.proto.BookieServer; +import org.apache.bookkeeper.test.BookKeeperClusterTestCase; +import org.junit.Test; + +/** + * Tests that we're skipping journal when it's configured to do so. + */ +@Slf4j +public class BookieJournalBypassTest extends BookKeeperClusterTestCase { + + private int bookieIdx = 0; + + public BookieJournalBypassTest() { + super(2); + } + + @Override + protected BookieServer startBookie(ServerConfiguration conf) throws Exception { + if (bookieIdx++ == 0) { + // First bookie will have the journal disabled + conf.setJournalWriteData(false); + } + return super.startBookie(conf); + } + + @Test + public void testJournalBypass() throws Exception { + ClientConfiguration conf = new ClientConfiguration(baseClientConf); + + Journal journal0 = bs.get(0).getBookie().journals.get(0); + LedgerStorage ls0 = bs.get(0).getBookie().getLedgerStorage(); + + Journal journal1 = bs.get(1).getBookie().journals.get(0); + LedgerStorage ls1 = bs.get(1).getBookie().getLedgerStorage(); + + ls0.flush(); + ls1.flush(); + + long offset0_before = journal0.getLastLogMark().getCurMark().getLogFileOffset(); + long offset1_before = journal1.getLastLogMark().getCurMark().getLogFileOffset(); + + writeEntries(conf); + ls0.flush(); + ls1.flush(); + + long offset0_after = journal0.getLastLogMark().getCurMark().getLogFileOffset(); + long offset1_after = journal1.getLastLogMark().getCurMark().getLogFileOffset(); + + int flushDelta = 10 * 1024; + int dataSize = 10 * 1024 * 1024; + + // Offset for journal-0 will be very close to previous point, just few KBs when flushing + assertEquals(offset0_before, offset0_after, flushDelta); + + // Offset for journal-0 should have changed with the data size + assertEquals(offset1_before + dataSize, offset1_after, flushDelta); + } + + private void writeEntries(ClientConfiguration conf) + throws Exception { + @Cleanup + BookKeeper bkc = new BookKeeper(conf); + + @Cleanup + WriteHandle wh = bkc.newCreateLedgerOp() + .withEnsembleSize(2) + .withWriteQuorumSize(2) + .withAckQuorumSize(2) + .withPassword("".getBytes()) + .execute() + .join(); + + for (int i = 0; i < 10; i++) { + wh.append(new byte[1024 * 1024]); + } + } +} From 4db06b1c53c02cf994f946f51f0b96ef950910e0 Mon Sep 17 00:00:00 2001 From: Matteo Merli Date: Fri, 7 May 2021 22:49:46 -0700 Subject: [PATCH 3/3] Fixed test variable names --- .../apache/bookkeeper/conf/ServerConfiguration.java | 9 ++++++++- .../bookkeeper/bookie/BookieJournalBypassTest.java | 12 ++++++------ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ServerConfiguration.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ServerConfiguration.java index 8d029009be2..fe23c4c2e94 100644 --- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ServerConfiguration.java +++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ServerConfiguration.java @@ -2080,7 +2080,14 @@ public ServerConfiguration setSkipListArenaMaxAllocSize(int size) { public boolean getJournalSyncData() { return getBoolean(JOURNAL_SYNC_DATA, true); } - + + /** + * Should the data be written to journal before acknowledgment. + * + *

Default is true + * + * @return + */ public boolean getJournalWriteData() { return getBoolean(JOURNAL_WRITE_DATA, true); } diff --git a/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/BookieJournalBypassTest.java b/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/BookieJournalBypassTest.java index 5939df04178..2d14a0f02ec 100644 --- a/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/BookieJournalBypassTest.java +++ b/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/BookieJournalBypassTest.java @@ -65,24 +65,24 @@ public void testJournalBypass() throws Exception { ls0.flush(); ls1.flush(); - long offset0_before = journal0.getLastLogMark().getCurMark().getLogFileOffset(); - long offset1_before = journal1.getLastLogMark().getCurMark().getLogFileOffset(); + long bk0OffsetBefore = journal0.getLastLogMark().getCurMark().getLogFileOffset(); + long bk1OffsetBefore = journal1.getLastLogMark().getCurMark().getLogFileOffset(); writeEntries(conf); ls0.flush(); ls1.flush(); - long offset0_after = journal0.getLastLogMark().getCurMark().getLogFileOffset(); - long offset1_after = journal1.getLastLogMark().getCurMark().getLogFileOffset(); + long bk0OffsetAfter = journal0.getLastLogMark().getCurMark().getLogFileOffset(); + long bk1OffsetAfter = journal1.getLastLogMark().getCurMark().getLogFileOffset(); int flushDelta = 10 * 1024; int dataSize = 10 * 1024 * 1024; // Offset for journal-0 will be very close to previous point, just few KBs when flushing - assertEquals(offset0_before, offset0_after, flushDelta); + assertEquals(bk0OffsetBefore, bk0OffsetAfter, flushDelta); // Offset for journal-0 should have changed with the data size - assertEquals(offset1_before + dataSize, offset1_after, flushDelta); + assertEquals(bk1OffsetBefore + dataSize, bk1OffsetAfter, flushDelta); } private void writeEntries(ClientConfiguration conf)