2012-10-24 27 views
7

我很難在我的SSD上存儲數十億個帶有散列陣列的16/32bytes的鍵/值對。京都內閣/伯克利DB:散列表大小限制

與京都內閣:當它工作正常,它插入在70000記錄/秒。一旦下降,它將下降到10-500記錄/秒。使用默認設置後,下降發生在大約一百萬條記錄之後。查看文檔,這是數組中的存儲區的默認數量,因此它是有道理的。我把這個數字增加到了25百萬,實際上,它可以正常工作,直到大約2500萬條記錄。問題是,只要我把桶的數量推到3千萬或以上,插入速率從一開始就下降到10-500記錄/秒。京都內閣的目的不是爲了增加數據庫創建後的存儲桶數量,所以我不能插入超過25萬條記錄。

1/一旦桶號超過25M,爲什麼KC的插入率會非常低?

與伯克利DB:我得到的最佳速度略低於KC,接近50000記錄/秒,但仍然可以。使用默認設置,就像KC一樣,速度在大約一百萬條記錄後突然下降。我知道BDB旨在逐步擴展桶的數量。無論如何,它試圖增加初始數量,使用HashNumElements和FillFactor,但是這些嘗試中的任何一個都使情況變得最糟糕。所以我仍然無法在DBD中插入1-2百萬條記錄。我嘗試激活非同步事務,嘗試不同的檢查點,增加緩存。沒有什麼改善了下拉。

2/什麼可能導致BDB插入率在1-2百萬次插入後下降?

注:我用java工作,當轉速下降時,CPU佔用率,而在正確的速度工作時,在100%降低到0-30%。
注意:停止進程並恢復插入不會改變任何內容。所以我不認爲這與內存限制或垃圾收集有關。

Thx。

+0

你的BDB環境是什麼樣的?你在使用交易,複製等嗎?另外,你可以發佈一些示例代碼? –

+0

目前的狀態是:[pastebin.com/bWJpbipZ](http://pastebin.com/bWJpbipZ)。我使用'database.put(transaction,k,v)'插入',使用'database.get(transaction,k,v,LockMode.DEFAULT)'讀取,每隔500000個插入使用'environment.checkpoint(null)'插入。 –

回答

3

以下是我如何設法存儲數十億條記錄,儘管KC遇到了寫入限制。

我付出了很多努力,對於京都議會和柏克萊DB都沒有解決過這個問題。不過,我使用京都內閣提出了一個有趣的解決方法。

我注意到我在一個KC文件上寫不到25M以上的記錄,但讀取沒有這樣的限制 - 無論數據庫的大小如何,它總是很快。我找到的解決方案是爲每25M新記錄創建一個新的KC文件(新數據庫)。這種方式在許多KC文件上進行讀取,並且速度仍然很快,寫入只發生在最後創建的文件上,並且速度也很快。剩下的問題是允許更新/刪除以前文件上的記錄。對於這一點,我複製SSTables接近,那就是:

  • 所有的0到N-1文件是隻讀的,文件N讀+寫。
  • 任何插入/更新/刪除都寫入文件N.
  • 讀取文件N到0,並返回第一次看到/最後一次寫入的插入/更新/刪除。
  • Bloom Filter附加到每個文件以避免訪問沒有所需記錄的文件。
  • 只要文件N達到25M記錄,它就變爲只讀並創建文件N + 1。

注:

  • 就像使用SSTables,如果大量的更新/進行刪除,我們可能要進行壓縮。然而,與SSTables相反,這裏的壓縮並不需要重寫文件。過期的記錄只是從KC文件中刪除,如果KC文件變得非常小,則可以刪除它 - 可以刪除文件N-中的記錄插入或重新打開新的插入記錄 - 提供下一個文件緊湊。
  • 刪除操作不會刪除該記錄,而是會寫入一個特殊值來標識該記錄已刪除。在壓縮過程中,刪除的記錄將被刪除。
  • 檢查記錄是否存在通常需要查看數據庫。感謝bloom過濾器,大多數負面答案都可以在沒有任何磁盤訪問的情況下給出。