关于java:分享一个Flink-checkpoint失败的问题和解决办法

本文来自: PerfMa技术社区

PerfMa(笨马网络)官网

接触Flink一段时间了,遇到了一些问题,其中有一个checkpoint失败导致作业重启的问题,遇到了很屡次,重启之后个别也能恢复正常,没有太在意,最近2天有共事又频繁遇到,这里记录一下解决方案和剖析过程。

咱们的flink测试环境有3个节点,部署架构是每个flink节点上部署一个HDFS的DataNode节点,hdfs用于flink的checkpoint和savepoint

景象

看日志是说有个3个datanode活着,文件正本是1,然而写文件失败

There are 3 datanode(s) running and no node(s) are excluded

网上搜了一下这种报错,没有间接的答案,我看了下namenode的日志,没有更多间接的信息

50070 web ui上看一切正常,datanode的残余空间都还有很多,使用率不到10%

我试了一下往hdfs上put一个文件再get下来,都ok,阐明hdfs服务没有问题,datanode也是通的

日志景象1

持续前后翻了一下namenode的日志,留神到有一些warning信息,

这时候狐疑块搁置策略有问题

依照日志提醒关上相应的的debug开关
批改

etc/hadoop/log4j.properties

找到

log4j.logger.org.apache.hadoop.fs.s3a.S3AFileSystem=WARN

照抄这个格局,在上面增加

log4j.logger.org.apache.hadoop.hdfs.server.blockmanagement.BlockPlacementPolicy=DEBUG
log4j.logger.org.apache.hadoop.hdfs.server.blockmanagement.DatanodeDescriptor=DEBUG
log4j.logger.org.apache.hadoop.net.NetworkTopology=DEBUG

重启namenode,而后重跑flink作业

日志景象2

这时候看到的问题是机架感知策略无奈满足,因为咱们没有提供机架映射脚本,默认同一个机架,然而认真想想跟这个应该也没有关系

因为很多生产环境的hdfs其实都不配置机架映射脚本,并且导致checkpoint失败的问题并不是始终存在,最起码put/get文件都是失常的。

这时候开始思考看一下hdfs的源码了,依据下面的日志调用栈,先看到BlockPlacementPolicyDefault以及相干的DatanodeDescriptor

这些源码大抵的意思是当给一个块抉择一个datanode的时候,要对这个datanode进行一些查看,比方看下残余空间,看下忙碌水平

当咱们的问题复现的时候,察看日志会发现一些与此相关的要害信息

这个日志的意思是,存储空间有43G,调配块理论须要100多M,然而scheduled大小就超过43G,因而咱们认为失常的datanode,namenode认为它空间有余了

起因

scheduled大小含意是什么呢? 依据代码能够看到scheduled大小是块大小跟一个计数器做乘法,计数器代表的其实是新建文件块数量计数器,hdfs依据这两个参数评估可能须要的存储空间,相当于给每个datanode预约了肯定的空间,预约的空间在文件写入后,计算完实在的占用空间后,还会调整回来。

理解这个原理之后,能够判断的是datanode在一段时间内被预约了太多的空间。

flink的checkpoint机制能够参考这一篇https://www.jianshu.com/p/9c5…
大抵的意思是taskmanager上的很多工作线程都会写hdfs

看了下hdfs的目录构造,有大量的相似uuid命名checkpoint文件,同时每个文件都很小

当咱们的作业并发较大时,相应的在hdfs上就会创立更多的checkpoint文件,只管咱们的文件大小只有几K,然而在每一个datanode预约的空间都是128M乘以调配到的文件数量(文件很小,不超过128M),那么43G的空间,最多预约多少文件呢?除一下也就是300多个,三个节点也就是最多900个,咱们有多个作业,总并发较大,在预留空间齐全开释前,是很容易呈现这个问题的。

之前晓得hdfs不适宜存储小文件,起因是大量小文件会导致inode耗费以及block location这些元数据增长,让namenode内存吃紧,这个例子还表明
当blocksize设置较大,文件大小却远小于blocksize时,大量这种小文件会导致datanode间接”不可用”。

解决办法

块大小不是集群属性,是文件属性,客户端能够设置的,flink这时候每个taskmanager和jobmanager都是hdfs的”客户端”,依据flink文档,咱们能够做如下配置
1、在conf/flink-conf.yaml中指定一个hdfs的配置文件门路

fs.hdfs.hadoopconf: /home/xxxx/flink/conf

这里跟flink的配置文件门路抉择同一个目录

2、放进去2个配置文件,一个core-site.xml一个是hdfs-site.xml

core-site.xml能够不放,如果checkpoint和savepoint指定了具体的hdfs地址的话,

hdfs-site.xml里加上blockSize配置即可,比方这里咱们给它设置为1M

具体块大小如何设置,须要察看本人的作业状态文件大小本人灵便调整。

重启flink集群,提交作业即可,运行时能够察看下hdfs的fsimage大小,留神不要因为块太小,小文件太多导致元数据过大。

小结

咱们曾经将该问题同步到集群自动化部署脚本中,部署时会专门增加blocksize的配置。

flink这套依赖hdfs的checkpoint计划对于轻量级的流计算场景稍显臃肿,checkpoint的分布式存储不论是间接filesystem还是rocksDB都须要hdfs,其实从checkpoint原理和数据类型思考,es应该也是不错的抉择,遗憾的是社区并没有提供这种计划。

一起来学习吧

PerfMa KO 系列课之 JVM 参数【Memory篇】

一次StackOverflowError排查,起因居然和Dubbo无关!

【腾讯云】轻量 2核2G4M,首年65元

阿里云限时活动-云数据库 RDS MySQL  1核2G配置 1.88/月 速抢

本文由乐趣区整理发布,转载请注明出处,谢谢。

您可能还喜欢...

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据