Improve performance

This commit is contained in:
Andrea Cavalli 2022-03-12 02:55:18 +01:00
parent 9b5071c45e
commit a4df72fe46
5 changed files with 68 additions and 13 deletions

View File

@ -6,6 +6,7 @@ import io.net5.buffer.api.Drop;
import io.net5.buffer.api.Owned;
import io.net5.buffer.api.Resource;
import io.net5.buffer.api.Send;
import io.net5.buffer.api.internal.ResourceSupport;
import it.cavallium.dbengine.client.BadBlock;
import it.cavallium.dbengine.client.CompositeSnapshot;
import it.cavallium.dbengine.database.LLDictionary;
@ -13,13 +14,14 @@ import it.cavallium.dbengine.database.LLDictionaryResultType;
import it.cavallium.dbengine.database.LLRange;
import it.cavallium.dbengine.database.LLSnapshot;
import it.cavallium.dbengine.database.LLUtils;
import io.net5.buffer.api.internal.ResourceSupport;
import it.cavallium.dbengine.database.UpdateMode;
import it.cavallium.dbengine.database.serialization.SerializationException;
import it.cavallium.dbengine.database.serialization.SerializerFixedBinaryLength;
import it.unimi.dsi.fastutil.objects.Object2ObjectSortedMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicLong;
import org.apache.commons.lang3.function.TriFunction;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.NotNull;
@ -73,6 +75,7 @@ public class DatabaseMapDictionaryDeep<T, U, US extends DatabaseStage<U>> extend
protected final LLDictionary dictionary;
private final BufferAllocator alloc;
private final AtomicLong totalZeroBytesErrors = new AtomicLong();
protected final SubStageGetter<U, US> subStageGetter;
protected final SerializerFixedBinaryLength<T> keySuffixSerializer;
protected final int keyPrefixLength;
@ -437,4 +440,50 @@ public class DatabaseMapDictionaryDeep<T, U, US extends DatabaseStage<U>> extend
this.range = null;
this.onClose = null;
}
public static <K1, K2, V, R> Flux<R> getAllLeaves2(DatabaseMapDictionaryDeep<K1, Object2ObjectSortedMap<K2, V>, DatabaseMapDictionary<K2, V>> deepMap,
CompositeSnapshot snapshot,
TriFunction<K1, K2, V, R> merger) {
if (deepMap.subStageGetter instanceof SubStageGetterMap<K2, V> subStageGetterMap) {
var keySuffix1Serializer = deepMap.keySuffixSerializer;
var keySuffix2Serializer = subStageGetterMap.keySerializer;
var valueSerializer = subStageGetterMap.valueSerializer;
return deepMap
.dictionary
.getRange(deepMap.resolveSnapshot(snapshot), deepMap.rangeMono)
.handle((entrySend, sink) -> {
try (var entry = entrySend.receive()) {
var keyBuf = entry.getKeyUnsafe();
var valueBuf = entry.getValueUnsafe();
assert keyBuf != null;
keyBuf.skipReadable(deepMap.keyPrefixLength);
K1 key1;
K2 key2;
try (var key1Buf = keyBuf.split(deepMap.keySuffixLength)) {
key1 = keySuffix1Serializer.deserialize(key1Buf);
}
key2 = keySuffix2Serializer.deserialize(keyBuf);
assert valueBuf != null;
var value = valueSerializer.deserialize(valueBuf);
sink.next(merger.apply(key1, key2, value));
} catch (IndexOutOfBoundsException ex) {
var exMessage = ex.getMessage();
if (exMessage != null && exMessage.contains("read 0 to 0, write 0 to ")) {
var totalZeroBytesErrors = deepMap.totalZeroBytesErrors.incrementAndGet();
if (totalZeroBytesErrors < 512 || totalZeroBytesErrors % 10000 == 0) {
LOG.error("Unexpected zero-bytes value in column " + deepMap.dictionary.getDatabaseName() + ":"
+ deepMap.dictionary.getColumnName() + " total=" + totalZeroBytesErrors);
}
sink.complete();
} else {
sink.error(ex);
}
} catch (SerializationException ex) {
sink.error(ex);
}
});
} else {
throw new IllegalArgumentException();
}
}
}

View File

