Я хотел бы понять, что происходит с MemoryError, которая кажется более или менее случайной.
Я запускаю программу на Python 3 в Docker и на виртуальной машине Azure (2CPU и 7 ГБ ОЗУ).
Для простоты программа работает с двоичными файлами, которые читаются определенной библиотекой (там нет проблем), затем я объединяю их по пиру файлов и, наконец, вставляю данные в базу данных.
Набор данных, который я получаю после слияния (и перед вставкой в БД), представляет собой фрейм данных Pandas, который содержит около ~ 2,8M строк и 36 столбцов .
Для вставки в базу данных я использую REST API, который обязывает меня вставлять файл порциями.
Перед этим я преобразую датафрам в буфер StringIO с помощью этой функции:
# static method from Utils class
@staticmethod
def df_to_buffer(my_df):
count_row, count_col = my_df.shape
buffer = io.StringIO() #creating an empty buffer
my_df.to_csv(buffer, index=False) #filling that buffer
LOGGER.info('Current data contains %d rows and %d columns, for a total
buffer size of %d bytes.', count_row, count_col, buffer.tell())
buffer.seek(0) #set to the start of the stream
return buffer
Так что в моей "основной" программе поведение таково:
# transform the dataframe to a StringIO buffer
file_data = Utils.df_to_buffer(file_df)
buffer_chunk_size = 32000000 #32MB
while True:
data = file_data.read(buffer_chunk_size)
if data:
...
# do the insert stuff
...
else:
# whole file has been loaded
break
# loop is over, close the buffer before processing a new file
file_data.close()
Проблема:
Иногда я могу вставить 2 или 3 файла подряд. Иногда возникает ошибка MemoryError в случайный момент (но всегда, когда он собирается вставить новый файл).
Ошибка возникает на первой итерации вставки файла (никогда не в середине файла). В частности, происходит сбой в строке, выполняющей чтение по блоку file_data.read(buffer_chunk_size)
Я слежу за памятью во время процесса (используя htop
): она никогда не превышает 5,5 ГБ памяти и, особенно, когда происходит сбой, в этот момент она использует ~ 3,5 ГБ используемой памяти. ..
Любая информация или советы будут оценены,
Благодарю. :)
EDIT
Я смог отладить и идентифицировать проблему, но еще не решил ее.
Это происходит, когда я читаю буфер StringIO по чанку. Блок данных значительно увеличивает потребление оперативной памяти, так как это большой str
, который содержит 320000000 символов файла.
Я попытался уменьшить его с 32000000 до 16000000. Мне удалось вставить некоторые файлы, но через некоторое время снова возникает ошибка MemoryError ... Я пытаюсь уменьшить ее до 8000000 прямо сейчас.