Mongodb hadoop连接器创建了很多分区,即使我向其中添加了查询
我有一个非常大的mongo表,我想用spark对它进行一些分析,它太大了,我不想加载整个数据库。但它看起来总是扫描整个数据库,并将它们分割成大量的分区,即使我将Mongodb hadoop连接器创建了很多分区,即使我向其中添加了查询,mongodb,hadoop,apache-spark,Mongodb,Hadoop,Apache Spark,我有一个非常大的mongo表,我想用spark对它进行一些分析,它太大了,我不想加载整个数据库。但它看起来总是扫描整个数据库,并将它们分割成大量的分区,即使我将mongo.input.query传递给它。我正在使用加载它,我的代码如下所示: val conf = new SparkConf().setAppName("Simple Application") val sc = new SparkContext(conf) val mongoConfig = new Configuration(
mongo.input.query
传递给它。我正在使用加载它,我的代码如下所示:
val conf = new SparkConf().setAppName("Simple Application")
val sc = new SparkContext(conf)
val mongoConfig = new Configuration()
val beginDate = new Date(2016 - 1900,6,7)
println("the begin data is: =========== >" + beginDate)
val beginId = new ObjectId(beginDate, 0,0.toShort,0)
mongoConfig.set("mongo.input.uri",
"mongodb://mymongoduri/mongodb.mongocollection")
val queryStr = """{"_id": {"$gt" : {"$oid":"beginDate" }}}""".replace("beginDate", beginId.toString)
mongoConfig.set("mongo.input.query", queryStr)
mongoConfig.set("mongo.input.fields", """{ "its.src":-1, "its._id":-1, "its.cid": -1}""")
val documents = sc.newAPIHadoopRDD(
mongoConfig, // Configuration
classOf[MongoInputFormat], // InputFormat
classOf[Object], // Key type
classOf[BSONObject]) // Value type
val OUTPUT_PATH = if(ENV == Some("dev")){
s"./result"
} else{
s"s3://${OUTPUT_BUCKET}/output/graph/${beginDate}"
}
documents.saveAsNewAPIHadoopFile(
OUTPUT_PATH,
classOf[Object],
classOf[BSONObject],
classOf[BSONFileOutputFormat[Object, BSONObject]]
)
它最终在s3中产生了大量的空文件,这不是我期望的结果(而且浪费了很多钱)
我已经阅读了文档,它说mongo.input.query
仅使用查询过滤输入集合
,我可以按照我查询的内容加载数据吗?不仅仅是过滤它们
或者,我可以只存储那些不为空的分区吗?spark hadoop connector for mongo始终读取整个集合并相应地进行分区,然后使用输入查询过滤对象。在保存文档RDD时,无论它是否为空,它都会保存分区
您可以将RDD重新分区为1。或者使用
documents.coalesce(1).saveAsNewAPIHadoopFile(..)
spark hadoop connector for mongo始终读取整个集合并进行相应的分区,然后使用输入查询筛选对象。在保存文档RDD时,无论它是否为空,它都会保存分区
您可以将RDD重新分区为1。或者使用
documents.coalesce(1).saveAsNewAPIHadoopFile(..)
我非常仔细地检查了代码。我发现默认的拆分器总是扫描整个数据库,而当您进行拆分时,com.mongodb.hadoop.splitter.MongoPaginatingSplitter
将应用查询
然后,我发现他们的wiki中的configurationmongo.splitter.class
下有一些东西:
com.mongodb.hadoop.splitter.MongoPaginatingSplitter
:
此拆分器构建增量范围查询以覆盖查询。此拆分器需要更多的工作来计算拆分边界,但在给定mongo.input.query时,它的性能优于其他拆分器
所以我认为这应该是我问题的最终答案。我非常仔细地检查了代码。我发现默认的拆分器总是扫描整个数据库,而当您进行拆分时,
com.mongodb.hadoop.splitter.MongoPaginatingSplitter
将应用查询
然后,我发现他们的wiki中的configurationmongo.splitter.class
下有一些东西:
com.mongodb.hadoop.splitter.MongoPaginatingSplitter
:
此拆分器构建增量范围查询以覆盖查询。此拆分器需要更多的工作来计算拆分边界,但在给定mongo.input.query时,它的性能优于其他拆分器
所以我认为这应该是我问题的最终答案。非常感谢,我已经尝试了coalesce(20),但是看起来将100k个分区合并成一个分区太难了,我正在尝试coalesce(10000)。coalesce(1000)。coalesce(100)。coalesce(20)。顺便问一下,有没有任何连接器不能读取整个集合?我只想查询其中的一部分。嗨,请阅读我的答案,spark hadoop连接器确实提供了一个拆分器来使用查询。你不需要扫描整个数据库,很好。我之前没有意识到。非常感谢,我已经尝试了coalesce(20),但是看起来将100k个分区合并成一个分区太难了,我正在尝试coalesce(10000)。coalesce(1000)。coalesce(100)。coalesce(20)。顺便问一下,有没有任何连接器不能读取整个集合?我只想查询其中的一部分。嗨,请阅读我的答案,spark hadoop连接器确实提供了一个拆分器来使用查询。你不需要扫描整个数据库,很好。我之前没有意识到这一点。