spark-redshift 写入 redshift 需要很多时间

spark-redshift takes a lot of time to write to redshift

我正在使用运动和红移设置 spark streamer。我每 10 秒从 kinesis 读取一次数据,对其进行处理并使用 spark-redshift lib 将其写入 redshift。

问题是只写 300 行要花很多时间。

这是它在控制台中显示的内容

[Stage 56:====================================================> (193 + 1) / 200]

看我的日志df.write.format就是这样做的

我在一台有 4 GB 内存和 2 核亚马逊 EC2 的机器上安装了 Spark,运行 --master local[*] 模式。

这是我创建流的方式

kinesisStream = KinesisUtils.createStream(ssc, APPLICATION_NAME, STREAM_NAME, ENDPOINT, REGION_NAME, INITIAL_POS, CHECKPOINT_INTERVAL, awsAccessKeyId =AWSACCESSID, awsSecretKey=AWSSECRETKEY, storageLevel=STORAGE_LEVEL)    
CHECKPOINT_INTERVAL = 60
storageLevel = memory

kinesisStream.foreachRDD(writeTotable)
def WriteToTable(df, type):
    if type in REDSHIFT_PAGEVIEW_TBL:
        df = df.groupby([COL_STARTTIME, COL_ENDTIME, COL_CUSTOMERID, COL_PROJECTID, COL_FONTTYPE, COL_DOMAINNAME, COL_USERAGENT]).count()
        df = df.withColumnRenamed('count', COL_PAGEVIEWCOUNT)

        # Write back to a table

        url = ("jdbc:redshift://" + REDSHIFT_HOSTNAME + ":" + REDSHIFT_PORT + "/" +   REDSHIFT_DATABASE + "?user=" + REDSHIFT_USERNAME + "&password="+ REDSHIFT_PASSWORD)

        s3Dir = 's3n://' + AWSACCESSID + ':' + AWSSECRETKEY + '@' + BUCKET + '/' + FOLDER

        print 'Start writing to redshift'
        df.write.format("com.databricks.spark.redshift").option("url", url).option("dbtable", REDSHIFT_PAGEVIEW_TBL).option('tempdir', s3Dir).mode('Append').save()

        print 'Finished writing to redshift'

请告诉我为什么要花这么多时间

我在通过 Spark 和直接写入 Redshift 时有过类似的经历。 spark-redshift会一直将数据写入S3,然后使用Redshift复制功能将数据写入目标table。这种方法是写入大量记录的最佳实践和最有效的方法。这种方法还会对写入造成大量开销,尤其是当每次写入的记录数相对较小时。

查看上面的输出,您的分区数量似乎很多(大概 200 个左右)。这可能是因为 spark.sql.shuffle.partitions 设置默认设置为 200。您可以找到更多详细信息 in the Spark documentation.

组操作可能生成 200 个分区。这意味着您正在对 S3 执行 200 次单独的复制操作,每个操作在获取连接和完成写入方面都有大量相关的延迟。

正如我们在下面的评论和聊天中讨论的那样,您可以将 group by 的结果合并到更少的分区中,对上面的行进行以下更改:

df = df.coalesce(4).withColumnRenamed('count', COL_PAGEVIEWCOUNT)

这会将分区数量从 200 减少到 4,并将从副本到 S3 的开销减少几个数量级。您可以试验分区数以优化性能。您还可以更改 spark.sql.shuffle.partitions 设置,以根据您正在处理的数据大小和可用内核的数量来减少分区数量。

你是数据块吗API。这是已知问题。我有同样的问题。我确实和 Databric API 团队谈过。从 Avaro 文件加载时,redshift 似乎没有提供良好的性能。我们确实与 AWS 团队进行了交谈。他们正在努力。 Databrick API 正在 S3 上创建 avaro 文件,然后复制命令将加载 avaro 文件。那是性能杀手。