Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add latency stats for entry location index lookup so that possible RocksDB bottleneck can be detected #3444

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,10 @@ public synchronized double getSuccessAverage() {
public synchronized long getSuccessCount() {
return successCount;
}

public synchronized long getFailureCount() {
return failureCount;
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.apache.bookkeeper.bookie.storage.ldb.KeyValueStorageFactory.DbConfigType;
import org.apache.bookkeeper.conf.ServerConfiguration;
import org.apache.bookkeeper.stats.StatsLogger;
import org.apache.bookkeeper.util.MathUtils;
import org.apache.bookkeeper.util.collections.ConcurrentLongHashSet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -73,18 +74,27 @@ public long getLocation(long ledgerId, long entryId) throws IOException {
LongPairWrapper key = LongPairWrapper.get(ledgerId, entryId);
LongWrapper value = LongWrapper.get();

long startTimeNanos = MathUtils.nowInNano();
boolean operationSuccess = false;
try {
if (locationsDb.get(key.array, value.array) < 0) {
if (log.isDebugEnabled()) {
log.debug("Entry not found {}@{} in db index", ledgerId, entryId);
}
return 0;
}

operationSuccess = true;
return value.getValue();
} finally {
key.recycle();
value.recycle();
if (operationSuccess) {
stats.getLookupEntryLocationStats()
.registerSuccessfulEvent(MathUtils.elapsedNanos(startTimeNanos), TimeUnit.NANOSECONDS);
} else {
stats.getLookupEntryLocationStats()
.registerFailedEvent(MathUtils.elapsedNanos(startTimeNanos), TimeUnit.NANOSECONDS);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.util.function.Supplier;
import lombok.Getter;
import org.apache.bookkeeper.stats.Gauge;
import org.apache.bookkeeper.stats.OpStatsLogger;
import org.apache.bookkeeper.stats.StatsLogger;
import org.apache.bookkeeper.stats.annotations.StatsDoc;

Expand All @@ -40,13 +41,20 @@
class EntryLocationIndexStats {

private static final String ENTRIES_COUNT = "entries-count";
private static final String LOOKUP_ENTRY_LOCATION = "lookup-entry-location";

@StatsDoc(
name = ENTRIES_COUNT,
help = "Current number of entries"
)
private final Gauge<Long> entriesCountGauge;

@StatsDoc(
name = LOOKUP_ENTRY_LOCATION,
help = "operation stats of looking up entry location"
)
private final OpStatsLogger lookupEntryLocationStats;

EntryLocationIndexStats(StatsLogger statsLogger,
Supplier<Long> entriesCountSupplier) {
entriesCountGauge = new Gauge<Long>() {
Expand All @@ -61,6 +69,7 @@ public Long getSample() {
}
};
statsLogger.registerGauge(ENTRIES_COUNT, entriesCountGauge);
lookupEntryLocationStats = statsLogger.getOpStatsLogger(LOOKUP_ENTRY_LOCATION);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@
package org.apache.bookkeeper.bookie.storage.ldb;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.io.IOException;
import org.apache.bookkeeper.conf.ServerConfiguration;
import org.apache.bookkeeper.stats.NullStatsLogger;
import org.apache.bookkeeper.test.TestStatsProvider;
import org.junit.Test;

/**
Expand Down Expand Up @@ -139,4 +141,31 @@ public void testDeleteSpecialEntry() throws IOException {
idx.removeOffsetFromDeletedLedgers();
assertEquals(0, idx.getLocation(40312, 10));
}

@Test
public void testEntryIndexLookupLatencyStats() throws IOException {
File tmpDir = File.createTempFile("bkTest", ".dir");
tmpDir.delete();
tmpDir.mkdir();
tmpDir.deleteOnExit();

TestStatsProvider statsProvider = new TestStatsProvider();
EntryLocationIndex idx = new EntryLocationIndex(serverConfiguration, KeyValueStorageRocksDB.factory,
tmpDir.getAbsolutePath(), statsProvider.getStatsLogger("scope"));

// Add some dummy indexes
idx.addLocation(40313, 11, 5);

// successful lookup
assertEquals(5, idx.getLocation(40313, 11));
TestStatsProvider.TestOpStatsLogger lookupEntryLocationOpStats =
statsProvider.getOpStatsLogger("scope.lookup-entry-location");
assertEquals(1, lookupEntryLocationOpStats.getSuccessCount());
assertTrue(lookupEntryLocationOpStats.getSuccessAverage() > 0);

// failed lookup
assertEquals(0, idx.getLocation(12345, 1));
assertEquals(1, lookupEntryLocationOpStats.getFailureCount());
assertEquals(1, lookupEntryLocationOpStats.getSuccessCount());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,18 @@ public interface OpStatsLogger {

/**
* Increment the failed op counter with the given eventLatency.
* @param eventLatencyMillis The event latency
* @param eventLatency The event latency
* @param unit
*/
void registerFailedEvent(long eventLatencyMillis, TimeUnit unit);
void registerFailedEvent(long eventLatency, TimeUnit unit);

/**
* An operation succeeded with the given eventLatency. Update
* stats to reflect the same
* @param eventLatencyMillis The event latency
* @param eventLatency The event latency
* @param unit
*/
void registerSuccessfulEvent(long eventLatencyMillis, TimeUnit unit);
void registerSuccessfulEvent(long eventLatency, TimeUnit unit);

/**
* An operation with the given value succeeded.
Expand Down