问题背景
本次进行一个项目的重构,在某些活动数据量比较大的情况下,会偶尔出现1200s超时的情况,如下:
AttemptID:attempt_1410771599055_11709_m_000033_0 Timed out after 1200 secs
而hadoop会不断启动备份任务进行重试,重试也许成功,但失败的概率还是比较大:
经过分析,hadoop的任务都有个超时时间,使用下面的参数设置,表示1200s后如果没有进展,就会任务该任务超时,将其状态设置为FAILED。
-Dmapreduce.task.timeout=1200000
到底因为什么原因导致超时?为了继续分析这个问题,我们将这个参数设置得非常之大。
调整超时参数
将超时时间设置为24小时之后,发现任务不会FAILED,但是其执行了大概40多个小时,仍然还没有执行完成。
还好我们在任务执行过程中打了不少的log,以帮助分析问题。经过日志的分析,我们发现有下面的现象:
2014-09-22 00:17:29,005 INFO [main] com.xxx.yo.phase1.Phase1Mapper: history(caid: 2000037, superid: 77477) is collected! 2014-09-22 00:17:29,005 INFO [main] com.xxx.yo.phase1.Phase1Mapper: history(caid: 2000037, superid: 77477) is collected! 2014-09-22 00:17:29,005 INFO [main] com.xxx.yo.phase1.Phase1Mapper: history(caid: 2000037, superid: 77477) is collected! 2014-09-22 01:17:29,054 INFO [main] com.xxx.yo.phase1.Phase1Mapper: history(caid: 2000037, superid: 120096) is collected! 2014-09-22 01:17:29,064 INFO [main] com.xxx.yo.phase1.Phase1Mapper: history(caid: 2000037, superid: 120096) is collected! 2014-09-22 01:17:29,064 INFO [main] com.xxx.yo.phase1.Phase1Mapper: history(caid: 2000037, superid: 120096) is collected! 2014-09-22 01:17:29,064 INFO [main] com.xxx.yo.phase1.Phase1Mapper: history(caid: 2000037, superid: 120096) is collected! ... 2014-09-22 01:17:36,590 INFO [main] com.xxx.yo.phase1.Phase1Mapper: history(caid: 2000037, superid: 164747) is collected! 2014-09-22 01:17:36,590 INFO [main] com.xxx.yo.phase1.Phase1Mapper: history(caid: 2000037, superid: 164747) is collected! 2014-09-22 01:17:36,590 INFO [main] com.xxx.yo.phase1.Phase1Mapper: history(caid: 2000037, superid: 164747) is collected! 2014-09-22 01:17:36,590 INFO [main] com.xxx.yo.phase1.Phase1Mapper: history(caid: 2000037, superid: 164747) is collected! 2014-09-22 02:17:36,674 INFO [main] com.xxx.yo.phase1.Phase1Mapper: history(caid: 2000037, superid: 158198) is collected! 2014-09-22 02:17:36,683 INFO [main] com.xxx.yo.phase1.Phase1Mapper: history(caid: 2000037, superid: 158198) is collected! 2014-09-22 02:17:36,683 INFO [main] com.xxx.yo.phase1.Phase1Mapper: history(caid: 2000037, superid: 158198) is collected! 2014-09-22 02:17:36,683 INFO [main] com.xxx.yo.phase1.Phase1Mapper: history(caid: 2000037, superid: 158198) is collected! .... 2014-09-22 02:17:40,888 INFO [main] com.xxx.yo.phase1.Phase1Mapper: history(caid: 2000037, superid: 203233) is collected! 2014-09-22 02:17:40,888 INFO [main] com.xxx.yo.phase1.Phase1Mapper: history(caid: 2000037, superid: 203233) is collected! 2014-09-22 02:17:40,888 INFO [main] com.xxx.yo.phase1.Phase1Mapper: history(caid: 2000037, superid: 203233) is collected! 2014-09-22 03:17:40,925 INFO [main] com.xxx.yo.phase1.Phase1Mapper: history(caid: 2000037, superid: 79188) is collected! 2014-09-22 03:17:40,934 INFO [main] com.xxx.yo.phase1.Phase1Mapper: history(caid: 2000037, superid: 79188) is collected! 2014-09-22 03:17:40,934 INFO [main] com.xxx.yo.phase1.Phase1Mapper: history(caid: 2000037, superid: 79188) is collected! 2014-09-22 03:17:40,934 INFO [main] com.xxx.yo.phase1.Phase1Mapper: history(caid: 2000037, superid: 79188) is collected!
日志分析得出的结论便是,程序总会在某个时间点休息3600秒(大概1个小时),然后再执行一会儿,便又休息3600秒。
hadoop configuration中得出初步结论
我们在这1个小时对该java进程进行监控,发现该进程在此期间(jstack命令查看其日志),一直在一个点等待:
"main" prio=10 tid=0x000000000293f000 nid=0x1e06 runnable [0x0000000041b20000] java.lang.Thread.State: RUNNABLE at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method) at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:228) at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:81) at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:87) - locked <0x00000006e243c3f0> (a sun.nio.ch.Util$2) - locked <0x00000006e243c3e0> (a java.util.Collections$UnmodifiableSet) - locked <0x00000006e243c1a0> (a sun.nio.ch.EPollSelectorImpl) at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:98) at org.apache.hadoop.net.SocketIOWithTimeout$SelectorPool.select(SocketIOWithTimeout.java:335) at org.apache.hadoop.net.SocketIOWithTimeout.doIO(SocketIOWithTimeout.java:157) at org.apache.hadoop.net.SocketInputStream.read(SocketInputStream.java:161) at org.apache.hadoop.hdfs.protocol.datatransfer.PacketReceiver.readChannelFully(PacketReceiver.java:258) at org.apache.hadoop.hdfs.protocol.datatransfer.PacketReceiver.doReadFully(PacketReceiver.java:209) at org.apache.hadoop.hdfs.protocol.datatransfer.PacketReceiver.doRead(PacketReceiver.java:171) at org.apache.hadoop.hdfs.protocol.datatransfer.PacketReceiver.receiveNextPacket(PacketReceiver.java:102) at org.apache.hadoop.hdfs.RemoteBlockReader2.readNextPacket(RemoteBlockReader2.java:170) at org.apache.hadoop.hdfs.RemoteBlockReader2.read(RemoteBlockReader2.java:135) - locked <0x00000006e12dcc78> (a org.apache.hadoop.hdfs.RemoteBlockReader2) at org.apache.hadoop.hdfs.DFSInputStream$ByteArrayStrategy.doRead(DFSInputStream.java:642) at org.apache.hadoop.hdfs.DFSInputStream.readBuffer(DFSInputStream.java:698) - eliminated <0x00000006e12dcc18> (a org.apache.hadoop.hdfs.DFSInputStream) at org.apache.hadoop.hdfs.DFSInputStream.readWithStrategy(DFSInputStream.java:752) at org.apache.hadoop.hdfs.DFSInputStream.read(DFSInputStream.java:793) - locked <0x00000006e12dcc18> (a org.apache.hadoop.hdfs.DFSInputStream) at java.io.DataInputStream.read(DataInputStream.java:149) at com.xxx.app.MzSequenceFile$PartInputStream.read(MzSequenceFile.java:451) at org.apache.hadoop.io.compress.DecompressorStream.getCompressedData(DecompressorStream.java:159) at org.apache.hadoop.io.compress.DecompressorStream.decompress(DecompressorStream.java:143) at org.apache.hadoop.io.compress.DecompressorStream.read(DecompressorStream.java:85) at java.io.DataInputStream.readFully(DataInputStream.java:195) at org.apache.hadoop.io.Text.readFields(Text.java:292) at org.apache.hadoop.io.serializer.WritableSerialization$WritableDeserializer.deserialize(WritableSerialization.java:71) at org.apache.hadoop.io.serializer.WritableSerialization$WritableDeserializer.deserialize(WritableSerialization.java:42) at com.xxx.app.MzSequenceFile$Reader.deserializeValue(MzSequenceFile.java:672) at com.xxx.app.MzSequenceFile$Reader.next(MzSequenceFile.java:684) at com.xxx.app.MzSequenceFile$Reader.next(MzSequenceFile.java:692) at com.xxx.yo.io.CombineFileRawLogReader.streamNext(CombineFileRawLogReader.java:284) at com.xxx.yo.io.CombineFileRawLogReader.next(CombineFileRawLogReader.java:342) at com.xxx.yo.io.CampaignRawLogReader.next(CampaignRawLogReader.java:73) at com.xxx.yo.io.CampaignRawLogReader.next(CampaignRawLogReader.java:23) at org.apache.hadoop.mapred.MapTask$TrackedRecordReader.moveToNext(MapTask.java:197) - locked <0x00000006e01dd3e0> (a org.apache.hadoop.mapred.MapTask$TrackedRecordReader) at org.apache.hadoop.mapred.MapTask$TrackedRecordReader.next(MapTask.java:183) - locked <0x00000006e01dd3e0> (a org.apache.hadoop.mapred.MapTask$TrackedRecordReader) at org.apache.hadoop.mapred.MapRunner.run(MapRunner.java:52) at org.apache.hadoop.mapred.MapTask.runOldMapper(MapTask.java:429) at org.apache.hadoop.mapred.MapTask.run(MapTask.java:341) at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:162) at java.security.AccessController.doPrivileged(Native Method) at javax.security.auth.Subject.doAs(Subject.java:415) at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1491)
当时初步怀疑是JDK版本问题,Java NIO也确实存在着臭名昭著的epoll空轮询导致CPU100%问题,但这个bug在JDK6中的高版本就已经解决了,更何况我们使用的是1.7。而且我们通过top -p 进程id的方式查看其CPU占用率为0,排除了该bug。
经过日志的初步分析,发现3600s这个线索,从job的configuration中,初步查找出参数dfs.client.socket-timeout,单位毫秒。
-Ddfs.client.socket-timeout=3600000
试验性地将这个参数修改为60ms,可以看出出现超时的概率非常大,但会不断重试以继续:
2014-09-26 12:53:03,184 WARN [main] org.apache.hadoop.hdfs.DFSClient: Failed to connect to /192.168.7.22:50010 for block, add to deadNodes and continue. java.net.SocketTimeoutException: 60000 millis timeout while waiting for channel to be ready for read. ch : java.nio.channels.SocketChannel[connected local=/192.168.7.17:22051 remote=/192.168.7.22:50010] java.net.SocketTimeoutException: 60 millis timeout while waiting for channel to be ready for read. ch : java.nio.channels.SocketChannel[connected local=/192.168.7.17:22051 remote=/192.168.7.22:50010] at org.apache.hadoop.net.SocketIOWithTimeout.doIO(SocketIOWithTimeout.java:164) at org.apache.hadoop.net.SocketInputStream.read(SocketInputStream.java:161) at org.apache.hadoop.net.SocketInputStream.read(SocketInputStream.java:131) at org.apache.hadoop.net.SocketInputStream.read(SocketInputStream.java:118) at java.io.FilterInputStream.read(FilterInputStream.java:83) at org.apache.hadoop.hdfs.protocolPB.PBHelper.vintPrefixed(PBHelper.java:1490) at org.apache.hadoop.hdfs.RemoteBlockReader2.newBlockReader(RemoteBlockReader2.java:392) at org.apache.hadoop.hdfs.BlockReaderFactory.newBlockReader(BlockReaderFactory.java:131) at org.apache.hadoop.hdfs.DFSInputStream.getBlockReader(DFSInputStream.java:1108) at org.apache.hadoop.hdfs.DFSInputStream.blockSeekTo(DFSInputStream.java:533) at org.apache.hadoop.hdfs.DFSInputStream.readWithStrategy(DFSInputStream.java:749) at org.apache.hadoop.hdfs.DFSInputStream.read(DFSInputStream.java:793) at org.apache.hadoop.hdfs.DFSInputStream.read(DFSInputStream.java:601) at java.io.DataInputStream.readInt(DataInputStream.java:387) at com.xxx.app.MzSequenceFile$Reader.init(MzSequenceFile.java:521) at com.xxx.app.MzSequenceFile$Reader.<init>(MzSequenceFile.java:515) at com.xxx.app.MzSequenceFile$Reader.<init>(MzSequenceFile.java:505) at com.xxx.yo.io.CombineFileRawLogReader.<init>(CombineFileRawLogReader.java:146) at com.xxx.yo.io.CampaignRawLogReader.next(CampaignRawLogReader.java:64) at com.xxx.yo.io.CampaignRawLogReader.next(CampaignRawLogReader.java:22) at org.apache.hadoop.mapred.MapTask$TrackedRecordReader.moveToNext(MapTask.java:197) at org.apache.hadoop.mapred.MapTask$TrackedRecordReader.next(MapTask.java:183) at org.apache.hadoop.mapred.MapRunner.run(MapRunner.java:52) at org.apache.hadoop.mapred.MapTask.runOldMapper(MapTask.java:429) at org.apache.hadoop.mapred.MapTask.run(MapTask.java:341) at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:162) at java.security.AccessController.doPrivileged(Native Method) at javax.security.auth.Subject.doAs(Subject.java:415) at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1491) at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:157)
于是,最终将这个参数设置为60s,这其实也是集群最终默认的超时时间,由于之前一次不明就里的优化,导致了后续这些问题的发生,因此在调整参数时,一定要注意了解清楚该参数造成的影响。
简要分析的结论
在Mapper端读取HDFS上的文件时,可能由于网络原因(由于我们的Split切分地比较大,因此不可能做到完全数据本地化)导致读取数据超时,原来居然设置成1个小时,而任务的超时时间仅设置为20分钟,因此只要发生读取数据超时,就必然会引起任务超时。
通过这次分析过程,学到了很多查找问题的方式,包括通过现象分析规律,得到线索,最终查找问题的原因。快速测试,不能忽略哪怕一个小的Exception,不行就是分析hadoop的源码,掌握其运行时行为。
对于悬挂的task,如果task tracker在一段时间(默认是10min,可以通过mapred.task.timeout属性值来设置,单位是毫秒)内一直没有收到它的进度报告,则把它标记为失效,这时候就会出现前面所说的超时错误。
TaskTracker通过心跳包告知JobTracker某个task attempt失败了,则JobTracker把该task尽量分配给另外一个task tracker来执行。如果同一个task连续4次(该值可以通过mapred.map.max.attempts和mapred.reduce.max.attempts属性值来设置)都执行失败,那JobTracker就不会再做更多的尝试了,本次job也就宣告失败了。
相关推荐
了解当前版本有助于解决配置兼容性问题以及查找相关文档。 2. hadoop.tmp.dir:这是Hadoop用于创建临时目录的基础路径。它使用了环境变量user.name,以确保临时目录是在用户的家目录下。这个路径是Hadoop工作时用于...
《Hadoop权威指南》第三版是一本深度探讨大数据处理与分析技术的重要著作,它全面而深入地介绍了Hadoop生态系统的核心组件及其应用。这本书对于想要在大数据领域深化理解、提升技能的专业人士来说,无疑是一份宝贵的...
ZooKeeper是Apache Hadoop项目中的一个分布式协调服务,它为分布式应用提供了高效且可靠的分布式同步、组服务、命名服务等。在CDH(Cloudera Distribution Including Apache Hadoop)5.13.2这个版本中,ZooKeeper被...
Zookeeper,作为一个分布式协调服务,是Apache Hadoop项目的重要组件,被广泛应用于大数据、云计算等领域的分布式系统中。它提供了一种高效且可靠的分布式一致性服务,帮助解决分布式环境下的命名服务、配置管理、...
- **MapReduce**:任务执行失败或长时间未完成时触发报警。 - **HBase**:Region负载不均衡或其他异常情况时触发报警。 #### 六、Cloudera Manager架构 Cloudera Manager的架构主要包括以下几个组成部分: - **...
5、自带一个集群文件浏览器,可以查看集群所有硬盘上的文件(不同于hadoop的namenode,没有单点问题和容量限制) 总的来说, 将集群看做一个操作系统,像操作本地文件一样操作远程文件。 但是fourinone并不提供一个...
在Zookeeper的学习过程中,下篇主要涵盖了更深入的理论概念、实战技巧以及常见问题的解决策略。Zookeeper,作为分布式协调服务的基石,广泛应用于大数据、云计算等领域,它的核心功能包括命名服务、配置管理、集群...
ZooKeeper是由Apache Hadoop项目开发的一个开源组件,它为分布式应用提供了一个高效、可靠的分布式协调解决方案。在分布式系统中,数据一致性、服务发现、配置管理、锁服务等都是常见的挑战,而ZooKeeper则提供了...
- Zookeeper是一个分布式服务框架,主要解决分布式环境中的数据一致性问题。 - 数据模型:Zookeeper的数据结构类似于文件系统,由路径、节点(znode)组成,分为临时节点和永久节点。 - 角色与架构:包含服务器...
它是一个分布式的,开放源码的分布式应用程序协调服务,是集群的必备组件,提供了一种简单有效的机制来管理和服务这些分布式应用,解决了分布式环境中的数据一致性问题。Zookeeper 3.4.10版本是其稳定且广泛使用的...
Zookeeper,一个分布式协调服务,是Apache Hadoop的一个子项目,主要用于解决分布式环境中的数据一致性问题。它提供了一种基于发布/订阅模式的消息系统,可以实现命名服务、配置管理、集群管理、分布式锁等功能。在...
- Hadoop:Hadoop中的YARN和HBase都使用Zookeeper来协调集群中的各个组件。 - Kafka:Kafka利用Zookeeper进行集群管理和消息队列的分配。 - Dubbo:Dubbo使用Zookeeper实现服务注册与发现,提供服务治理功能。 ### ...
Zookeeper是Apache Hadoop项目下的一个子项目,它是一个高度可用的分布式协调服务。Zookeeper提供了诸如命名服务、配置管理、集群同步、分布式锁等基础服务,使得分布式应用能够更好地管理和通信。以下是对Zookeeper...
4. **领导者选举**:在分布式系统中,Zookeeper可以协助进行领导者选举,确保只有一个节点成为领导者,避免了并发控制的问题。 三、Zookeeper的架构 Zookeeper采用Paxos算法的简化版来保证数据一致性。通常,...
Zookeeper是Apache Hadoop项目下的一个分布式协调服务,它作为一个高可用、高性能的中间件,被广泛应用于分布式系统中,如分布式配置管理、命名服务、分布式锁、集群管理等场景。本笔记将围绕Zookeeper的核心概念、...
4. **分布式锁**: 在分布式环境中,Zookeeper可以实现不同节点间的锁机制,保证同一时刻只有一个节点执行特定操作。 5. **事件发布/订阅**: Zookeeper支持发布订阅模式,允许节点之间进行事件的传递和通知。 **三...
Zookeeper是Apache Hadoop项目下的一个子项目,它是一个分布式的,开放源码的分布式应用程序协调服务,是集群的管理者,监视着集群中各个节点的状态根据节点提交的反馈进行下一步合理操作。最终将简单易用的接口和...
- **领导者-跟随者(Leader-Follower)模型**:集群中有一个领导者负责处理所有的写操作,其他跟随者负责复制和同步。 - **原子广播协议**:ZooKeeper使用ZAB(ZooKeeper Atomic Broadcast)协议来确保集群间的...
Zookeeper,作为Apache Hadoop项目的一部分,是一个分布式协调服务,它为分布式应用程序提供了简单有效的命名服务、配置管理、集群管理、分布式锁和分组服务等功能。在Dubbo等微服务框架中,Zookeeper常被用作服务...
Zookeeper采用PAXOS算法来保证数据的一致性,通过主备模式运行,集群中的每个节点都被称为一个Server,分为三种角色:领导者(Leader)、跟随者(Follower)和观察者(Observer)。当客户端发起请求时,请求首先由...