从Spark读取Mongo数据

时间:2017-09-11 12:45:01

标签: mongodb scala apache-spark

我正在使用com.mongodb.spark.sql连接器(v 2.0.0)在spark作业上从mongodb读取数据。 它适用于大多数db,但对于特定的db,该阶段需要很长时间,并且分区数量非常高。 我的程序设置在128个分区(x2个vCPU)上,经过一些测试我们做了很好的工作。在此加载时,数字跳转到2061个分区,并且该阶段需要几分钟才能处理,即使我使用过滤器并且文档清楚地指出过滤器是在下划线数据源上完成的(https://docs.mongodb.com/spark-connector/v2.0/scala/datasets-and-sql/

这是我阅读数据的方式:

val readConfig: ReadConfig = ReadConfig(
    Map(
      "spark.mongodb.input.uri" -> s"${mongodb.uri}/?${mongodb.uriParams}",
      "spark.mongodb.input.database" -> s"${mongodb.dbNamesConfig.siteInstances}",
      "collection" -> params.collectionName
    ), None)

  val df: DataFrame = sparkSession.read.format("com.mongodb.spark.sql").options(readConfig.asOptions)
    .schema(impressionSchema)
    .load()

  println("df: " + df.rdd.getNumPartitions) // this is 2061 partitions


  val filteredDF = df.coalesce(128).filter(
    $"_timestamp".isNotNull
      .and($"_timestamp".between(new Timestamp(start.getMillis()), new Timestamp(end.getMillis())))   
      .and($"component_type" === SITE_INSTANCE_CHART_COMPONENT)
  )

  println("filteredDF: " + filteredDF.rdd.getNumPartitions) // 128 after using coalesce

  filteredDF.select(
    $"iid",
    $"instance_id".as("instanceId"),
    $"_global_visitor_key".as("globalVisitorKey"),
    $"_timestamp".as("timestamp"),
    $"_timestamp".cast(DataTypes.DateType).as("date")
  )

数据不是很大(此阶段的随机写入为20MB),即使我只过滤1个文档,运行时间也相同(只有Shuffle Write要小得多)。

如何解决这个问题?

由于 尼尔

0 个答案:

没有答案