繁体   English   中英

键值存储建议

[英]key-value store suggestion

我需要一个非常基本的 java 键值存储。 我从 HashMap 开始,但似乎 HashMap 的空间效率有点低(我存储了大约 2000 万条记录,并且似乎需要大约 6GB RAM)。

map 是Map<Integer,String> ,所以我正在考虑使用 GNU Trove TIntObjectHashMap<byte[]> ,并将 map 值存储为 ascii 字节数组而不是字符串。

作为替代方案,是否有一个键值存储只需要添加 jar 文件,不会一次将整个 map 保存在 RAM 中,并且仍然相当快?

巴布数据库

BabuDB 是一个嵌入式非关系型数据库系统。 其精简和简单的设计使其能够持久存储大量键值对,而无需像 BerkeleyDB 这样的类似方法的开销和复杂性。

许可证:新 BSD 许可证,语言:Java

JDBM2

JDBM2 提供了由磁盘存储支持的 HashMap 和 TreeMap。

许可证:Apache 许可证 2.0,语言:Java

香蕉数据库

Banana DB 是在 Java 中实现的自包含键/值对数据库。

许可证:Apache 许可证 2.0,语言:Java


我试过 BabuDB 和 JDBM2,它们工作正常。 BabuDB 设置起来有点困难,但可能提供比 JDBM2 更高的性能。

这些都是允许在磁盘上持久化数据的所有数据库。 还有一些解决方案可以在 memory( ehcachehazelcast ,...)中保存一个大的 map。

使用伯克利数据库

Berkeley DB 将 object 图、collections 中的对象或简单的二进制键/值数据直接存储在磁盘上的 btree 中 这种简单、高效的方法消除了 ORM 解决方案中所有不必要的开销。 使用直接持久层 (DPL) Java 开发人员使用存储信息注释类,就像 JPA 一样。 这种方法熟悉、高效且快速。 DPL 在不牺牲速度的情况下降低了数据存储的复杂性。

这肯定会给您带来 memory 和速度方面的巨大收益,同时不会增加应用程序的复杂性。 享受!

http://www.mapdb.org/是您正在寻找的。 这是 java.util.Map 的快速持久实现。

特征

同时

MapDB 具有记录级锁定和最先进的并发引擎。 它的性能几乎与内核数量呈线性关系。 数据可以由多个并行线程写入。

快速地

MapDB 具有出色的性能,只有原生 DB 才能与之匹敌。 这是十多年优化和重写的结果。

MapDB 可选地支持具有完全 MVCC 隔离的 ACID 事务。 MapDB 使用 write-ahead-log 或 append-only 存储来实现出色的写入持久性。

灵活的

MapDB 可用于从内存缓存到多 TB 数据库的任何地方。 它还有许多选项可以用持久性换取写入性能。 这使得配置 MapDB 以完全满足您的需求变得非常容易。

可破解

MapDB 是基于组件的,大多数功能(实例缓存、异步写入、压缩)只是 class 包装器。 将新功能或组件引入 MapDB 非常容易。

SQL 喜欢

MapDB 被开发为 SQL 引擎的更快替代品。 它具有许多特性,使从关系数据库的转换更容易:二级索引/集合、自动增量顺序 ID、连接、触发器、复合键……

磁盘空间使用率低

MapDB 具有许多功能(序列化、增量键打包……)以最小化其存储使用的磁盘。 它还具有非常快速的压缩和自定义序列化程序。 我们认真对待磁盘使用,不浪费单个字节。

考虑Koloboke Collections ,根据各种测试,它比 Trove 快 2 倍:

如果配置为使用与 Trove 相同的 memory。 或者,如果配置为与 Trove 一样快,您可以认为它消耗的 memory 会少得多。


如果您想在 JVM 之间保持 map 以非常快速的引导程序运行,您可能还对Chronicle-Map感兴趣,它将String存储在String byte[]科洛博克/特罗夫)。 Chronicle-Map 对于持久键值存储来说是超快的,但比 Koloboke 甚至 Trove 要慢一些。

只是想参考一些自首次提出此问题以来随着时间的推移而变得可用的更多开源选项。

Apache 2、BTree、Apache 目录项目 JDBM 替换工作:

http://directory.apache.org/mavibot/

MPL2/EPL1、RTree、MVStore、H2 存储引擎:

http://www.h2database.com/html/mvstore.html

Apache 2、Xodus 环境、JetBrains YouTrack 和 Hub 存储引擎:

https://github.com/JetBrains/xodus

map 是 Map,所以我正在考虑使用 GNU Trove TIntObjectHashMap,并将 map 值存储为 ascii 字节数组而不是字符串。

这并不完全有意义,因为TIntObjectHashMap不是Map 但是,这种方法是合理的。


你知道我可以为 Trove 节省多少空间?

最好的答案是尝试一下。

但这里有一些粗略的估计(假设是 32 位 JVM):

  • HashMap 密钥需要是 Integer 实例。 它们将占用每个实例约 18 个字节 + 每个引用 4 个字节。 共 24 个字节。

  • Trove 键将是 4 字节int值。

  • 字符串值将是 20 字节 + 12 字节 + 2 * “字符”数。

  • 字节数组值将是 12 字节 + 1 * “字符”数。

  • 我还没有检查各个 hash 表内部数据结构的详细信息。

这可能相当于节省了大约 50% memory,尽管它主要取决于值“字符串”的平均长度。 (它们越长,它们将越多地支配空间使用。)

FWIW,Trove在这里发布他们自己的基准。 它们看起来不是很有说服力,但是您应该能够挖掘出他们的基准代码并对其进行修改以更好地匹配您的用例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM