推荐快速且可扩展的持久性Map – Java

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

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

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

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


更新

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

我可能会使用本地数据库。 比如说Bdb JE或HSQLDB 。 请问这种方法有什么问题? 你必须有一些理由寻找替代品。

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

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

UPDATE

该项目现已发展为MapDB http://www.mapdb.org

您可能想要了解OrientDB 。

您可以从http://openhft.net/products/chronicle-map/尝试Java Chronicles.Chronicle Map是一种高性能的堆外键值,在内存中,持久化数据存储。 它的工作方式类似于标准的Java映射

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

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

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

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

  // 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(); 

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

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

唯一的痛苦是JDBC接口。 与简单的HashMap相比,它很笨重。 我经常最终为特定项目编写JDBC包装器,它可以添加许多样板代码。

JBoss(树)缓存是一个很好的选择。 您可以从JBoss独立使用它。 非常强大,高效,灵活。

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