SparkStreaming “Could not read data from write ahead log record” 报错分析解决
# if open wal
org.apache.spark.SparkException: Could not read data from write ahead log record FileBasedWriteAheadLogSegment
SparkStreaming开启了checkpoint wal后有时会出现如上报错,但不会影响整体程序,只会丢失报错的那个job的数据。其根本原因是wal文件被删了,被sparkstreaming自己的清除机制删掉了。通常意味着一定程度流式程序上存在速率不匹配或堆积问题。
查看driver日志可发现类似如下的日志:
-- :: INFO [Logging.scala:] Attempting to clear old log files in hdfs://alps-cluster/tmp/banyan/checkpoint/RhinoWechatConsumer/receivedBlockMetadata older than 1490248380000:
-- :: INFO [Logging.scala:] Attempting to clear old log files in hdfs://alps-cluster/tmp/banyan/checkpoint/RhinoWechatConsumer/receivedBlockMetadata older than 1490248470000: hdfs://alps-cluster/tmp/banyan/checkpoint/RhinoWechatConsumer/receivedBlockMetadata/log-1490248404471-1490248464471
-- :: INFO [Logging.scala:] Cleared log files in hdfs://alps-cluster/tmp/banyan/checkpoint/RhinoWechatConsumer/receivedBlockMetadata older than 1490248470000
-- :: ERROR [Logging.scala:] Task in stage 35.0 failed times; aborting job
-- :: ERROR [Logging.scala:] Error running job streaming job ms.
org.apache.spark.SparkException: Job aborted due to stage failure: Task in stage 35.0 failed times, most recent failure: Lost task 41.3 in stage 35.0 (TID , alps60): org.apache.spark.SparkException: Could not read data from write ahead log record FileBasedWriteAheadLogSegment(hdfs://alps-cluster/tmp/banyan/checkpoint/RhinoWechatConsumer/receivedData/0/log-1490248403649-1490248463649,44333482,118014)
at org.apache.spark.streaming.rdd.WriteAheadLogBackedBlockRDD.org$apache$spark$streaming$rdd$WriteAheadLogBackedBlockRDD$$getBlockFromWriteAheadLog$(WriteAheadLogBackedBlockRDD.scala:)
可以发现 1490248403649 的日志被删除程序删除了(cleared log older than 1490248470000),然后这个wal就报错了。
Spark官方文档没有任何关于这个的配置,因此直接看源码。(spark很多这样的坑,得看源码才知道如何hack或有些隐藏配置)。
1.FileBasedWriteAheadLogSegment 类中根据日志搜索发现了clean方法(后面的逻辑就是具体删除逻辑,暂不关心),核心就是如何调整这个threshTime了。
/**
* Delete the log files that are older than the threshold time.
*
* Its important to note that the threshold time is based on the time stamps used in the log
* files, which is usually based on the local system time. So if there is coordination necessary
* between the node calculating the threshTime (say, driver node), and the local system time
* (say, worker node), the caller has to take account of possible time skew.
*
* If waitForCompletion is set to true, this method will return only after old logs have been
* deleted. This should be set to true only for testing. Else the files will be deleted
* asynchronously.
*/
def clean(threshTime: Long, waitForCompletion: Boolean): Unit = {
val oldLogFiles = synchronized {
val expiredLogs = pastLogs.filter { _.endTime < threshTime }
pastLogs --= expiredLogs
expiredLogs
}
logInfo(s"Attempting to clear ${oldLogFiles.size} old log files in $logDirectory " +
s"older than $threshTime: ${oldLogFiles.map { _.path }.mkString("\n")}")
2.一步步看调用追踪出去,ReceivedBlockHandler -> ReceiverSupervisorImpl -> CleanUpOldBlocks 。这里有个和ReceiverTracker通信的rpc,因此直接搜索CleanUpOldBlocks -> ReceiverTracker -> JobGenerator
在JobGenerator.clearCheckpointData 中有这么一段逻辑
/** Clear DStream checkpoint data for the given `time`. */
private def clearCheckpointData(time: Time) {
ssc.graph.clearCheckpointData(time) // All the checkpoint information about which batches have been processed, etc have
// been saved to checkpoints, so its safe to delete block metadata and data WAL files
val maxRememberDuration = graph.getMaxInputStreamRememberDuration()
jobScheduler.receiverTracker.cleanupOldBlocksAndBatches(time - maxRememberDuration)
jobScheduler.inputInfoTracker.cleanup(time - maxRememberDuration)
markBatchFullyProcessed(time)
}
发现了 ssc.graph有个 maxRememberDuration 的成员属性!这就意味着有机会通过ssc去修改它。
搜索一下代码便发现了相关方法:
jssc.remember(new Duration(2 * 3600 * 1000));
反思:
从之前的日志我们发现默认的清除间隔是几十秒左右,但是在代码中我们可以发现这个参数只能被设置一次(每次设置都会检查当前为null才生效,初始值为null)。所以问题来了,这几十秒在哪里设置的?代码一时没找到,于是项目直接搜索 remember,发现了在DStream里的初始化代码(其中slideDuration初始化来自InputDStream)。根据计算,我们的batchInterval为15s,其他两个没有设置,则checkpointDuration 为15s,rememberDuration为30s。
override def slideDuration: Duration = {
if (ssc == null) throw new Exception("ssc is null")
if (ssc.graph.batchDuration == null) throw new Exception("batchDuration is null")
ssc.graph.batchDuration
}
/**
* Initialize the DStream by setting the "zero" time, based on which
* the validity of future times is calculated. This method also recursively initializes
* its parent DStreams.
*/
private[streaming] def initialize(time: Time) {
if (zeroTime != null && zeroTime != time) {
throw new SparkException("ZeroTime is already initialized to " + zeroTime
+ ", cannot initialize it again to " + time)
}
zeroTime = time
// Set the checkpoint interval to be slideDuration or 10 seconds, which ever is larger
if (mustCheckpoint && checkpointDuration == null) {
checkpointDuration = slideDuration * math.ceil(Seconds(10) / slideDuration).toInt
logInfo("Checkpoint interval automatically set to " + checkpointDuration)
}
// Set the minimum value of the rememberDuration if not already set
var minRememberDuration = slideDuration
if (checkpointDuration != null && minRememberDuration <= checkpointDuration) {
// times 2 just to be sure that the latest checkpoint is not forgotten (#paranoia)
minRememberDuration = checkpointDuration * 2
}
if (rememberDuration == null || rememberDuration < minRememberDuration) {
rememberDuration = minRememberDuration
}
// Initialize the dependencies
dependencies.foreach(_.initialize(zeroTime))
}
SparkStreaming “Could not read data from write ahead log record” 报错分析解决的更多相关文章
- sass-loader使用data引入公用文件或全局变量报错
报错信息: ValidationError: Invalid options object. Sass Loader has been initialised using an options obj ...
- vue调用组件,组件回调给data中的数组赋值,报错Invalid prop type check failed for prop value. Expecte
报错信息: 代码信息:调用一个tree组件,选择一些信息 <componentsTree ref="typeTreeComponent" @treeCheck="t ...
- 详细解读 :java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed,Java报错之Connection is read-only.
问题分析: 实际开发项目中,进行insert的时候,产生这个问题是Spring框架的一个安全权限保护方法,对于方法调用的事物保护,一般配置如下: <!-- 事务管理 属性 --> < ...
- filebeat+kafka+SparkStreaming程序报错及解决办法
// :: WARN RandomBlockReplicationPolicy: Expecting replicas with only peer/s. // :: WARN BlockManage ...
- @Data注解使用后get set报错解决方法
Maven项目中已经导入相关的lombok.jar包但是使用后仍提示无set/get方法 .在idea中安装如下插件,安装后重启idea可用不报错. 转载于:https://www.cnblogs.c ...
- The data property "dialogVisble" is already declared as a prop. Use prop default value instead报错原因
vue中使用props传递数据就不能在子组件的data中用同样的名字(比如dialogVisble)了,否则会报错.解决方法直接去掉data中的相同名字改为其他的.
- jQuery Ajax请求(关于火狐下SyntaxError: missing ] after element list ajax返回json,var json = eval("("+data+")"); 报错)
$.ajax({ contentType: "application/x-www-form-urlencoded;charset=UTF-8" , type: &quo ...
- 1125MySQL Sending data导致查询很慢的问题详细分析
-- 问题1 tablename使用主键索引反而比idx_ref_id慢的原因EXPLAIN SELECT SQL_NO_CACHE COUNT(id) FROM dbname.tbname FORC ...
- HBase的Write Ahead Log (WAL) —— 整体架构、线程模型
解决的问题 HBase的Write Ahead Log (WAL)提供了一种高并发.持久化的日志保存与回放机制.每一个业务数据的写入操作(PUT / DELETE)执行前,都会记账在WAL中. 如果出 ...
随机推荐
- webstorm我用到的快捷键【不断更新】
alt+insert:新建一个文件或其他 ctrl+shift+l:代码格式化 [可能会和qq的锁屏键冲突] ctrl+shift+r:批量查找替换 多点编辑:按住alt键选择多列,就可以编辑多行了 ...
- 最大子数组(I, II, III,IV,V)和最大子数组乘积 (动态规划)
I 找一个连续最大子数组,sum加到nums[i], 如果前面子数组和<0则舍去,从头开始. class Solution { public: /** * @param nums: A list ...
- openstack2 kvm
一.kvm安装 1.首先虚拟机的话需要打开虚拟化功能,服务器的话需要在bios中设置 2.安装kvm用户态管理工具qemu-kvm 和 用来管理kvm虚拟机的插件libvirt和创建虚拟机用的virt ...
- Vue全局API总结
1.extend用于创建一个子类Vue,用$mount来挂载 <body> <div id="app"></div> <script> ...
- jquery|js|jq常用正则
var mobReg=/^1[34578]\d{9}$/; //手机号 if (!mobReg.test(mob)) { mui.alert("请填写正确手机号!"," ...
- BZOJ3437 小P的牧场 动态规划 斜率优化
原文链接http://www.cnblogs.com/zhouzhendong/p/8696321.html 题目传送门 - BZOJ3437 题意 给定两个序列$a,b$,现在划分$a$序列. 被划 ...
- day 51 js-2 函数,对象,正则 (定时器示例)
本文转载自cnblogs.liwenzhou-----哪吒博客 先来一个定时器让我们看看函数的效果: <script src="/js/jquery-3.2.1.min.js" ...
- android studio使用CMake和NDK,实现应用自身被卸载时打开某一网址
实现应用自身被卸载时打开某一网址的c代码 MyActivity: public class MyActivity extends Activity { /** * Called when the ac ...
- IO流巧记图
本文特意将各种IO流的类总结到一起,作成图,方便记忆 1.流的写入和读取 2.字符输入流 3.字符输出流 4.字节输入流 5.字节输出流 6.概念杂记 * Buffered;带缓冲区的字符读取流,高效 ...
- [ 高危 ] mt网主站SQL注入
rank 75 金币 75 等价RMB 750 数据包样式如下 POST /ajax.php HOST: xxx.meituan.com Cookie: xxx id=123&job= ...