我正在使用纪事地图临时存储/查找大量的KV对(实际上是几十亿)。我不需要持久性或复制,我使用的是内存映射文件,而不是纯堆外内存。平均密钥长度为8个字节。
对于小型数据集--多达2亿个条目--我获得了每秒100万条的吞吐量,也就是说,创建条目需要大约200秒,这是惊人的,但在4亿个条目中,地图的速度明显减慢,创建它们需要1500秒。
我已经在Mac /16 G6 Core/500 G6和Proliant G6服务器上运行了测试,这些服务器运行的是8核/64 G6/300 G6 1(而不是SSD)。在这两个平台上都表现出相同的行为。
如果有帮助,下面是地图设置:
try {
f = File.createTempFile(name, ".map");
catalog = ChronicleMapBuilder
.of(String.class, Long.class)
.entries(size)
.averageKeySize(8)
.createPersistedTo(f);
} catch (IOException ioe) {
// blah
}还有一个简单的写作测试:
long now = -System.currentTimeMillis();
long count = 400_000_000L;
for (long i = 0; i < count; i++) {
catalog.put(Long.toString(i), i);
if ((i % 1_000_000) == 0) {
System.out.println(i + ": " + (now + System.currentTimeMillis()));
}
}
System.out.println(count + ": " + (now + System.currentTimeMillis()));
catalog.close();所以我的问题是--我是否可以做一些调优来改善这个问题,例如改变段数,使用不同的键类型(例如CharSequence),还是这仅仅是OS分页这么大文件的伪产物?
发布于 2016-01-05 02:20:28
有几件事可能会有帮助:
3.3.0-beta,下一个3.4.0-beta将在几天后到来)- Use `CharSequence` as the key type and `LongValue` as the value type.
- Simple test code could look like公共类VinceTest {公共静态空主(String[] args)抛出IOException { long count = 400_000_000L;File f= File.createTempFile("vince",".map");f.deleteOnExit();(ChronicleMap catalog = ChronicleMap .of(CharSequence.class,LongValue.class) .entries(count) .averageKeySize(8.72) .putReturnsNull(true) .createPersistedTo(f)) { long prev = System.currentTimeMillis();StringBuilder key = new StringBuilder();LongValue值= Values.newHeapInstance(LongValue.class);for (长i= 1;i <=计数;i++) { key.setLength(0);key.append(i);value.setValue(i);catalog.put(键,值);如果((i % 1_000_000) == 0) { long now = System.currentTimeMillis();System.out.printf(“插入每mi #%d:%d\n的平均ns”,(i / 1_000_000),now - prev);}System.out.println(“文件大小”+ MEGABYTES.convert(f.length(),字节)+“MB");}}
-请注意putReturnsNull(true)的使用,以避免意外地将垃圾创建为返回的值(尽管这个测试的情况不是这样,因为所有的键都是唯一的,put()总是返回null,但在生产中可能是这样)。
averageKeySize()。从这个测试中,平均键大小实际上接近9个字节(因为大多数键都大于10万字节)。不过,更好的做法是尽量精确,这是这项有40万元的特别测试的8.72分。https://stackoverflow.com/questions/34593354
复制相似问题