处理/加载巨大的gzip文件到蜂巢

时间:2019-05-15 23:38:01

标签: python bash hive large-data

我有一个巨大的压缩后的csv文件(压缩后为55GB,扩展后为660GB),试图将其处理并以更有用的格式加载到配置单元中。

该文件具有设备事件的2.5B记录,每行给出device_id,event_id,timestamp和event_name进行标识,然后再提供约160列,其中只有少数对于给定的event_name不为空。< / p>

最终,我想将数据格式化为几个标识列和一个JSON列,该列仅存储给定event_name的相关字段,并将其保存在按日期,小时和event_name(以及分区)划分的配置单元表中基于时区等元数据,但希望这只是个小问题),因此我们可以轻松查询数据以进行进一步分析。但是,文件的绝对大小给我带来麻烦。

我尝试了几种方法,但收效甚微:

  1. 直接将文件加载到配置单元中,然后执行“ INSERT OVERWRITE ... SELECT TRANSFORM(*)”(使用'python transform.py'FROM ...')存在明显的问题

  2. 我使用bash命令将文件分为200万行的多个gzip文件:gzip -cd file.csv.gz | split -l 2000000 -d -a 5 --filter ='gzip> split / $ FILE.gz'并仅将其中一个加载到hive中进行转换,但尽管如此,我仍然遇到内存问题试图增加内存限制(我必须检查看看我们更改了哪些参数)。

    A。尝试了使用pandas的转换脚本(因为它可以很容易地按event_name分组,然后删除每个事件名称不需要的列),并且将pandas限制为一次只能读取10万行,但是仍然需要限制hive的选择以免出现内存问题(1000行效果很好,5万行效果不好)。

    B。我还尝试制作一个辅助临时表(存储为ORC),其列与csv文件中的列相同,但按event_name进行分区,然后仅选择该临时表中的200万行,但是也存在内存问题。

我已经考虑过尝试按event_name拆分数据。我可以使用awk做到这一点,但是我不确定这是否比仅处理200万行文件要好得多。

我希望有人对如何处理该文件提出一些建议。我愿意接受bash,python / pandas,hadoop / hive(我也可以考虑其他人)的任何组合来完成工作,只要可以使其大部分自动进行即可(我将有几个其他文件)像这样处理)。

这是我正在使用的配置单元转换查询:

SET hive.exec.dynamic.partition.mode=nonstrict;
SET hive.exec.max.dynamic.partitions.pernode=10000;
SET mapreduce.map.memory.mb=8192;
SET mapreduce.reduce.memory.mb=10240;

ADD FILE transform.py;

INSERT OVERWRITE TABLE final_table
PARTITION (date,hour,zone,archetype,event_name)
SELECT TRANSFORM (*)
USING "python transform.py"
AS device_id,timestamp,json_blob,date,hour,zone,archetype,event_name
FROM (
SELECT *
FROM event_file_table eft
JOIN meta_table m ON eft.device_id=m.device_id
WHERE m.name = "device"
) t
;

这是python转换脚本:

import sys
import json
import pandas as pd

INSEP='\t'
HEADER=None

NULL='\\N'
OUTSEP='\t'

cols = [# 160+ columns here]
metaCols =['device_id','meta_blob','zone','archetype','name']

df = pd.read_csv(sys.stdin, sep=INSEP, header=HEADER, 
                 names=cols+metaCols, na_values=NULL, chunksize=100000, 
                 parse_dates=['timestamp'])

for chunk in df:
    chunk = chunk.drop(['name','meta_blob'], axis=1)
    chunk['date'] = chunk['timestamp'].dt.date
    chunk['hour'] = chunk['timestamp'].dt.hour
    for name, grp in chunk.groupby('event_name'):
        grp = grp.dropna(axis=1, how='all') \
              .set_index(['device_id','timestamp','date','hour',
                          'zone','archetype','event_name']) \

        grp = pd.Series(grp.to_dict(orient='records'),grp.index) \
                .to_frame().reset_index() \
                .rename(columns={0:'json_blob'})
        grp = grp[['device_id',timestamp','blob',
                   'date','hour','zone','archetype','event_name']]

        grp.to_csv(sys.stdout, sep=OUTSEP, index=False, header=False)

根据纱线配置以及首先达到极限的情况,我收到了错误消息:

  1. 错误:Java堆空间

  2. 超出了GC开销限制

  3. 超出物理内存限制

0 个答案:

没有答案