1

我们正在从Redshift迁移到Spark。我有一张Redshift表格,需要导出到S3。从S3开始,这将被提供给Apache Spark(EMR)。将数据从Amazon Redshift导出为JSON

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

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

回答

2

在我建立了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用于生成{}字符

这个操作是不一样快卸刚刚以csv。它需要2-3倍的时间。但是,因为我们需要做一次,它很好。我卸载了大约1600万条记录并成功导入了Spark中的所有记录。

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

+0

这真棒,帮了我很多!谢谢! – unpairestgood

1

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

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

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

+0

我们先用这个。 'spark-redshift'使用s3传输数据。我想知道是否有任何方法可以使用这个库来卸载所有的数据?稍后我将使用火花进行处理。但它会在S3。 –

相关问题