将Amazon Redshift中的数据导出为JSON

时间:2016-10-25 10:27:00

标签: amazon-web-services apache-spark amazon-s3 mapreduce amazon-redshift

我们正在从Redshift迁移到Spark。我在Redshift中有一个表,我需要导出到S3。从S3开始,这将被提供给Apache Spark(EMR)。

我发现只有一种方法可以从Redshift导出数据。这是UNLOAD命令。并且卸载无法导出类型化数据。它导出csv,这是一个字符串表。基于不同的格式(引用,分隔符等),Spark似乎并没有很好地认识到它。所以我正在寻找一种卸载它们的方法,并确保它们被适当类型的火花读取。

有没有办法将数据卸载为JSON或Spark可识别的其他类型格式?

3 个答案:

答案 0 :(得分:5)

最后,我使用字符串连接手动构建了JSON,

# UPLOAD AS JSON
UNLOAD ('SELECT CHR(123)||
\'"receiver_idfa":"\'||nvl(receiver_idfa,\'\')||\'",\'||
\'"brand":"\'||nvl(brand,\'\')||\'",\'||
\'"total":\'||nvl(total,0)||\',\'||
\'"screen_dpi":\'||nvl(screen_dpi,0)||\',\'||
\'"city":"\'||nvl(city,\'\')||\'",\'||
\'"wifi":\'||nvl(convert(integer,wifi),0)||\',\'||
\'"duration":\'||nvl(duration,0)||\',\'||
\'"carrier":"\'||nvl(carrier,\'\')||\'",\'||
\'"screen_width":\'||nvl(screen_width,0)||\',\'||
\'"time":\'||nvl("time",0)||\',\'||
\'"ts":"\'||nvl(ts,\'1970-01-01 00:00:00\')||\'",\'||
\'"month":\'||nvl(month,0)||\',\'||
\'"year":\'||nvl(year,0)||\',\'||
\'"day":\'||nvl(day,0)||\',\'||
\'"hour":\'||nvl(hour,0)||\',\'||
\'"minute":\'||nvl(minute,0)||
chr(125) from event_logs')                                                                                              
TO 's3://BUCKET/PREFIX/KEY'
WITH CREDENTIALS AS 'CREDENTIALS...' 
GZIP
DELIMITER AS '\t'
;

下面,

  1. nvl函数用于替换空值
  2. convert用于将布尔值替换为int
  3. ||是Redshift中的连接运算符
  4. chr用于生成{}字符
  5. 此操作没有像csv那样快速卸载。它会花费2-3倍的时间。但是,由于我们需要做一次,它很好。我卸载了大约1600万条记录,并成功地在Spark中导入了所有记录。

    注意:通过spark解析json不是有效的方法。还有其他更快的格式,如镶木地板文件,序列文件。所以对于火花来说,这可能不是一条正确的道路。但是对于卸载为JSON,您可以使用此解决方案。

答案 1 :(得分:1)

因为Redshift是基于postgresql的RDBMS;可能没有一种简单的方法可以提取到json。运行卸载'csv'的卸载命令后,可以将该csv转换为json格式

这是一个github项目:https://github.com/darwin/csv2json

如果您想要一个基于命令的工具:https://www.npmjs.com/package/csvtojson

答案 2 :(得分:1)

查看spark-redshift库,该库旨在允许Apache Spark使用UNLOAD从Redshift进行批量读取;它会自动管理转义和模式处理。

您可以直接针对从Redshift加载的数据运行Spark查询,也可以将Redshift数据保存为Parquet等类型格式,然后查询该数据。

完全披露:我是该图书馆的主要维护者。