【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:

  1. 启动NameNode(active)

  2. 启动NameNode(standby)

  3. 启动zkfc

等待元数据加载完成后启动Datanode节点

总结

因为Hadoop集群的使用场景不同,集群规模不同,软件版本不同,在运维集群过程中会出现各种各样的问题,如何能够尽快解决问题恢复集群环境,是大部分集群运维人员比较关心的问题。从多次处理集群问题的经验来看,大部分问题都会从官网相关补丁或问题文档中得到解决方案,建议在遇到集群问题时能够仔细分析问题原因,通过相关日志定位问题关键字,进而能够通过关键字快速查找到问题解决方案。

猜你喜欢

转载自blog.csdn.net/mnasd/article/details/81184803