【HADOOP】“填坑”指南
Hadoop作为大数据离线分析平台环境,目前已经在各行业广泛使用,由于应用场景、环境版本、数据量等不同因素,经常会出现一些集群问题,有些问题会导致数据查询错误,有些问题会导致整个集群无法正常运行,本系列文章将列举一些问题案例,通过描述问题处理过程。
场景
数据表翻倍,导致数据表产生后无法查询。
软件环境:Hadoop 2.6
-
错误1
select * from table1where dt=’2017-01-11′ limit 1;
Failed with exception java.io.IOException:java.lang.RuntimeException:serious problem
-
错误2
select count(*)from table1 where dt=’2017-01-11′ limit1
Diagnostic Messages for this Task:
Error: java.io.IOException: java.lang.reflect.InvocationTargetException
… …
Caused by: com.google.protobuf.InvalidProtocolBufferException: Protocol message was too large. May be malicious. Use CodedInputStream.setSizeLimit() to increase the size limit.
… …
FAILED: Execution Error, return code 2 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask
MapReduce Jobs Launched: Stage-Stage-1: Map: 120 HDFS Read: 0 HDFS Write: 0 FAIL
Total MapReduce CPU Time Spent: 0 msec
解决分析过程
-
错误1
google搜索关键字,问题相关文章https://community.hortonworks.com/questions/23242/caused-by-comgoogleprotobufinvalidprotocolbufferex.html
文章提供建议在hive命令行中执行set hive参数
set orc.compress.size=4096
set hive.exec.orc.default.stripe.size=268435456
问题未解决,但提供如下官方jira
https://issues.apache.org/jira/browse/HIVE-11592
通过问题描述发现原因是由于ORC 元数据片段超过 protobuf message 大小限制
ORC metadata section can sometimesexceed protobuf message size limit
解决办法:修改hive源码 ReaderImpl.java 重新编译,替换jar包(目前0.14和1.2.1版本均有问题)mvn clean package -Phadoop-2 -Pdist -DskipTests -Dtar
覆盖文件:hive-exec-0.14.0.jar
-
错误2
错误1解决后,错误2问题仍存在,分析问题原因:客户端heap大小不足(hdfs问题),解决办法
1.在hive客户端执行:export HADOOP_HEAPSIZE=”8192″
2.hdfs解决策略(需要重启hdfs解决问题)
官方详细描述:https://issues.apache.org/jira/browse/HADOOP-13039
场景:hadoop hdfs 中的nondfs增加到一定大小时会导致dfs可用空间减小,会导致部分data节点可用空间不足,从而产生不健康节点。重启datanode可释放nondfs空间,当hadoop集群节点数量超过100台时,循环重启datanode后造成hdfs响应速度变慢,无法正常使用。为了解决此问题,重启hdfs,重启后问题仍然存在。
分析过程
google搜索关键字 BlockReport slow namenode相关信息,了解到:
大批量重启Datanode时,由于未开启安全模式,仍有数据写入到hdfs,从而导致hdfs中数据块会产生少于标准3备份的1-2备份块,或者是多余3备份的4-10备份块,Datanode默认每6(dfs.datanode.directoryscan.interval)小时调用DirectoryScanner去做内存和磁盘数据集块校验,而这个过程fdataset这个数据结构一直持有独占锁,导致其他的线程都被BLOCK住,而数据量越大在默认情况1个(dfs.datanode.directoryscan.threads)线程的执行时间越久.虽然在HADOOP-4584后分离了diskscanner和heartbeat
sender但是还是存在共享竞争资源,所以当需要扫描的数据块数量特别多时,会影响hdfs的正常使用。
当重启hdfs时,由于每次启动集群后,Datanode都会向Namenode汇报数据块情况,由于hdfs默认扫描块的进程数为1,所以当集群的数据块未全部检查完前,集群无法正常对外提供服务。
解决办法
调整hdfs参数,调整以下两个参数后,可减缓数据块汇报时间,并加大块扫描进程数,修改参数后重启集群,hdfs可恢复正常使用,dfs.datanode.directoryscan.threads切忌修改过大,大量扫描进程会造成Namenode压力增大,导致Namenode进程死掉。
hdfs-site.xml
<property>
<name>dfs.datanode.directoryscan.threads</name>
<value>6</value>
</property>
<property>
<name>dfs.blockreport.initialDelay</name>
<value>600</value>
</property>
以上解决办法只能缓解hdfs数据块同步问题,仍未根本解决大规模Hadoop集群由于Namenode异常引起的hdfs响应缓慢问题,官方提供了代码级的解决方案如下:
https://issues.apache.org/jira/browse/HDFS-7980
官方提到的解决方案需要修改源码,并重新编译源码,替换原有jar包。
大规模Hadoop集群运维的过程中,经常会因为集群扩容,或者主Namenode故障引起各种集群问题,而当集群故障时,每次重启调试都会消耗大量时间,为了提高Hadoop启动速度,建议按以下步骤启动hdfs:
-
启动NameNode(active)
-
启动NameNode(standby)
-
启动zkfc
等待元数据加载完成后启动Datanode节点
总结
因为Hadoop集群的使用场景不同,集群规模不同,软件版本不同,在运维集群过程中会出现各种各样的问题,如何能够尽快解决问题恢复集群环境,是大部分集群运维人员比较关心的问题。从多次处理集群问题的经验来看,大部分问题都会从官网相关补丁或问题文档中得到解决方案,建议在遇到集群问题时能够仔细分析问题原因,通过相关日志定位问题关键字,进而能够通过关键字快速查找到问题解决方案。
转载自:https://blog.csdn.net/JDJRdata/article/details/72956124