我的工作,其中包括建立一個哈希以約1,700萬鍵一個Perl項目。這太大了無法存儲在內存中(我的筆記本電腦的內存只能容納大約1000萬個按鍵)。我知道解決的辦法是將數據存儲在磁盤上,但我有在實踐中執行這個麻煩。以下是我已經試過:的Perl:故障磁盤上存儲一個巨大的哈希?
DB_File
use strict;
use DB_File;
my $libfile = shift;
my %library;
tie %library, "DB_File", "$libfile";
for (my $a = 1; $a < 17000000; a++) {
# Some code to generate key and value #
$library{$key} = $value;
}
這給了我分割故障:通過循環11部分,對於原因,我不明白。
的BerkeleyDB
use strict;
use BerkeleyDB;
my $libfile = shift;
my $library = new BerkeleyDB::Hash
-Filename => $libfile,
-Flags => DB_CREATE;
for (my $a = 1; $a < 17000000; a++) {
# Some code to generate key and value #
$library->db_put($key, $value);
}
這似乎很好的工作,對前15個百萬個密鑰,但隨後大幅下降減緩並最終完全凍結附近的循環結束。我不認爲這是一個記憶問題;如果我將循環分成四部分,將它們放在四個獨立的程序中,然後按順序運行(每次向數據庫添加約400萬條記錄),前三個成功完成,但第四個在數據庫大約15百萬把鑰匙。所以看起來也許BerkeleyDB只能處理大約1500萬個密鑰?
DBM ::深
use strict;
use DBM::Deep;
my $libfile = shift;
my $library = new DBM::Deep $libfile;
for (my $a = 1; $a < 17000000; a++) {
# Some code to generate key and value #
$library->put($key => $value);
}
從初步測試,這似乎好的工作,但它真的很慢:每千個鍵約5秒,或〜22日小時以使整個循環。如果可能的話,我寧願避免這種情況。
我非常感謝對這些軟件包中的一個進行故障診斷的建議,或者關於完成相同事情的其他選項的想法。
UPDATE
看看是否可以使用諸如mongodb之類的nosql數據庫。 http://www.mongodb.com/learn/nosql – stevenl
什麼操作系統和版本的Perl和你試過的模塊?你的平均密鑰和平均值有多大? – ysth
您能否在「按鍵排序」模式下生成條目?我認爲我記得一個巨大的BerkeleyDB的情況下,從哈希切換到btree與「鍵排序」插入提高性能。改進非常顯着,但還不夠。 – AnFi