我正在使用编年史地图来临时存储/查找大量的KV对(实际上是数十亿)。我不需要持久性或复制,我使用的是内存映射文件,而不是纯堆外内存。平均密钥长度为8字节。
对于较小的数据集--多达2亿个条目--我得到的吞吐量约为每秒100万个条目,即创建条目需要大约200秒,这是惊人的,但到了4亿个条目时,地图已经显著放缓,创建它们需要1500秒。
我已经在Mac OSX/16GB四核/500GB SSD和Proliant G6服务器上运行了测试,这些服务器运行Linux和8核/64GB RAM/300GB Raid 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),或者这只是操作系统分页如此大的文件的人工制品?
有几件事可能会有所帮助:
>
确保使用最新的历史地图版本(目前是3.3.0-beta
,下一个3.4.0-beta
几天后发布)
实际上,使用无垃圾技术,即使对于这样的测试,这也很重要,因为垃圾收集可能会起作用:
public class VinceTest {
public static void main(String[] args) throws IOException {
long count = 400_000_000L;
File f = File.createTempFile("vince", ".map");
f.deleteOnExit();
try (ChronicleMap<CharSequence, LongValue> 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 value = Values.newHeapInstance(LongValue.class);
for (long i = 1; i <= count; i++) {
key.setLength(0);
key.append(i);
value.setValue(i);
catalog.put(key, value);
if ((i % 1_000_000) == 0) {
long now = System.currentTimeMillis();
System.out.printf("Average ns to insert per mi #%d: %d\n",
(i / 1_000_000), now - prev);
prev = now;
}
}
System.out.println("file size " + MEGABYTES.convert(f.length(), BYTES) + " MB");
}
}
}
思想?
编年史地图是否有任何概念(或可插拔的能力)来提供自动条目过期?
我们有一个在50台服务器上使用相同数据集(键值对)的系统。对该数据集的更新数量约为每小时1000次,并且必须在这50台服务器上复制。我们有一个主系统接收这些更新,并负责将这些更新传播到其他服务器。目前,我们每小时以文件的形式将整个数据集(而不是增量更新)同步到所有服务器。然后将这些数据加载到不可变的Koloboke映射中。每个服务器每秒处理大约25000个请求,每个请求对这个映射进行30次查找。在
一个简单的问题:我看到chronicle Map3x正在将一些功能转移到引擎产品中。然而,引擎本身依赖于MAP2X。我有点困惑,我怎么能把它们一起用呢?我想我错过了什么,但不确定到底是什么。
在描述中说: 编年史映射提供内存访问速度,并支持超低垃圾收集。编年史地图可以支持最苛刻的应用程序。
我有以下映射定义,其中map.containsKey()显然不起作用: 我使用的是编年史地图2.4.17,在我的项目中迁移到版本3太难了。