2009-10-08 102 views
22

我需要一個支持磁盤的Map結構以用於Java應用程序。它必須具備以下條件:推薦一個快速且可擴展的持久性地圖 - Java

  1. 可存儲數百萬條記錄(甚至數十億)
  2. 快速查找 - 在地圖上的大多數操作只會看是否有鍵已經存在。這和上面的1是最重要的標準。對於經常使用的密鑰應該有一個有效的內存緩存機制。
  3. 持久性,但不需要是事務性的,可以承受一定的失敗。即高興地定期與磁盤同步,並且不需要是事務性的。
  4. 能夠存儲簡單的原始類型 - 但我不需要存儲序列化的對象。
  5. 它不需要分配,即將在一臺機器上運行。
  6. 簡單設置&免費使用。
  7. 沒有關係查詢所需

記錄鍵將字符串或多頭。如上所述,讀取將比寫入更頻繁,並且大部分讀取將僅僅是檢查密鑰是否存在(即,不需要讀取密鑰相關數據)。每條記錄只會更新一次,記錄不會被刪除。

我目前使用Bdb的JE,但我正在尋求其他的選擇。


更新

以來通過減少在第二個鍵的依賴在我現有的BDB設置提高查詢性能。有些查詢需要在兩個輔助鍵上進行連接,通過將它們組合成一個組合鍵,我在查找中刪除了一個間接級別,這可以很好地加快速度。

+0

我正在考慮的一個選擇是改變我使用現有BDB實施的方式。目前,我的所有記錄都有一個大型數據庫。然而,我應該能夠將數據分成多個集合並且每個集合有一個數據庫 - 如果我知道在任何時候我只需要訪問某些集合,那麼我可以保持關閉那些我不使用的集合,這應該有助於bdb爲我更高效地管理數據。 – Joel 2009-10-08 12:44:08

+0

我已經使用bdb je。根據您的標準,這非常合適。然而,我對它的脆弱性感到非常失望,並且不推薦將它用於生產用途。 java進程中的任何打嗝導致bdb子系統需要重啓,blech! – james 2009-10-08 15:24:21

+0

我不確定你的意思是BDB JE的「脆弱性」。 BDB JE可擴展到數TB的數據,並且我一直在生產系統中使用它。這是一個非常棒的技術。 – jasonmp85 2010-05-30 23:56:30

回答

3

我可能會使用本地數據庫。就像說Bdb JEHSQLDB。請問這種方法有什麼問題?你必須有一些理由尋找替代品。

迴應評論: 由於問題的表現,我猜你已經在使用JDBC來處理這個問題,所以可能值得嘗試使用HSQLB並閱讀Memory and Disk Use一章。

+1

+1同意。我會使用常規數據庫併爲需求編寫一個很好的API,以便後端可以輕鬆切換。 – flybywire 2009-10-08 10:40:20

+0

一旦Bdb達到了可以在內存中緩存的限制,我發現它會讓人無法接受地變慢。這通常發生在約1毫米插入後。 – Joel 2009-10-08 10:46:44

+0

HSQLDB怎麼樣?我會猜測它們都是JDBC,所以你應該可以在不修改大部分現有代碼的情況下插入它。 值得一讀: http://hsqldb.org/doc/2.0/guide/deployment-chapt.html#deployment_mem_disk-sect – 2009-10-08 11:24:28

1

SQLite這樣做。我寫了一個使用它從Java的包裝:http://zentus.com/sqlitejdbc

正如我在評論中提到的,我成功地使用SQLite與千兆字節的數據和數億行的表。如果你認真考慮索引,速度非常快。

唯一的痛苦是JDBC接口。與簡單的HashMap相比,它笨重。我經常最終爲特定項目編寫一個JDBC包裝器,這可以添加許多樣板代碼。

+0

我嚴重懷疑sqlite會擴展到這麼多的記錄。 – 2009-10-08 12:02:53

+1

我成功地使用了SQLite和千兆字節的數據和數億行的表。如果你認真考慮索引,速度非常快。 – 2009-10-08 22:44:26

0

JBoss (tree) Cache是一個不錯的選擇。你可以從JBoss單獨使用它。非常強大,高性能和靈活性。

+1

它是否持久? – 2010-08-09 12:25:43

1

我發現Tokyo Cabinet是一個簡單的持久哈希/地圖,並且快速設置和使用。

此縮寫示例,從the 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(); 
19

JDBM3做你正在尋找什麼。它是一個磁盤備份地圖庫,它具有非常簡單的API和高性能。

UPDATE

這個項目現在已經演變成創建mapdb http://www.mapdb.org

6

您可以從http://openhft.net/products/chronicle-map/ 紀事地圖嘗試Java的編年史是一款高性能,離堆,鍵值,在內存中,堅持數據存儲。它像一個標準的java地圖

+1

雖然此鏈接可能會回答問題,但最好在此處包含答案的重要部分,並提供供參考的鏈接。如果鏈接頁面更改,則僅鏈接答案可能會失效。 – Cyclonecode 2014-11-24 22:37:18

+2

@krister - 我認爲這是一個不太理想的問題,它產生了違反SO政策的答案(答案在回答問題方面做得很好)。在這種情況下,我傾向於反對這個問題。 – jww 2014-11-25 00:31:04

2

截至今天,我會使用MapDB(基於文件/支持同步或異步)或Hazelcast。在後面你將不得不實現你自己的持久性,即通過實現一個Java接口來支持RDBMS。編年史可能是另一種選擇。我不確定持久性是如何工作的,因爲我從來沒有使用它,但聲稱擁有一個。 OpenHFT完全不在堆中,並且允許(無原型)序列化對象(原語)的部分更新,這可能會帶來性能上的好處。

注意:如果您需要基於內存問題的映射磁盤,最簡單的選項是MapDB。 Hazelcast可以用作緩存(分發或不分發),允許您在時間或大小之後從堆中逐出元素。 OpenHFT不在堆中,如果您只需要jvm重新啓動的持久性,就可以考慮使用它。