28

我需要一个磁盘支持的 Map 结构才能在 Java 应用程序中使用。它必须具有以下条件:

  1. 能够存储数百万条记录(甚至数十亿条)
  2. 快速查找 - Map 上的大多数操作将只是查看键是否已经存在。这和上面的 1 是最重要的标准。对于经常使用的键,应该有一个有效的内存缓存机制。
  3. 持久的,但不需要是事务性的,可以忍受一些失败。即乐于定期与磁盘同步,并且不需要事务性。
  4. 能够存储简单的原始类型 - 但我不需要存储序列化对象。
  5. 它不需要分布式,即在一台机器上运行。
  6. 设置简单且免费使用。
  7. 不需要关系查询

记录键将是字符串或长整数。如上所述,读取将比写入频繁得多,并且大多数读取将只是检查密钥是否存在(即不需要读取与密钥相关的数据)。每条记录只会更新一次,记录不会被删除。

我目前使用 Bdb JE,但正在寻找其他选择。


更新

此后,通过减少对辅助键的依赖,提高了我现有 BDB 设置的查询性能。一些查询需要连接两个辅助键,通过将它们组合成一个复合键,我在查找中删除了一个间接级别,这很好地加快了速度。

4

9 回答 9

20

JDBM3完全符合您的要求。它是一个磁盘支持的地图库,具有非常简单的 API 和高性能。

更新

这个项目现在已经演变成 MapDB http://www.mapdb.org

于 2012-02-23T14:30:38.887 回答
6

您可能想查看OrientDB

于 2010-06-12T09:54:16.033 回答
6

您可以从http://openhft.net/products/chronicle-map/尝试 Java Chronicles。 Chronicle Map 是一种高性能、堆外、键值、内存中的持久数据存储。它像标准的 java 地图一样工作

于 2014-11-24T15:22:29.223 回答
3

我可能会使用本地数据库。就像说Bdb JEHSQLDB。请问这种方法有什么问题吗?你必须有一些理由去寻找替代品。

回应评论:由于性能问题,我猜你已经在使用 JDBC 来处理这个问题,可能值得尝试 HSQLB 并阅读关于内存和磁盘使用的章节。

于 2009-10-08T10:35:28.030 回答
3

截至今天,我将使用MapDB(基于文件/支持同步或异步)或Hazelcast。稍后,您将必须实现自己的持久性,即通过实现 Java 接口由 RDBMS 支持。OpenHFT编年史可能是另一种选择。我不确定持久性在那里是如何工作的,因为我从未使用过它,但声称拥有它。OpenHFT 完全是堆外的,并且允许在没有(反)序列化的情况下对(原语的)对象进行部分更新,这可能会带来性能优势。

注意:如果由于内存问题需要基于地图磁盘,最简单的选择是 MapDB。Hazelcast 可以用作缓存(分布式或非分布式),它允许您在时间或大小之后从堆中逐出元素。OpenHFT 不在堆中,如果您只需要 jvm 重新启动的持久性,则可以考虑使用。

于 2017-03-12T17:38:24.527 回答
1

SQLite 做到了这一点。我写了一个从 Java 中使用它的包装器:http: //zentus.com/sqlitejdbc

正如我在评论中提到的,我已经成功地将 SQLite 用于数千兆字节的数据和数亿行的表。如果您正确考虑索引,它会非常快。

唯一的痛点是 JDBC 接口。与简单的 HashMap 相比,它显得笨重。我经常为特定项目编写一个 JDBC 包装器,这可能会增加很多样板代码。

于 2009-10-08T11:03:23.607 回答
1

我发现Tokyo Cabinet是一个简单的持久性 Hash/Map,并且可以快速设置和使用。

这个来自docs 的简短示例显示了从持久映射中保存和检索数据是多么简单:

    // create the object
    HDB hdb = new HDB();
    // open the database
    hdb.open("casket.tch", HDB.OWRITER | HDB.OCREAT);
    // add item 
    hdb.put("foo", "hop");
    hdb.close();
于 2010-09-27T12:21:48.567 回答
0

我认为Hibernate Shards可以轻松满足您的所有要求。

于 2009-10-08T10:37:29.217 回答
0

JBoss(树)缓存是一个不错的选择。您可以从 JBoss 独立使用它。非常健壮、高效且灵活。

于 2009-10-08T15:26:02.897 回答