我使用 Spark:1.6.2 和 MongoDB:3.2.8
我有一个包含8列和10亿行的数据帧。 shuffle写入数据帧是60GB。
我将使用mongo-spark-conector(mongo-spark-connector_2.10)在mongodb中插入该数据帧。
MongoSpark.write(sourceValueDf).options(mongoDbOptions).mode(SaveMode.Append).save();
对于插入,需要10个小时以上。
如何提高效果?
答案 0 :(得分:4)
还有很多事情要做:
MongoSpark.write(sourceValueDf).options(mongoDbOptions).mode(SaveMode.Append).save()
但无论mongoDBOptions
如何,调整都需要两倍,并且需要在Spark和MongoDB中修复性能瓶颈。成功的关键是了解运行上述代码时发生的情况,然后才能确定改善性能的最佳方法。
我有一个包含8列和10亿行的数据帧。 shuffle写入数据帧是60GB。
sourceValueDf
上没有任何信息,但您需要配置源并了解瓶颈是什么?请参阅Spark Monitoring文档,了解如何更好地了解Spark作业中发生的情况。
一般来说,Spark调整的关键点是; 分区,缓存,序列化和 shuffle 操作。有关更多信息,请参阅cloudera的这篇精彩博文:Working with Apache Spark: Or, How I Learned to Stop Worrying and Love the Shuffle。如何改善星火作业有很多潜在的收获。
让我们看一下MongoDB Spark连接器将使用的功能:
MongoSpark.write(sourceValueDf).options(mongoDbOptions).mode(SaveMode.Append).save()
此处连接器采用底层RDD,并使用以下逻辑将数据作为文档保存在现有数据库中:
rdd.foreachPartition(iter => if (iter.nonEmpty) {
mongoConnector.withCollectionDo(writeConfig, { collection: MongoCollection[D] =>
iter.grouped(DefaultMaxBatchSize).foreach(batch => collection.insertMany(batch.toList.asJava))
})
})
对于每个分区,它将批量写入insertMany,每批使用512个文档(底层Java驱动程序批量大小)。 sourceValueDf
中的分区数量较少会对保存的性能产生负面影响。增加分区数可能会增加此方法在Spark工作程序中的可并行性,从而增加吞吐量。
还有其他一些通用方法可以改善MongoDB批量操作的写入性能:
网络强>
确保Spark Workers和MongoDB实例共存或具有尽可能小的网络跃点。你无法击败物理学。
<强>拆分强>
通过插入分片集合来增加写入的可并行性,尤其是在插入分片键上的数据时。 Spark工作人员与Sharded MongoD的共址可以提供最快的写入方案。有关配置选项的详细信息,请参阅连接器文档中的how can I achieve data locality部分。
<强>索引强>
在插入数据之前删除索引并在之后重建它们。在插入大量数据时,用户通过在流程开始时删除索引,然后在结束时只构建一次索引,从而发现了性能改进。例如:
val writeConfig = WriteConfig(mongoDbOptions)
MongoConnector(writeConfig.asOptions).withCollectionDo(writeConfig, {
coll: MongoCollection[Document] => coll.dropIndex("index")
})
MongoSpark.write(sourceValueDf)
.options(writeConfig.asOptions)
.mode(SaveMode.Append)
.save()
MongoConnector(writeConfig.asOptions).withCollectionDo(writeConfig, {
coll: MongoCollection[Document] => coll.createIndex(...)
})
写关注
仅写入主节点而不是等待复制会以冗余为代价提高速度。这可以通过WriteConfig
/ mongoDbOptions
进行配置。请参阅Output configuration documentation。
运行此作业时,MongoDB计算机上的负载是多少?这是瓶颈吗?像MongoDB Cloud Manager这样的系统提供全面的性能可见性和监控,以帮助您了解MongoDB层发生的情况。
简而言之,没有万能药或魔术配置选项来帮助提高性能。它将需要调试,了解手头的问题,并可能考虑Spark和MongoDB集群的配置。它们一起被证明可以提供very fast compute and storage但它取决于使用情况和每个系统协同工作。
第一步是使用可用的监控工具来了解瓶颈的位置。