Scala 将数据帧从spark集群写入cassandra集群:分区和性能调优

Scala 将数据帧从spark集群写入cassandra集群:分区和性能调优,scala,apache-spark,cassandra,datastax-java-driver,spark-cassandra-connector,Scala,Apache Spark,Cassandra,Datastax Java Driver,Spark Cassandra Connector,我有两个集群- 1.Cloudera Hadoop-Spark作业在此处运行 2.云-卡桑德拉集群,多个DC 在将spark作业中的数据帧写入cassandra集群时,我正在spark中进行重新分区(repartionCount=10),然后再写入。见下文: import org.apache.spark.sql.cassandra._ records.repartition(repartitionCount).write.cassandraFormat(table, keySpace) .

我有两个集群- 1.Cloudera Hadoop-Spark作业在此处运行 2.云-卡桑德拉集群,多个DC

在将spark作业中的数据帧写入cassandra集群时,我正在spark中进行重新分区(repartionCount=10),然后再写入。见下文:

import org.apache.spark.sql.cassandra._
records.repartition(repartitionCount).write.cassandraFormat(table, keySpace)
  .mode(SaveMode.Append)
  .options(options)
  .option(CassandraConnectorConf.LocalDCParam.name, cassandraDC.name)
  .option(CassandraConnectorConf.ConnectionHostParam.name, cassandraDC.hosts)
  .save()
在我的多租户spark集群中,对于具有2000万条记录的spark批处理负载以及以下配置,我看到了大量的任务失败、资源抢占和动态失败

spark.cassandra.output.batch.grouping.buffer.size=1000
spark.cassandra.output.batch.grouping.key=partition
spark.cassandra.output.concurrent.writes=20 
spark.cassandra.connection.compression=LZ4
我应该如何调整这个?是重新分配造成的吗

PS:一开始我的理解是:对于一个有2000万行的负载,“重新分配”应该将负载均匀地分配到执行器上(每个分区有2M行),批处理将在这些分区级别(2M行)上完成。但是现在,我怀疑如果spark cassandra连接器在整个数据帧级别(整个20M行)上进行批处理,这是否会导致不必要的混乱


更新:删除“重新分区”大大降低了我的cloudera spark群集的性能(spark级别的默认分区设置为-
spark.sql.shuffle.partitions:200
),因此我深入研究了一下,发现我最初的理解是正确的。请注意,我的spark和cassandra群集是不同的。Datastax spark cassandra连接器使用cassandra协调器节点为每个分区打开一个连接,因此我决定让它保持不变。正如Alex所建议的,我已经减少了并发写入,我相信这会有所帮助

您不需要在Spark中执行重新分区-只需将数据从Spark写入Cassandra,不要尝试更改Spark Cassandra连接器默认值-它们在大多数情况下都可以正常工作。您需要查看发生了什么类型的阶段故障-很可能您只是因为
spark.Cassandra.output.concurrent.writes=20
(使用默认值(
5
))而导致Cassandra过载-有时编写器较少有助于更快地写入数据,因为您不会过载Cassandra,作业也不会重新启动


p.S.
spark.cassandra.output.batch.grouping.key中的
partition
-这不是spark分区,而是取决于partition key列的值的cassandra分区。

非常感谢。随着并行写入cassandra集群的批处理作业数量的增加,我的集群中出现了很多问题。每个批处理作业虽然很大,但基数很高,其中单个分区(cassandra)通常少于1000行,因此批处理在运行时可能较小,从而导致对cassandra的写入请求较多。此外,我还观察到卡桑德拉·里德很少在写得很重的时候会往下读,尽管写的速度总是很快。在我的场景中,replica_是否设置了一个好选项,以及上面的建议。如果您的Cassandra节点在读取过程中频繁停机,您可能需要调整输入参数。例如,使用
LOCAL\u ONE
读取通常会使节点过载,而使用
LOCAL\u QUORUM
读取会减少单个节点的负载,而且由于它不会崩溃,因此它读取速度更快,尽管
LOCAL\u QUORUM
比使用每个\u QUORUM写入、使用LOCAL\u QUORUM读取的速度慢。Cassandra没有停机,但在大量写入期间,读取延迟增加了很多倍。这是意料之中的,但主要的是节点没有停机