在大型数据集上,如果Bag.to_avro出现Killed / MemoryError失败,则会失败

时间:2018-12-09 02:21:21

标签: dask

我正在尝试处理大量由换行符分隔的文本文件。将文件压缩后,我将文件分成小块,未压缩的文件大小约为100mb左右。我总共有296个单独的压缩文件,总未压缩大小约为30Gb。

行为NQuads,我正在使用Bag将行映射为可以导入数据库的格式。行被键折叠,以便我可以合并与单个页面相关的行。

这是我用来读取文件并折叠它们的代码。

with dask.config.set(num_workers=2):
  n_quads_bag = dask.bag.\
    read_text(files)

  uri_nquads_bag = n_quads_bag.\
    map(parser.parse).\
    filter(lambda x: x is not None).\
    map(nquad_tuple_to_page_dict).\
    foldby('uri', binop=binop).\
    pluck(1).\
    map(lang_extract)

然后我将数据标准化为页面和实体。我正在通过map函数使用(page, entities)将事物拆分为一个元组来实现。我要摘录数据,然后将其写入Avro中的两个单独的文件集。

  pages_entities_bag = uri_nquads_bag.\
      map(map_page_entities)

  pages_bag = pages_entities_bag.\
    pluck(0).\
    map(page_extractor).\
    map(extract_uri_details).\
    map(ntriples_to_dict)

  entities_bag = pages_entities_bag.\
    pluck(1) .\
    flatten().\
    map(entity_extractor).\
    map(ntriples_to_dict)

  with ProgressBar():
    pages_bag.to_avro(
      os.path.join(output_folder, 'pages.*.avro'),
      schema=page_avro_scheme,
      codec='snappy',
      compute=True)
    entities_bag.to_avro(
      os.path.join(output_folder, 'entities.*.avro'),
      schema=entities_avro_schema,
      codec='snappy',
      compute=True)

pages_bag.to_avro(... compute=True)Killed/MemoryError上的代码失败。我一直在努力减少分区大小并将处理器数减少到2。

我在设置compute=True时错了吗?这是将整个数据集带入内存的原因吗?如果是这样,我还能怎么写文件?

对于计算机而言,页面或实体的分区是否可能太大?

我遇到的另一个问题是我是否错误地使用了Bags,这是我要解决的问题的正确方法吗?

我在其上运行的计算机的规格:

  • 4个CPU
  • 16GB的Ram
  • 375暂存盘

1 个答案:

答案 0 :(得分:0)

使此内存不耗尽的方法是使文件〜100MB保持未压缩状态,并使用groupby。如Dask文档所述,您可以强制其在磁盘上随机播放。 groupby支持在输出上设置多个分区。

with dask.config.set(num_workers=2):
  n_quads_bag = dask.bag.\
    read_text(files)

  uri_nquads_bag = n_quads_bag.\
    map(parser.parse).\
    filter(lambda x: x is not None).\
    map(nquad_tuple_to_page_dict).\
    groupby(lambda x: x[3], shuffle='disk', npartitions=n_quads_bag.npartitions).\        
    map(grouped_nquads_to_dict).\
    map(lang_extract)
相关问题