[英]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 提供了由磁盤存儲支持的 HashMap 和 TreeMap。
許可證:Apache 許可證 2.0,語言:Java
Banana DB 是在 Java 中實現的自包含鍵/值對數據庫。
許可證:Apache 許可證 2.0,語言:Java
我試過 BabuDB 和 JDBM2,它們工作正常。 BabuDB 設置起來有點困難,但可能提供比 JDBM2 更高的性能。
這些都是允許在磁盤上持久化數據的所有數據庫。 還有一些解決方案可以在 memory( ehcache , hazelcast ,...)中保存一個大的 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 非常容易。
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 存儲引擎:
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.