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 文件。那是性能杀手。
我正在使用运动和红移设置 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 文件。那是性能杀手。