Словарь травления Python 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()

Все скрипты работают нормально, кроме одного. Тот, у кого есть проблемы, посещает различные веб-сайты, собирает данные и сохраняет их в словаре. Этот код работает весь день, собирая и распаковывая словари, и останавливается в полночь. Затем cronjob запускает его снова на следующее утро. Этот скрипт может работать неделями без проблем, но примерно раз в месяц скрипт умирает из-за ошибки EOFError при попытке открыть словарь. Размер словарей обычно составляет около 80 МБ. Я даже пытался добавить SellerDict.flush() перед SellerDict.close() при обработке данных, чтобы убедиться, что вечер сбрасывается.

Любая идея, что может быть причиной этого? Python довольно надежен, поэтому я не думаю, что это связано с размером файла. Там, где код работает нормально в течение длительного времени, прежде чем умереть, это наводит меня на мысль, что, возможно, что-то сохраняется в словаре, что вызывает эту проблему, но я понятия не имею.

Кроме того, если вы знаете лучший способ сохранения словарей, кроме рассола, я открыт для вариантов. Как я уже говорил ранее, словари постоянно открываются и закрываются. Просто для пояснения: только одна программа будет использовать один и тот же словарь, поэтому проблема не вызвана тем, что несколько программ пытаются получить доступ к одному и тому же словарю.

ОБНОВИТЬ:

Вот трассировка, которую я получил из файла журнала.

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

person jordanskis    schedule 21.04.2012    source источник
comment
Используете ли вы какую-либо стратегию блокировки?   -  person AJ.    schedule 22.04.2012
comment
Я не использую никаких стратегий блокировки...   -  person jordanskis    schedule 22.04.2012


Ответы (2)


Так что это на самом деле оказалось проблемой памяти. Когда у компьютера заканчивается оперативная память и он пытается распаковать или загрузить данные, процесс не сможет заявить об этой ошибке EOFError. Я увеличиваю оперативную память на компьютере, и это больше никогда не было проблемой.

Спасибо за все комментарии и помощь.

person jordanskis    schedule 08.01.2013
comment
насколько велики в среднем словари, которые вы собираете и распаковываете? - person Algorithmatic; 05.11.2014

Вот что происходит, когда вы не используете блокировку:

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()

Вот результат:

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

В конце концов, какой-то процесс чтения попытается прочитать замаринованный файл, в то время как процесс записи уже открыл его для записи. Вы должны убедиться, что у вас есть какой-то способ узнать, есть ли у другого процесса файл, открытый для записи, прежде чем вы попытаетесь прочитать его.

Очень простое решение можно найти в этой ветке, в которой обсуждается использование Filelock.

person AJ.    schedule 21.04.2012
comment
AJ, я ценю ваш ответ. Однако только одна программа использует каждый словарь. Таким образом, никогда не будет другого процесса, пытающегося прочитать или открыть словарь, который текущий процесс использует или в который записывает. - person jordanskis; 22.04.2012
comment
Можете ли вы включить полную трассировку в свой вопрос? - person AJ.; 22.04.2012
comment
Я обновил исходный вопрос с помощью трассировки. Спасибо за вашу помощь! - person jordanskis; 22.04.2012