当前位置: 首页 > 知识库问答 >
问题:

编年史地图在超过200M条目时显著减慢

太叔富
2023-03-14

我正在使用编年史地图来临时存储/查找大量的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),或者这只是操作系统分页如此大的文件的人工制品?

共有1个答案

滕无尘
2023-03-14

有几件事可能会有所帮助:

>

  • 确保使用最新的历史地图版本(目前是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太难了。