ambari hdfs 启动报错_HDFS 运维常见问题处理
腾讯游戏CROS体系的DBA维护着多套互娱数据平台的核心HDFS集群,积累了不少维护经验。
1. 定期block全盘扫描,引起dn心跳超时而脱离集群
hdfs有一个目录扫描机制,默认6小时会全盘扫描一次所有block,判断与内存里的那份blockMap是否一致。参考
https://blog.cloudera.com/hdfs-datanode-scanners-and-disk-checker-explained/ 。
在小文件比较多的情况,扫描的时候特征很明显——磁盘的iops很高,但吞吐量很低。当然这不是引起datanode心跳超时的原因,真正的原因是处理扫描后的结果,比如比较完发现有20000个block不一致,在修复这些block时不断的持有了 FsDatasetImpl 这个对象的一把锁,在磁盘比较慢的情况下,可能需要5分钟甚至10分钟处理完,从而一直阻塞读、写、心跳的线程。
详细的可以了解 HDFS-14476 lock too long when fix inconsistent blocks between disk and in-memory,包括一些特征、证据,以及block修复逻辑,细节比较多。
解决办法是,我们这边加了个patch(已合入官方版本 2.10和3.x),在处理异常block的时候,中间休息2秒,处理一下正常的请求,不至于datanode卡住甚至离线。
修复后的结果也是很明显,datanode心跳平滑了许多:
2. namenode迁移裁撤,遇到客户端无法写入
在需要迁移/裁撤namenode时,一般思路是保持 namenode hostname 不变,滚动迁移 standby 的方式迁移。
但是在我们的迁移实践中,发现 hdfs namenode 完成迁移后,集群正常,但 hdfs 客户端访问异常。在 yarn 这样的长任务场景下,会导致文件读写一直失败,直到 yarn nodemanager 重启。
具体问题是这样的:
client使用的是 ConfiguredFailoverProxyProvider ,client启动之后会根据当时的inetsocket创建nn1,nn2两个namenode proxy,这个在任何网络异常的情况下都不会重新创建。
client 的 updateAddress 方法能检测到namenode ip发生了变化,但由于那个异常没有捕获,本该在下次循环使用正确的 namenode ip 就能正常,但抛出异常后导致client重新连接namenode,然而上面的 namenode proxy 还是旧地址,SetupConnection 异常,又进入updateAddress判断逻辑,返回true又去建连接,陷入了死结。
复现步骤
打开一个hdfsclient,长时间写一个文件 hdfs put
更新hdfs新namenode hostname-ip
stop old nn2, start new nn2
更新客户端的namenode hostname-ip (client还在操作文件)
切换到新namenode hdfs haadmin -failover nn1 nn2
此时会发现client一直报错
在yarn客户端启动的周期内,哪怕是新文件写入,依旧会报错
对 ConfiguredFailoverProxyProvider 打了个patch,就是在client failover之后,也进行updateAddress判断,如果有ip变动,就重新 createProxy。验证这个patch同样有效。不过在client那边统一捕获会比较好,因为还有其他类型的HaProvider可能也有这个问题。
这个问题的 patch 已经被合入 Apache Hadoop 3.4,见 HADOOP-17068 client fails forever when namenode ipaddr changed。我们用的版本是 2.6.0-cdh5.4.11 ,patch也已合入官方版本。
除了从根源问题上解决,也可以在 namenode 迁移操作时,在老节点上启用端口转发,再逐个重启 yarn,避免引起大范围故障。
3. 集群dn不均衡导致文件写入失败
现象:集群将满时,扩容了批机器缓解空间。运行了2个星期客户端突然报文件写入失败
原因:hdfs在部分datanode空间满的情况下,理论会自动挑选其它可用的空闲节点。由于 dfs.datanode.du.reserved
配置不当,导致依然会选中满节点。具体是dfs.datanode.du.reserved
如果小于分区block reserved,在磁盘用满时就会出现
org.apache.hadoop.ipc.RemoteException(java.io.IOException): File /kafka/xxxtmp.parquet could only be replicated to 0 nodes instead of minReplication (=1). \There are 14 datanode(s) running and no node(s) are excluded in this operation.
解决:
扩容完,跑rebalance
修改磁盘分区的block reserved,使其小于
dfs.datanode.du.reserved
.增加单个datanode容量告警
4. 做 rebalance 时速度很慢
启动 rebalance 命令./start-balancer.sh -threshold 10
,如果需要提高速度可以修改限流带宽hdfs dfsadmin -setBalancerBandwidth 52428800 。
但是 datanode 上同时接收 blocks 并发数,是不能在线调整的(或者说只能调小),调整hdfs-site.xml
默认的balance参数,并重启
dfs.balancer.moverThreads=1000dfs.balancer.dispatcherThreads=200dfs.datanode.balance.max.concurrent.moves=50
如果启动balance时,尝试以更高的并发执行,datanode会判断没有足够的线程接收 block: IOException: Got error, status message Not able to copy block ... because threads quota is exceeded。
当 move 出现失败时,迁移速度是指数级下降的,因为move block失败默认会sleep一段时间。
./start-balancer.sh -threshold 5\ -Ddfs.datanode.balance.max.concurrent.moves=20 \ -Ddfs.datanode.balance.bandwidthPerSec=150000000 \ -Ddfs.balancer.moverThreads=500 \ -Ddfs.balancer.dispatcherThreads=100
5. 给datanode在线增加磁盘
腾讯云上的机器,可以直接在原有 datanode 上直接挂在新的磁盘,快速给hdfs扩容。
增加磁盘,不需要重启datanode。(前提是设置了 dfs.datanode.fsdataset.volume.choosing.policy
为AvailableSpaceVolumeChoosingPolicy
)
挂载后,先建立hadoop数据目录并修正权限
在
hdfs-site.xml
里加上新目录配置dfs.datanode.data.dir
可以使用 reconfig 命令使其生效:
hdfs dfsadmin -reconfig datanode dn-x-x-x-x:50020 start
6. namenode设置了HA,但故障时未成功切换
现象:active namenode 内存故障,主备切换失败
原因:dfs.ha.fencing.methods
设置为了ssh,但是并不能登录其他namenode执行fence
解决:生成ssh key,免密码登录。或者改成shell(/bin/true)
,强切。注意,修改fence方式后,需要重启zkfc。
7. hdfs client input/output error
现象:执行 hdfs
客户端命令报错 input/output error
,试着拷贝 hadoop / jdk 的介质目录,亦发现文件损坏。有时会发现 jvm core
原因:磁盘存在坏块,刚好hdfs或者jdk的 jar 库损坏。通过观察 messages 发现有 sda IO Input/Output Error 。
使用badblocks -s -v -o bb.log /dev/sda
可以看到磁盘损坏了哪些扇区
解决:从其他机器,拷贝一份正常的介质
8. hdfs误将 data 盘作为数据盘
误将系统盘作为了dfs.datanode.data.dir
,运行一段时间后,这个分区很容易最先满。
这个是配置上的问题,理解datanode的工作方式,可以快速的将这个分区里的block挪到正确的磁盘分区。
处理方法就是停止datanode,拷贝/data
block到其它分区,删掉/data
的配置。因为datanode上block的位置是每次启动的时候,扫描上报给namenode,所以可以做物理拷贝。
可以使用拷贝命令cp -a /data/hadoopdata/current/BP-*-*/current/finalized/* /data1/hadoopdata/current/BP-*-*/current/finalized/
,不能拷贝整个 hadoopdata 目录,因为VERSION文件里面的storageID不同。
9. 使用decomiss方式将datanode退服时,客户端读写异常
现象:将datanode加入 exclude ,正常 decomissing 的方式退役节点,应用层反馈 spark 任务部分异常,报错 Unable to close file because the last block doest not have enough number of replicas ,但该集群一些其它的文件读写任务正常。
原因:spark任务会频繁的创建、删除application目录。在decomissing时,部分磁盘性能低的节点,磁盘更加繁忙,导致出现 last contact 心跳时间长。
解决:经过验证,发现直接 kill datanode进程的方式,不影响spark任务。但必须保证一个一个的kill,否则会出现 missing block. (这不一定是解决问题最好的办法,但的确有效)
10. namenode editlog 长时间未做checkpoint
standby namenode 的一个作用是,定期合并从journalnode上获取的editlog,生成新的元数据fsimage,然后推送到active namenode。
当standby namenode出现异常,如进程退出、软件bug(比如我们遇到过 IOException: No image directories available!),导致长时间未合并editlog。一旦需要发生切换或者重启namenode,有可能导致启动时间过长,严重的editlog合并需要的内存不足,无法启动namenode.
如果内存不足,一种解决办法是借一台高内存临时机器合并editlog:
把standby停下来,将hdfs的软件介质和配置文件,拷贝到高内存机器
同时拷贝
dfs.namenode.name.dir
目录中最新能用的 fsimage_xxx 和它之后的所有 edits_xxx-xxx在临时机器上启动 namenode 进程,会自动从对应目录加载 fsiamge 、合并editlog
预防比补救要重要,一定要监控namenode上 TransactionsSinceLastCheckpoint
这个指标,我们的阈值是达到 5000000 就告警。
11. HDFS 3.x datanode 出现大量 CLOSE-WAIT
这个问题 HDFS-15402 是在定期对 datanode http://127.0.0.1:50075/jmx
jmx 进行探测的时候产生的,我们有 5 个 hadoop 3.1.3 的集群都存在该问题。在 hadoop 2.x 中正常。
50075 端口上产生过多 close-wait 的影响是,正常的 webhdfs 会出现 504 Gateway-timeout
[root@dn-9-4-xxx-yy /tmp]# ss -ant|grep :50075 |grep CLOSE-WAIT|wc -l16464[root@dn-9-4-xxx-yy /tmp]# ss -ant|grep :50075 |grep CLOSE-WAIT|head -3CLOSE-WAIT 123 0 9.4.xxx.yy:50075 9.4.xxx.yy:39706CLOSE-WAIT 123 0 9.4.xxx.yy:50075 9.4.xxx.yy:51710CLOSE-WAIT 123 0 9.4.xxx.yy:50075 9.4.xxx.yy:47475
lsof -i:39706COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAMEjava 134304 hdfs *307u IPv4 429yy7315 0t0 TCP dn-9-4-xxx-yy:50075->dn-9-4-xxx-yy:39706 (CLOSE_WAIT)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program nametcp 123 0 9.4.xxx.yy:50075 9.4.xxx.yy:39706 CLOSE_WAIT 134304/java
CLOSE-WAIT 状态是客户端(curl)发起关闭tcp连接时,服务端(datanode)收到了FIN-ACK,但在关闭socket时一直没有完成。正常流程是关闭socket完成,然后向客户端发送FIN:
所以问题出在datanode server上,与knox还是haproxy客户端没有关系。并且这个问题调整os内核参数是没有用的,除非kill datanode,否则close-wait状态会永久存在。使用网上的kill_close_wait_connections.pl
能够清理这些 close-wait,之后 webhdfs 请求变得好转。
目前避开的方法就是,不再请求 datanode jmx 做监控,只获取 namenode 上的指标。datanode 上采集 os 级别的指标。
12. knox 无法上传 8G 文件
在官方 jira 里我们提了这个问题 KNOX-2139 Can not handle 8GB file when using webhdfs ,当我们使用 webhdfs with knox 上传 8589934592 bytes 大小的文件,会出现 (55) Send failure: Broken pipe,在 hdfs 只能看到一个空文件。而且在版本 knox 1.1、1.2 中是必现,在 0.8 版本正常。
简单 debug 了一下代码,knox 拿到的请求 contentLength 为 0,8G 以外的情况 contentLength 为 -1。
我们后来使用 haproxy 代替 knox 解决 knox 自身上传速度慢和这个 8G 文件的问题。
不过在最新的 1.4 版本,8G问题又消失了。根据官方的恢复,可能跟 jetty 的升级有关。
13. Unable to load native-hadoop library for your platform
Unable to load native-hadoop library for your platform... using builtin-java classes
经常在执行 hdfs
客户端命令时会有这样的提示,其实是个老生常谈的问题。
简单说就是系统里没有找到原生的 hadoop 库 libhdfs.so
,这个库是 C 写的,性能比较好。缺少但不影响使用,因为 hadoop 里有 java 实现的客户端库。
出现这个总结原因有 3 个:
hadoop 安装包里没有自带
libhdfs.so
这个情况占很大一部分。去到目录${HADOOP_HOME}/lib/native/
,看下是否有libhdfs.so,libhdfs.a,libhadoop.so,libhadoop.a。如果没有的话,可以重新下一个完整的二进制包,把lib/native
拷出来用
这种看到才是正常的
./bin/hadoop checknative20/05/14 20:13:39 INFO bzip2.Bzip2Factory: Successfully loaded & initialized native-bzip2 library system-native20/05/14 20:13:39 INFO zlib.ZlibFactory: Successfully loaded & initialized native-zlib libraryNative library checking:hadoop: true /data1/hadoop-hdfs/hadoop-dist/target/hadoop-2.6.0-cdh5.4.11-tendata/lib/native/libhadoop.so.1.0.0zlib: true /lib64/libz.so.1snappy: true /data1/hadoop-hdfs/hadoop-dist/target/hadoop-2.6.0-cdh5.4.11-tendata/lib/native/libsnappy.so.1lz4: true revision:10301bzip2: true /lib64/libbz2.so.1openssl: true /usr/lib64/libcrypto.so
实在不行就在自己的 os 上编译一个。
mvn clean package -Pdist,native -DskipTests -Dtar -Dbundle.snappy -Dsnappy.lib=/usr/local/lib
so 文件存在,但路径不对
现在的版本,默认路径都能找得到 so 库。这个 https://stackoverflow.com/questions/19943766/hadoop-unable-to-load-native-hadoop-library-for-your-platform-warning 里面介绍的大部分方法,都是在教怎么设置路径。真实原因很少会因为路径不对,不过这个答案靠谱 https://stackoverflow.com/a/30927689 ,也就是我们的情况 3编译的版本,在我们的 os 上依赖库不全
遇到过这种,glibc 库版本不够:
$ ldd lib/native/libhadoop.solib/native/libhadoop.so: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by lib/native/libhadoop.so) linux-vdso.so.1 => (0x00007ffd1db6d000) /$LIB/libonion.so => /lib64/libonion.so (0x00007f5bfd37d000) libdl.so.2 => /lib64/libdl.so.2 (0x00007f5bfce40000) libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f5bfcc23000) libc.so.6 => /lib64/libc.so.6 (0x00007f5bfc88f000) /lib64/ld-linux-x86-64.so.2 (0x00007f5bfd266000)
$ strings /lib64/libc.so.6 |grep GLIBC_可以看当前系统支持哪些版本的 glibc
但是 glibc 安装升级有风险,如果要安装 2.14 版本务必先做好测试。
14. 处理 missing blocks
hdfs 集群出现 missing block,无非就是 namenode 里还记录的 block 元数据信息,但是所有副本都丢失了。如果是同时挂了多个机器,或者损坏了多个机器上的磁盘,是有可能会出现。
遇到过 2 次人为产生 missing blocks:
kill 一个 datanode 进程,就出现 missing block
先设置所有文件的 replication 为 1,一小段时间后,再设置为 2
这两种情况都算是 bug,对应的文件确实无法 get 下来了。但第 1 中情况还好,经过排除日志,发现实际这些丢失的 blocks 本就接收到了删除命令,过一段时间后,missing block 一般会自动消失。第 2 种情况,是真的意外丢 block 了,比较严重。不要轻易把 replication 设置为 1,再改回去可能丢 block。
如果确认这些 missing block 可以消除,可以通过 fsck 命令手动处理:
// 如果missing blocks数不是很多,可以直接逐个deletehdfs fsck file_name -delete
// 如果missing blocks较多,可以从namenode上拿到corrupt块hdfs fsck / -list-corruptfileblocks -openforwrite | egrep -v '^\.+$' | egrep "MISSING|OPENFORWRITE" | grep -o "/[^ ]*" | sed -e "s/:$//" > missing_blocks.txt
15. 应该关注的告警
实际还有些许多问题,比如用户supergroup 权限问题、rack-aware.sh
文件缺失的问题,限于篇幅就不列举了。
问题是不断会出现的,但及时对大部分场景做到监控工具,能够提前发现问题。下面是整理并上线的关键告警指标:
datanode lastcontactdatanode 与 namenode 心跳监控。心跳时间长意味着这个 dn 没响应了,默认超过10m30s 没响应,dn会脱离集群。
namenode and datanode web probe
namenode 50070 与 datanode 50075 从外部探测,并且 datanode 会根据 include里面的地址自动增减。我们使用修改过了 telegraf http_response 插件,支持动态读取url,比如exec bash get_datanode_urls.sh
dirctory max files
单目录下的文件数告警。hdfs默认限制单目录下最大的文件数100万,由配置项dfs.namenode.fs-limits.max-directory-items
决定。
这个指标数据来源于 fsimage 目录画像分析。transactions not merged
standby 未滚动的editlog数。长期未checkpoint会导致下次namenode启动消耗过多内存,甚至启动失败。missing blocks
异常blocks数test write file
在2个namenode节点上,定期使用 hdfs put/get 写入文件。如果失败会告警non-active namenode
hdfs集群namenode有且只有一个active,一个standby。其它情况告警cluster capacity
集群总体容量监控node usage, ioutil
单个 datanode 磁盘空间使用率预警,ioutil持续5分钟大于95%预警。failover occurs
hdfs namenode发生failovernamenode heap size
namenode heap size使用比率。blocks数量多,内存使用越多。
ambari hdfs 启动报错_HDFS 运维常见问题处理相关推荐
- ambari hdfs 启动报错_Ambari 1.6 自动安装hadoop 2.2.0 在Ambari启动namenode时报错
展开全部 lib/ambari-agent/data/, ',587 - Modifying group nobody 2015-03-11 09;cache/:34:49;python2: Fals ...
- HDFS启动报错Expected to be able to read up until at least txid but unable to find any edit logs
现象 Hadoop集群出现了异常断电后,HDFS启动报错,报错信息截图如下, 解决 Hadoop NN中的元数据包括: fsimage:包含某个时间点的文件系统的完整状态 edit logs:包含在最 ...
- python2 python3共存导致conda报错_Windows运维之Windows10下配置Python2和Python3共存 并用anaconda实现方便的包管理...
本文主要向大家介绍了Windows运维之Windows10下配置Python2和Python3共存 并用anaconda实现方便的包管理,通过具体的内容向大家展现,希望对大家学习Windows运维有所 ...
- mysql建库语句on报错_mysql运维必备知识点(转载至其他作者)
(1)基础笔试命令考察 1.开启MySQL服务 /etc/init.d/mysqld start service mysqld start systemctl start mysqld 2.检测端口是 ...
- oracle中00604,【案例】Oracle无法启动报错ORA-00604 ORA-01578官方解决办法
天萃荷净 Oracle研究中心案例分析:运维DBA反映Oracle数据库无法启动并报错ORA-00604 ORA-01578,分析原因为遇核心对象bootstrap$有坏块的解决办法.change b ...
- linux ora 01157,案例:Oracle报错ORA-01157 ORA-01110 数据启动报错RMAN恢复数据库思路
天萃荷净 rman从多份备份中还原操作,运维DBA工程师反映数据库在进行恢复时报错ORA-01157 ORA-01110,分析原因为11号数据文件需要recover 1.数据恢复ORA错误 RMAN& ...
- Hadoop 在关机重启后,namenode启动报错
Hadoop 在关机重启后,namenode启动报错: 2011-10-21 05:22:20,504 INFO org.apache.hadoop.hdfs.server.common.Storag ...
- 【总结】ElasticSearch 安装启动报错max file descriptors [32768] for elasticsearch process is too low, increase
ElasticSearch 安装启动报错max file descriptors [32768] for elasticsearch process is too low, increase to a ...
- 应用时间线服务器启动报错_从服务器到无服务器的时间轴和教程
应用时间线服务器启动报错 Amazon Web Services is a behemoth powering companies from Fortune 500 corporations to h ...
最新文章
- python语言deLong‘s test:通过统计学的角度来比较两个ROC曲线、检验两个ROC曲线的差异是否具有统计显著性
- 漫画 | TCP,一个悲伤的故事
- AWR baseline template的管理
- 深度学习新星:GAN的基本原理、应用和走向 | 硬创公开课
- C和指针 (pointers on C)——第七章:函数(上)
- 深度学习和目标检测系列教程 11-300:小麦数据集训练Faster-RCNN模型
- 给初级拍摄者的十条好建议
- 缓慢的http拒绝服务攻击 tomcat_常见的网络攻击类型
- java jpa 模糊查询_JPA 以SQL实现分页不模糊查询(参数可能为空)
- 批量修改linux换行格式,linux中sed命令批量修改
- php接口三结构,grape动态PHP结构(三)——API接口
- 键盘拆开重新安装步骤_电脑键盘如何维修 电脑键盘常见问题维修技巧【详解】...
- The tough time set
- macbook 终端命令怎么使用_Mac终端怎么打开?带你全面了解在macOS中使用终端命令行...
- snownlp 原理_情感分析snownlp包部分核心代码理解
- 学计算机的装系统都不会,为什么刚买的新电脑,却不支持安装Win7系统,背后的真实原因...
- 【C++决赛】2019年全国高校计算机能力挑战赛决赛C++组题解
- 怎么去除视频字幕清理视频字幕或水印的几种方法
- 小程序中将lees转成wxss
- 在chrome中屏蔽百度推荐
热门文章
- 业界首创,腾讯网络平台部实现大规模光网络实时管控系统TOOP
- 拼车日滴滴派单的那些事
- leetcode 16. 3Sum Closest | 16. 最接近的三数之和(双指针)
- leetcode 476. 数字的补数(Java版)| How to extract ‘k’ bits from a given position in a number
- 高等数学:e的-t平方次方求积分
- Volatile可见性、缓存一致性协议、指令重排、内存屏障 - 手写笔记
- 数据库规范设计说明书(参考阿里开发规范)
- Web Storage API的介绍和使用
- JDK9的新特性:JVM的xlog
- android 禁用dlsym_Android7.0对dlopen的改变——读取私有.so结果变化