Spark With Mongodb 实现方法及error code -5, 6, 13127解决方案
1.spark mongo 读取
val rdd = MongoSpark.builder().sparkSession(spark).pipeline(Seq(`match`(regex("path", java.util.regex.Pattern compile r.toString)))).build.toRDD()
2.error code 6
在spark读数据时容易遇到,mongos连接池已满,操作被拒绝,需要修改spark中的connectionperhost
lazy val mongo = new MongoClient("192.168.12.161", MongoClientOptions.builder().connectionsPerHost(8).build())
然后找管理员查看Mongos当前已连接数,在过多时需要进行重启mongos ./bin/mongostat --host 192.168.12.161
PS: 修改MongoDB机器的打开文件数会明显改善此问题出现的频次,甚至不需要修改connectionsPerHost即可解决问题。修改/etc/security/limits.conf中的nofile即可,mongoDB3.4之后的版本连接数默认是65536,不用修改连接数限制。
3.error code -5
driver出现错误,任务终止
Caused by: com.mongodb.MongoCursorNotFoundException: Query failed with error code - and error message 'Cursor 2639909050433532364 not found on server 192.168.12.161:27017' on server 192.168.12.161:
at com.mongodb.operation.QueryHelper.translateCommandException(QueryHelper.java:)
at com.mongodb.operation.QueryBatchCursor.getMore(QueryBatchCursor.java:)
at com.mongodb.operation.QueryBatchCursor.hasNext(QueryBatchCursor.java:)
at com.mongodb.MongoBatchCursorAdapter.hasNext(MongoBatchCursorAdapter.java:)
at scala.collection.convert.Wrappers$JIteratorWrapper.hasNext(Wrappers.scala:)
at scala.collection.Iterator$class.foreach(Iterator.scala:)
at scala.collection.AbstractIterator.foreach(Iterator.scala:)
at org.apache.spark.rdd.RDD$$anonfun$foreach$$$anonfun$apply$.apply(RDD.scala:)
at org.apache.spark.rdd.RDD$$anonfun$foreach$$$anonfun$apply$.apply(RDD.scala:)
at org.apache.spark.SparkContext$$anonfun$runJob$.apply(SparkContext.scala:)
at org.apache.spark.SparkContext$$anonfun$runJob$.apply(SparkContext.scala:)
at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:)
at org.apache.spark.scheduler.Task.run(Task.scala:)
at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:)
at java.lang.Thread.run(Thread.java:)
cursor超时,按照官方说法为cursor10分钟未使用,查看spark日志发现是第433个分片出现错误
17/07/17 19:37:31 ERROR Executor: Exception in task 433.0 in stage 0.0 (TID 433)
com.mongodb.MongoCursorNotFoundException: Query failed with error code -5 and error message 'Cursor 2639909048849185072 not found on server 192.168.12.161:27017' on server 192.168.12.161:27017
可以看到是19:37出现的错误,这个task启动时间为:
17/07/17 19:14:23 INFO CoarseGrainedExecutorBackend: Got assigned task 433
17/07/17 19:14:23 INFO Executor: Running task 433.0 in stage 0.0 (TID 433)
可以确定的是,确实超过10分钟了,申请完cursor之后并没有开始执行,而是等到10分钟之后才开始进行操作,目前未发现原因。
查看日志发现中间有一些文件访问被拒绝的错误,:ulimit -a 看只有1024,
于是修改/etc/security/limits.conf:
* soft nofile 40960
* hard nofile 40960
修改之后不设置connectionsPerHost也不会出现访问被拒绝的错误或者error code 6,但仍旧会出现error code -5
在最新一次运行中,第452、1940、2005等分片出现错误,而且分片处于不同的executor上,也就是说此错误和计算节点无关。
在stackoverflow上发现java driver的解决方案,java里可以使用 db.find().nocursorTimeout()来解决,但需要记得关闭cursor,不然mongos会一直占用额外内存。
去github上查看mongo-spark-connector的源代码发现:
MongoRDD的compute方法:
override def compute(split: Partition, context: TaskContext): Iterator[D] = {
val client = connector.value.acquireClient()
val cursor = getCursor(client, split.asInstanceOf[MongoPartition])
context.addTaskCompletionListener((ctx: TaskContext) => {
log.debug("Task completed closing the MongoDB cursor")
Try(cursor.close())
connector.value.releaseClient(client)
})
cursor.asScala
}
getCursor的函数:
private def getCursor(client: MongoClient, partition: MongoPartition)(implicit ct: ClassTag[D]): MongoCursor[D] = {
val partitionPipeline: Seq[BsonDocument] = readConfig.partitioner match {
case MongoSinglePartitioner => pipeline
case _ => new BsonDocument("$match", partition.queryBounds) +: pipeline
}
client.getDatabase(readConfig.databaseName)
.getCollection[D](readConfig.collectionName, classTagToClassOf(ct))
.withReadConcern(readConfig.readConcern)
.withReadPreference(readConfig.readPreference)
.aggregate(partitionPipeline.asJava)
.allowDiskUse(true)
.iterator
}
对于connector来讲,每个分片创建一个Mongoclient,获取database,添加聚合数据,由于我程序中执行完toRDD操作之后直接进行了foreach,按理说不会出现获取了cursor但是未使用的状况。考虑到mongos的执行过程:一次操作获取每个shard上的一个cursor,最后把数据汇总起来返回结果。
开始怀疑是不是因为某一个节点上pipeline执行equal的操作过慢导致cursor被拒绝,后来发现即使不加pipeline也会出现问题。
后来排查是不是Mongodb并发读数据有问题,后来发现执行MongoSpark.load.toRDD.count并没有出错,而且访问速度也较有处理过程的快得多,于是决定先进行cache,然后count获取全量数据cache在本地,再对此rdd进行操作。解决问题的原理就是通过一个简单的count程序将所需要的数据全部读到分片本地,使用cache方法缓存起来,这样后面处理此RDD时就用的本地缓存数据,而不会因为处理时间过长出现curser超时的问题。 因此推荐解决方案如下: 1)单机条件下Java driver 使用
db.find().nocursorTimeout()来解决,但需要记得关闭cursor。
2) Spark环境下在代码真正的处理逻辑之前加上如下两句:
rdd.cache()
println(rdd.count())
先把读取数据cache一下,然后使用一个简单的Action操作把数据真正缓存起来
另一种可以解决但是不用每次都修改Spark代码逻辑的方法是:
先修改MongoDB的代码,把AggregateIterable加入noCursorTimeout方法,然后修改mongo-spark-connector,使用此方法。是不是很6?
因为AggregateIterable虽然和FindIterable都是获取数据的方式,但是noCursorTimeout是FindIterable的特有方法,但是又不能把connector的Aggregate方法改成Find方法,因为Find不能加Pipeline,毕竟还得加查询条件不是~
不要看没用的
4. error code 13127
Query failed with error code 13127 and error message 'cursor id 206776738953 didn't exist on server.' on server 192.168.12.161:27017
和-5错误原因是一样的,同样的解决方案。
5.spark resource引用
试了好几种方法,最稳的还是把resource拷贝到每台机器并指定绝对路径。。
Spark With Mongodb 实现方法及error code -5, 6, 13127解决方案的更多相关文章
- MySQL安装过程中对The error code is 2203的解决方案
MySQL安装过程中对The error code is 2203的解决方案 1.问题描述 Windows系统安装MySQL遇到The error code is 2203.,具体描述如下 The i ...
- SQLyog恢复数据库报错解决方法【Error Code: 2006 - MySQL server has gone away】
https://blog.csdn.net/niqinwen/article/details/8693044 导入数据库的时候 SQLyog 报错了 Error Code: 2006 – MySQL ...
- MySQL Workbench “Error Code: 1175” 的解决方法
转自:http://www.linuxidc.com/Linux/2012-04/59333.htm 当用MySQL Workbench进行数据库的批量更新时,执行一个语句会碰到以下错误提示: Err ...
- python3 中mlpy模块安装 出现 failed with error code 1的决绝办法(其他模块也可用本方法)
在python3 中安装其它模块时经常出现 failed with error code 1等状况,使的安装无法进行.而解决这个问题又非常麻烦. 接下来以mlpy为例,介绍一种解决此类安装问题的办法. ...
- window10 安装出现the error code is 2503错误的解决方法
window10 安装出现the error code is 2503错误的解决方法: 设置 C:\WINDOWS\TEMP的权限
- 【经验】Windows7、8、8.1 MSI安装错误Error Code 2502 & 2503 解决方法
[因] 今天升级TortoiseSVN到1.8.8,出现问题:Error Code 2502 & 2503,一直不能安装成功. 上网一搜,国内没找到好的解决方法,在一个外文网上找到了方案,原链 ...
- Error Code: 1064 – You have an error in your SQL syntax解决几个方法
本文转自 http://www.anyiwa.com/?p=1066 Error Code: 1064 – You have an error in your SQL syntax解决几个方法 十一月 ...
- Android 4.0 ProGuard 代码混淆 以及 proguard returned with error code 1.See console异常的解决方法
最近呢说要上线,就去找了下上线的方法...之前做过代码混淆,用的是progarud.cfg,但是呢自己反编译了之后还是无效,然后就丢着先不管了,因为实在不知道什么情况.今天来上线的时候结果总是报错,总 ...
- Command "python setup.py egg_info" failed with error code 1一种问题的解决方法
问题描述:无论是你在pycharm中直接使用import and install命令,还是pip的时候出现了Command "python setup.py egg_info" f ...
随机推荐
- EC2(elastic compute cloud,弹性计算云,又称EC2实例)
(一)定义:EC2和实例EC2(elastic compute cloud,弹性计算云),即云中的虚拟服务器. 是用于在云中创建和运行虚拟机的 Amazon Web 服务.简言之,EC2就是一部具有无 ...
- (4.21)sql server中复制查询结果集
在查询结果窗口中复制列标题似乎是一项简单的任务,但对于业余爱好者来说,这可能是一场噩梦. 没有可见的指令/链接/按钮,其中一个可以使用列标题单击和复制所选数据.让我们看看如何在SQL Server M ...
- Failed to load bundle(http://loaclhost:8081/index.bundle?platfrom=ios.....
另外RN的创建的项目可能上架审核不太容易通过,祝你好运 1.可能当前同时运行多个项目,关闭一个项目就可以,或者重启 2.init 命令默认会创建最新的版本,而目前最新的 0.45 及以上版本需要下载 ...
- vue-preview的使用
使用vue-preview做图片缩率图1.安装 npm i vue-preview -S2.如果使用vue-cli生成的项目,需要修改webpack.base.conf.js文件中的loaders,添 ...
- vuex 子组件传值
以下是基础的使用方法,详细且深入使用方法详细见博客:https://segmentfault.com/a/1190000015782272 Vuex官网地址:https://vuex.vuejs.or ...
- 使用Emmet 快速生成HTML代码
在前端开发的过程中,一个最繁琐的工作就是写 HTML.CSS 代码.数量繁多的标签.属性.尖括号.标签闭合等,让前端们甚是苦恼.于是,我向大家推荐 Emmet,它提供了一套非常简单的语法规则,书写起来 ...
- Java Selenium - 元素操作 (二)
一篇概括了常用的元素定位方法,但是找到元素还是不够的,模拟鼠标的操作,完成各个功能点的自动操作才是关键. 下面是常见的页面元素操作会涉及到的方法,不是很全,比较复杂的后面单独拿出来做案例. 一, 输入 ...
- Dapper基础入门
Dapper是一个轻量级的ORM.之前最常用的ORM是EF,其实EF底层是Ado.net实现的. 现在基本上已经远离SqlHelper时代了. Dapper是开源的 https://github.c ...
- 字符串转Int—parseInt源码实现。
public static int parseInt(String s, int radix) throws NumberFormatException{ /* * WARNING: This met ...
- LeetCode111.二叉树的最小深度
给定一个二叉树,找出其最小深度. 最小深度是从根节点到最近叶子节点的最短路径上的节点数量. 说明: 叶子节点是指没有子节点的节点. 示例: 给定二叉树 [3,9,20,null,null,15,7], ...