2012-04-21 12 views
3

私は、さまざまな辞書をpickleしたりunpickleするサーバ上でいくつかのスクリプトを実行しています。それらはすべて以下のように酸洗いに同じ基本コードを使用します:Python pickling dictionary EOFError

SellerDict=open('/home/hostadl/SellerDictkm','rb') 
SellerDictionarykm=pickle.load(SellerDict) 
SellerDict.close() 

SellerDict=open('/home/hostadl/SellerDictkm','wb') 
pickle.dump(SellerDictionarykm,SellerDict) 
SellerDict.close() 

すべてのスクリプトは、1つを除いて正常に実行されます。問題のあるものは、さまざまなウェブサイトに行き、データをスクラップして辞書に格納します。このコードでは、一日中の長時間の漬け物と解凍用の辞書を実行し、深夜に停止します。 cronjobはそれから再びそれを始める 翌朝。このスクリプトは問題なく何週間も実行できますが、辞書を開くときにEOFErrorが発生するため、月に約1回スクリプトが停止します。ディクショナリのサイズは通常約80 MBです。私はさらに、夕方が洗い流されていることを確認するためにデータをpicklingするときに、SellerDict.close()の前にSellerDict.flush()を追加しようとしました。

これを引き起こす原因は何でしょうか?私はそれがファイルのサイズに起因するとは思わないので、Pythonは非常にしっかりしています。死ぬ前にコードが長い間うまく動作する場所では、この問題の原因となっている辞書に何かが保存されている可能性があると私は信じていますが、わかりません。

また、pickle以外の辞書を保存するより良い方法を知っていれば、私はオプションを公開しています。私が以前に言ったように、辞書は絶えず開いて閉じています。明確にするために、1つのプログラムだけが同じ辞書を使用するので、問題は同じ辞書にアクセスしようとするいくつかのプログラムによって引き起こされていません。

UPDATE:ここ

私は、ログファイルから持っているトレースバックです。ここで

import pickle 

# define initial dict 
orig_dict={'foo':'one'} 

# write dict to file 
writedict_file=open('./mydict','wb') 
pickle.dump(orig_dict,writedict_file) 
writedict_file.close() 

# read the dict from file 
readdict_file=open('./mydict','rb') 
mydict=pickle.load(readdict_file) 
readdict_file.close() 

# now we have new data to save 
new_dict={'foo':'one','bar':'two'} 
writedict_file=open('./mydict','wb') 
#pickle.dump(orig_dict,writedict_file) 
#writedict_file.close() 

# but...whoops! before we could save the data 
# some other reader tried opening the file 
# now they are having a problem 
readdict_file=open('./mydict','rb') 
mydict=pickle.load(readdict_file) # errors out here 
readdict_file.close() 

出力です:

Traceback (most recent call last): 
    File "/home/hostadl/CompileRecentPosts.py", line 782, in <module> 
    main() 
    File "/home/hostadl/CompileRecentPosts.py", line 585, in main 
    SellerDictionarykm=pickle.load(SellerDict) 
EOFError 
+0

どのような種類のロック戦略を使用していますか? –

+0

私はロック戦略を使用していません... – jordanskis

答えて

2

は、ここでは、ロックを使用しないときに何が起こるかだ結局

python pickletest.py 
Traceback (most recent call last): 
    File "pickletest.py", line 26, in <module> 
    mydict=pickle.load(readdict_file) # errors out here 
    File "/usr/lib/python2.6/pickle.py", line 1370, in load 
    return Unpickler(file).load() 
    File "/usr/lib/python2.6/pickle.py", line 858, in load 
    dispatch[key](self) 
    File "/usr/lib/python2.6/pickle.py", line 880, in load_eof 
    raise EOFError 
EOFError 

、いくつかのリード処理は、漬けファイルを読み取ろうとしています書き込みプロセスはすでに書き込み可能な状態になっています。他のプロセスが既にファイルを開いてから読み込もうとするかどうかを確認する方法があることを確認する必要があります。

非常に簡単な解決方法は、this thread that discusses using Filelockをご覧ください。

+2

AJ、私はあなたの答えに感謝します。ただし、1つのプログラムでは各辞書が使用されます。したがって、現在のプロセスが使用している、または書き込んでいる辞書を読み込みまたは開こうとしている別のプロセスはありません。 – jordanskis

+1

質問に完全なトレースバックを含めることはできますか? –

+0

元の質問をトレースバックで更新しました。ご協力いただきありがとうございます! – jordanskis

5

これは実際にメモリの問題であることが判明しました。コンピュータのRAMが不足し、データをアンピクルまたはロードしようとすると、プロセスはこのEOFErrorを要求して失敗します。私はコンピュータのRAMを増やし、これは再び問題にはなりませんでした。

すべてのコメントとご協力ありがとうございます。

+2

平均して、あなたが酸洗していない辞書はどれくらい大きいのですか? – Algorithmatic