我有6个平均10G大小的csv文件
我通过shell 1为每个文件运行6个进程(xargs)
merchants () {
echo -n merchant_1 merchant_2 merchant_2 merchant_4 merchnat_5 merchant_6
}
merchants | xargs -L1 -P6 -d' ' -I{} bash -c \"python main.py '{}' || true\
我的代码有以下流程。 (1个文件)
pool.async(process, (df, transformer,
output_filename))
process函数接受数据帧,创建一个变换器对象(变换器是一个有12-15种方法的类。每个方法负责执行转换(例如删除某些黑名单单词,重命名列,小写等) )然后返回转换后的数据帧。然后将数据帧写入新的csv文件。结果我获得了多个新的csv文件(每行200,000行)
现在的问题是内存使用情况。
按照上面的计算,应该使用24gb(已经有一点缓冲区)。
该机器有64 gb的内存和32个处理器。由于我运行多处理,我看到流程运行从10-20到htop不等。
但是它会逐渐增加内存并达到整个60GB内存并且每件事都会被杀死。有两个可能的原因导致这种高内存使用。
以下是相关代码
transformer = globals()[merchant['transformer']] # i take the class name from configuration file
pool = Pool(processes=merchant['num_of_process']) # 2
chunk_index = 1
for df in pd.read_csv(downloaded_file, chunksize=chunksize, compression='gzip', skipinitialspace=True, encoding='utf-8'):
output_file_name = output_path + \
merchant['output_file_format'].format(
file_index, chunk_index)
pool.apply_async(process, (df, transformer, output_file_name))
chunk_index += 1
处理
def process(df, transformer, output_file_name):
"""
Process the csv chunk in a separate thread
:param df:
:param transformer:
:param file_index:
:param chunk_index:
"""
with TransformerContext(transformer(df)) as transformer:
methods = [method for method in dir(transformer) if callable(
getattr(transformer, method)) if not method.startswith('_')]
for method in methods:
getattr(transformer, method)()
handle = open(output_file_name, "w")
transformer.df.to_csv(output_file_name, index=False,
compression='gzip', sep='\t', quoting=1, encoding='utf-8')
del df
del transformer
handle.close()
return True
我在这里使用上下文的原因是我想在写入csv之前删除不必要的列。由于它必须运行不同类型的文件,因此它将作为通用代码。
class TransformerContext:
def __init__(self, transformer):
self.transformer = transformer
self.original_columns = list(transformer.df.columns)
def __enter__(self):
return self.transformer
def __exit__(self, exc_type, exc_val, exc_tb):
processed_columns = list(self.transformer.df.columns)
for column in self.original_columns:
if column in processed_columns:
del self.transformer.df[column]
如果这里有与多处理相关的内容,我需要帮助识别/修复。如果没有,那么我将去检查我的逻辑代码。
由于