@ -16,8 +16,8 @@ import reactor.core.publisher.Mono;
public class SubStageGetterMap<T, U> implements
SubStageGetter<Object2ObjectSortedMap<T, U>, DatabaseMapDictionary<T, U>> {
private final SerializerFixedBinaryLength<T> keySerializer;
private final Serializer<U> valueSerializer;
final SerializerFixedBinaryLength<T> keySerializer;
final Serializer<U> valueSerializer;
public SubStageGetterMap(SerializerFixedBinaryLength<T> keySerializer,
Serializer<U> valueSerializer) {

View File

@ -137,7 +137,7 @@ public class LLLocalKeyValueDatabase implements LLKeyValueDatabase {
}
}
var optionsWithCache = openRocksDb(path, databaseOptions);
OptionsWithCache optionsWithCache = openRocksDb(path, databaseOptions);
var rocksdbOptions = optionsWithCache.options();
try {
List<ColumnFamilyDescriptor> descriptors = new LinkedList<>();
@ -175,7 +175,6 @@ public class LLLocalKeyValueDatabase implements LLKeyValueDatabase {
tableOptions
.setIndexType(IndexType.kTwoLevelIndexSearch)
.setPartitionFilters(true)
.setBlockCache(optionsWithCache.cache())
.setCacheIndexAndFilterBlocks(databaseOptions.setCacheIndexAndFilterBlocks().orElse(true))
.setCacheIndexAndFilterBlocksWithHighPriority(true)
.setPinTopLevelIndexAndFilter(true)
@ -185,7 +184,6 @@ public class LLLocalKeyValueDatabase implements LLKeyValueDatabase {
tableOptions
.setIndexType(IndexType.kTwoLevelIndexSearch)
.setPartitionFilters(true)
.setBlockCache(optionsWithCache.cache())
.setCacheIndexAndFilterBlocks(databaseOptions.setCacheIndexAndFilterBlocks().orElse( true))
.setCacheIndexAndFilterBlocksWithHighPriority(true)
.setPinTopLevelIndexAndFilter(true)
@ -195,7 +193,10 @@ public class LLLocalKeyValueDatabase implements LLKeyValueDatabase {
tableOptions.setFilterPolicy(bloomFilter);
tableOptions.setOptimizeFiltersForMemory(true);
}
tableOptions.setBlockSize(16 * 1024); // 16KiB
tableOptions
.setBlockCacheCompressed(optionsWithCache.compressedCache())
.setBlockCache(optionsWithCache.standardCache())
.setBlockSize(16 * 1024); // 16KiB
columnOptions.setTableFormatConfig(tableOptions);
columnOptions.setCompactionPriority(CompactionPriority.MinOverlappingRatio);
@ -391,7 +392,7 @@ public class LLLocalKeyValueDatabase implements LLKeyValueDatabase {
// end force compact
}
record OptionsWithCache(DBOptions options, Cache cache) {}
record OptionsWithCache(DBOptions options, Cache standardCache, Cache compressedCache) {}
private static OptionsWithCache openRocksDb(@Nullable Path path, DatabaseOptions databaseOptions) throws IOException {
// Get databases directory path
@ -409,6 +410,7 @@ public class LLLocalKeyValueDatabase implements LLKeyValueDatabase {
// the Options class contains a set of configurable DB options
// that determines the behaviour of the database.
var options = new DBOptions();
options.setParanoidChecks(false);
options.setCreateIfMissing(true);
options.setCreateMissingColumnFamilies(true);
options.setInfoLogLevel(InfoLogLevel.ERROR_LEVEL);
@ -427,6 +429,7 @@ public class LLLocalKeyValueDatabase implements LLKeyValueDatabase {
options.setMaxOpenFiles(databaseOptions.maxOpenFiles().orElse(-1));
Cache blockCache;
Cache compressedCache;
if (databaseOptions.lowMemory()) {
// LOW MEMORY
options
@ -438,7 +441,8 @@ public class LLLocalKeyValueDatabase implements LLKeyValueDatabase {
.setWalSizeLimitMB(0) // 16MB
.setMaxTotalWalSize(0) // automatic
;
blockCache = new ClockCache(databaseOptions.blockCache().orElse( 8L * SizeUnit.MB), -1, true);
blockCache = new ClockCache(databaseOptions.blockCache().orElse( 8L * SizeUnit.MB) / 2, -1, true);
compressedCache = new ClockCache(databaseOptions.blockCache().orElse( 8L * SizeUnit.MB) / 2, -1, true);
if (databaseOptions.useDirectIO()) {
options
@ -460,7 +464,8 @@ public class LLLocalKeyValueDatabase implements LLKeyValueDatabase {
.setWalSizeLimitMB(1024) // 1024MB
.setMaxTotalWalSize(2L * SizeUnit.GB) // 2GiB max wal directory size
;
blockCache = new ClockCache(databaseOptions.blockCache().orElse( 512 * SizeUnit.MB), -1, true);
blockCache = new ClockCache(databaseOptions.blockCache().orElse( 512 * SizeUnit.MB) / 2);
compressedCache = new ClockCache(databaseOptions.blockCache().orElse( 512 * SizeUnit.MB) / 2);
if (databaseOptions.useDirectIO()) {
options
@ -491,7 +496,7 @@ public class LLLocalKeyValueDatabase implements LLKeyValueDatabase {
options.setUseDirectIoForFlushAndCompaction(true);
}
return new OptionsWithCache(options, blockCache);
return new OptionsWithCache(options, blockCache, compressedCache);
}
private static List<DbPath> convertPaths(Path databasesDirPath, Path path, List<DatabaseVolume> volumes) {

View File

@ -79,8 +79,8 @@ public abstract class LLLocalReactiveRocksIterator<T> extends
return Flux.generate(() -> {
var readOptions = new ReadOptions(this.readOptions);
if (!rangeShared.hasMin() || !rangeShared.hasMax()) {
readOptions.setReadaheadSize(32 * 1024); // 32KiB
readOptions.setFillCache(false);
//readOptions.setReadaheadSize(32 * 1024); // 32KiB
//readOptions.setFillCache(false);
readOptions.setVerifyChecksums(false);
}
if (logger.isTraceEnabled()) {

View File

@ -130,6 +130,7 @@ public class RocksdbFileStore {
private static DBOptions getDBOptions() {
var options = new DBOptions();
options.setParanoidChecks(false);
options.setWalSizeLimitMB(256);
options.setMaxWriteBatchGroupSizeBytes(2 * SizeUnit.MB);
//options.setAtomicFlush(false);