HDFS的standby节点启动过慢原因分析以及应对策略

HDFS的standby节点启动过慢原因分析以及应对策略

  • 1. NN启动大致流程
  • 2. Editlog日志清理策略
    • 2.1 为什么需要合并editlog?
    • 2.2 什么时候删除editlog?
  • 3. NN启动的日志加载策略
  • 4. Standby启动慢应对策略
  • 5. 疑问和思考
    • 5.1 如何人工阅读editlog和fsimage文件的内容?
    • 5.2 checkpoint的触发策略是什么?
    • 5.3 如果删除editlog失效导致保存过多的editlog,如果nn重启,启动过程是否会很长?
    • 5.4 如果standby长期宕机,active重启后有没有快速恢复的办法?
    • 5.5 如何人工触发checkpoint?
  • 6. 参考文档

在hdfs的nn重启过程时,以standby的方式进行启动,其中当前节点的fsimage和active节点的editlog数量对启动时间起到关键性的影响。本问题探讨hdfs的active节点正常,当standby节点重启时重启过慢的原因分析以及应对的策略。


为了分析出standby节点启动慢的原因,有必要分析和了解nn启动过程中在做什么事情,才能进一步分析慢在哪里,以及怎么优化。

1. NN启动大致流程

这里不探讨nn启动过程中复杂的代码逻辑实现,梳理整体上nn启动时,nn在能处理client的请求之前必须完成以下几步:

  1. 从fsimage文件中读取系统metadata
  2. 读取edit logs并把记录在其中的操作合并到系统metadata中去
  3. 生成一个新的checkpoint(新的fsimage必须和旧fsimage加上edit log上操作保持一致)
  4. 保持safe mode直到Datanodes上报足够数量的block信息
  5. 节点状态升级为standby,集群状态恢复,可以给客户端提供服务

图形如下

启动服务
加载fsimage
拉取editlog进行数据合并
进行checkpoint
通知active拉取fsimage
safe mode 上报block
启动完成

说明

  • 启动时会调用jn的rpc接口拉取editlog进行合并,值得注意的是,editlog信息并不会写入到本地的editlog文件中而是加载到当前节点的内存中进行数据合并,因此standby节点的editlog会被active节点少
  • standby完成checkpoint后生成fsimage文件后通知acrive节点,active节点通过jn的GET接口拉取fsimage,完成checkpoint同步
  • editlog合并、checkpoint生成fsimage依赖机器的内存、磁盘io性能,并且如果需要合并的editlog文件很多,就会导致启动过程很慢

根据生产经验,在大多数情况下,造成nn启动慢的原因,是在拉取editlog进行数据合并环节耗时过多,针对该问题进行重点分析。

2. Editlog日志清理策略

在HA架构下,fsimage + checkpoint后的editlog组成了完整的数据,但是不代表hdfs的nn节点只保存checkpoint后的editlog。事实上,nn拥有自己的保存策略。在讨论这个问题前,我觉得有必要回顾一下为什么需要合并editlog以及合并editlog的策略是什么。

2.1 为什么需要合并editlog?

在client写数据是,在一致性流程中我们在HDFS高可用架构涉及常用功能整理进行了梳理,editlog会通过append的方式记录数据写入的相关操作,在获得极致的写入性能同时,却牺牲了数据的组织性,因此难以通过查询editlog的方式组织数据结构。这就会导致一个问题,editlog持续写入,如果不进行数据合并,就会导致editlog越来越多,最后难以管理,特别是重启后,需要重新回放所有的editlog,这是难以接受的。所以通过合并editlog的方式(过程叫checkpoint),生产fsimage。为了减少active的压力,合并editlog的工作是交给standby负责的。

大体上的checkpoint流程如下
在这里插入图片描述

2.2 什么时候删除editlog?

之前我一直以为,nn是在standby完成checkpoint,active将fsimage同步完成后会自行删除editlog,减少active的过期的editlog。直到我重新做了认真整理了checkpoint环节并阅读了部分代码后,发现checkpoint和删除editlog策略是两件不相干的事儿

editlog日志的删除,内部维护了特定的日志删除策略。主要的代码如下

/**void purgeOldStorage(NameNodeFile nnf) throws IOException {FSImageTransactionalStorageInspector inspector =new FSImageTransactionalStorageInspector(EnumSet.of(nnf));storage.inspectStorageDirs(inspector);long minImageTxId = getImageTxIdToRetain(inspector);purgeCheckpointsOlderThan(inspector, minImageTxId);if (nnf == NameNodeFile.IMAGE_ROLLBACK) {// do not purge edits for IMAGE_ROLLBACK.return;}// If fsimage_N is the image we want to keep, then we need to keep// all txns > N. We can remove anything < N+1, since fsimage_N// reflects the state up to and including N. However, we also// provide a "cushion" of older txns that we keep, which is// handy for HA, where a remote node may not have as many// new images.//// First, determine the target number of extra transactions to retain based// on the configured amount.long minimumRequiredTxId = minImageTxId + 1;//最小的日志事务id为: 最小需要保留的事务txid减去需要额外保留的事务id,其中minimumRequiredTxId为检查点镜像文件的最后一条事务id,本质上就是保留numExtraEditsToRetain条事务。long purgeLogsFrom = Math.max(0, minimumRequiredTxId - numExtraEditsToRetain);//edit log的文件输入流ArrayList<EditLogInputStream> editLogs = new ArrayList<EditLogInputStream>();//填充purgeableLogs.selectInputStreams(editLogs, purgeLogsFrom, false, false);//排序,优先比较第一条事务txid,然后比较最后一条事务txidCollections.sort(editLogs, new Comparator<EditLogInputStream>() {@Overridepublic int compare(EditLogInputStream a, EditLogInputStream b) {return ComparisonChain.start().compare(a.getFirstTxId(), b.getFirstTxId()).compare(a.getLastTxId(), b.getLastTxId()).result();}});// Remove from consideration any edit logs that are in fact required.//如果edit log文件的第一个事务txid比最小需要保留的事务txid大,那么该edit log需要保留,从待editLogs list中移除。while (editLogs.size() > 0 &&editLogs.get(editLogs.size() - 1).getFirstTxId() >= minimumRequiredTxId) {editLogs.remove(editLogs.size() - 1);}// Next, adjust the number of transactions to retain if doing so would mean// keeping too many segments around.//如果editLogs list的条数比需要保留的最大edits文件数多,那么能保留的最小事务id  purgeLogsFrom 需要扩大,将purgeLogsFrom 置为该日志的文件事务txid//如果了解前因后果的话,需要清除的日志由两个参数控制,需要保留的事务数量及需要保留的日志文件数,两个是且的关系,只有两个条件都满足的日志才会保留,有一个不满足就会删除,这里其实就是当日志文件数大于需要保留的日志文件数时,多余的日志文件数需要清除。while (editLogs.size() > maxExtraEditsSegmentsToRetain) {purgeLogsFrom = editLogs.get(0).getLastTxId() + 1;editLogs.remove(0);}// Finally, ensure that we're not trying to purge any transactions that we// actually need.//最后确认下,本次清除的事务id必须比最低要求低,不然抛出异常。if (purgeLogsFrom > minimumRequiredTxId) {throw new AssertionError("Should not purge more edits than required to "+ "restore: " + purgeLogsFrom + " should be <= "+ minimumRequiredTxId);}//调用方法清除,这个前文已经将了purgeableLogs.purgeLogsOlderThan(purgeLogsFrom);}

更多细节不在展开,总结下来,nn删除editlog主要由2个策略决定

  • 保留 numExtraEditsToRetain 条事务
  • 保留 maxExtraEditsSegmentsToRetain 个edit log日志文件

两个策略独立运行,只要有一个条件不满足,日志就会被删除

查看源码得知,

  • numExtraEditsToRetain对应的参数为 dfs.namenode.num.extra.edits.retained(默认值1000000)
  • maxExtraEditsSegmentsToRetain对应的参数为 dfs.namenode.max.extra.edits.segments.retained(默认值10000)

所以整体总结过来的策略是,editlog的删除策略是

  • 最多保留dfs.namenode.max.extra.edits.segments.retained(默认值10000)+ n (n跟fsimage的文件个数有关)个editlog,如果nn的事务增长较快,由于只保留dfs.namenode.num.extra.edits.retained(默认值1000000)条事务,因此editlog数量可能会少于dfs.namenode.max.extra.edits.segments.retained(默认值10000)个。

另外,可以从fsimage的名称可以获取最小的事务id,比如fsimage_000000000096796869,对应的最小事务id是000000000096796869,往前保留1000000个事务,即从95796870开始,事务ID比这个小的editlog文件都会被删除(包含95796870的editlog会被保留,即便该editlog文件的事务ID可能会比95796870小,这也是为什么可能保留的editlog可能超过fs.namenode.max.extra.edits.segments.retained(默认值10000)的原因)
在这里插入图片描述
在查看hadoop的官方hdfs-default.xml文档获得相关配置的解释。

名称默认值description翻译
dfs.namenode.num.extra.edits.retained1000000The number of extra transactions which should be retained beyond what is minimally necessary for a NN restart. It does not translate directly to file’s age, or the number of files kept, but to the number of transactions (here “edits” means transactions). One edit file may contain several transactions (edits). During checkpoint, NameNode will identify the total number of edits to retain as extra by checking the latest checkpoint transaction value, subtracted by the value of this property. Then, it scans edits files to identify the older ones that don’t include the computed range of retained transactions that are to be kept around, and purges them subsequently. The retainment can be useful for audit purposes or for an HA setup where a remote Standby Node may have been offline for some time and need to have a longer backlog of retained edits in order to start again. Typically each edit is on the order of a few hundred bytes, so the default of 1 million edits should be on the order of hundreds of MBs or low GBs. NOTE: Fewer extra edits may be retained than value specified for this setting if doing so would mean that more segments would be retained than the number configured by dfs.namenode.max.extra.edits.segments.retained.应该保留的额外事务的数量超出了 NN 重新启动所需的最低限度。它不会直接转换为文件的年龄或保存的文件数量,而是转换为事务的数量(这里“编辑”是指事务)。一个编辑文件可能包含多个事务(编辑)。在检查点期间,NameNode 将通过检查最新的检查点事务值减去此属性的值来确定要保留的编辑总数。然后,它扫描编辑文件以识别不包括计算范围的保留交易的旧文件,并随后清除它们。保留对于审计目的或 HA 设置很有用,其中远程备用节点可能已离线一段时间并且需要保留更长的保留编辑积压才能重新开始。通常,每次编辑大约为几百字节,因此默认的 100 万次编辑应该是数百 MB 或低 GB 的数量级。注意:如果这样做意味着保留的段数多于 dfs.namenode.max.extra.edits.segments.retained 配置的数量,则保留的额外编辑可能少于为此设置指定的值。
dfs.namenode.num.checkpoints.retained2最多保存2个fsimage文件

3. NN启动的日志加载策略

nn启动时会加载本地的fsimage,然后通过jn下载editlog进行数据回放,但是如果nn的editlog清理策略不生效,保留了很长时间以前的editlog,standby重启后,到底是把active节点的所有editlog都下载下来回放还是会根据本地的fsimage下载相应的editlog(fsimage最小事务之后的editlog)进行回放?也就是说,active如果保留了过多的editlog,是否会对standby的启动流程是否有影响?

为了解答这个疑问,我自己搭建了一个hdfs集群,并进行模拟和验证,观察相关的日志情况如下

nn2节点(standby)重启,相关日志如下,nn2加载了fsimage_0000000000000002066,并记录当前的txid=0000000000000002066,并开始从txid=2067进行下载,因此直接忽略txid=2066的editlog文件。
在这里插入图片描述
可以得出结论

  • standby重启后,会根据fsimage计算最小的txid,并从最小txid开始下载editlog,因此active节点如果保存了过多的editlog并不会干扰standby的启动过程。
  • 如果standby本地的fsimage版本过老,就会需要从nn1下载大量的editlog进行数据合并,需要消耗很长时间
  • 正常情况下,active最多保存dfs.namenode.max.extra.edits.segments.retained(默认值10000)+ n (n跟fsimage的文件个数有关)个editlog,如果standby宕机时间过久,本地的fsimage + active保留的editlog,有可能无法完成数据回放,会出现数据丢失。

4. Standby启动慢应对策略

如果standby启动过慢,原因是由于fsimage版本过老,应对的策略应该是从active节点同步最新的fsimage,从而减少下载editlog日志。

如下2种方式均可

  1. 将active节点的fsimage拷贝给standby节点,在启动standby节点
  2. 执行命令同步元数据后,在启动standby节点
hdfs namenode -bootstrapStandby

如果standby节点宕机时间过长,active节点由于没有standby节点进行checkpoint,可能fsimage的版本很低,可以在启动standby节点前手动执行savepoint,在同步fsimage。但是需要注意,手动执行checkpoint需要先进入安全模式,此时客户端是不能读写的,对业务有影响,需要业务低峰期执行。

# 进入安全模式
hdfs dfsadmin -safemode enter# 执行checkpoint
hdfs dfsadmin -saveNamespace
hdfs dfsadmin -saveNamespace# 离开安全模式
hdfs dfsadmin -safemode leave# standby同步元数据
hdfs namenode -bootstrapStandby

5. 疑问和思考

5.1 如何人工阅读editlog和fsimage文件的内容?

可以通过hdfs提供的工具进行读取

# 读取editlog和fsimage文件,并转化成xml文件
hdfs oev -i edits_0000000000000157832-0000000000000158267 -o test_edits.xml
hdfs oev -i fsimage_0000000000000002066 -o test_edits.xml
# -i 为输入edits文件地址
# -o 为输出的xml地址cat  test_edits.xml

在这里插入图片描述

5.2 checkpoint的触发策略是什么?

触发进行checkpoint的时机由这么几个配置项决定

dfs.namenode.checkpoing.check.period

检测是否满足上面两个条件的时间间隔,默认值为60秒。即1分钟检查一次。

dfs.namenode.checkpoint.period

执行checkpoint的最小时间间隔,默认为3600秒,即1小时。

dfs.namenode.checkpoint.txns

触发checkpoint的事务数,默认值为1000000。

上述两个条件只要符合其一,则执行checkpoint。
也就是说,3600s内一定会触发一次checkpoint,如果集群的写频繁,满足1000000条事务(还没到3600s)就会触发checkpoint

5.3 如果删除editlog失效导致保存过多的editlog,如果nn重启,启动过程是否会很长?

不一定。

启动过程时,依赖本地的fsimage,通过fsimage计算最小txid,并基于最小txid加载回放editlog,通常回放editlog的多少对启动过程的时长有很大的影响。

因此,

  • 如果standby进行checkpoint的流程正常,fsimage的版本比较高,nn启动过程也是比较快的。
  • 如果standby进行checkpoint的流程不正常,fsimage的版本比较低,nn启动过程就会比较慢。

5.4 如果standby长期宕机,active重启后有没有快速恢复的办法?

暂无。

原因是standby长期宕机,没有节点进行checkpoint,active节点的fsimage很老,需要回放大量的editlog(如果fsimage版本过低,editlog被清理策略清理,有可能会导致数据丢失),需要时间很长,因此很难快速恢复。

5.5 如何人工触发checkpoint?

# 进入安全模式
hdfs dfsadmin -safemode enter# 执行checkpoint
hdfs dfsadmin -saveNamespace
hdfs dfsadmin -saveNamespace# 离开安全模式
hdfs dfsadmin -safemode leave# standby同步元数据
hdfs namenode -bootstrapStandby

6. 参考文档

  • hadoop edits日志不删除现象排查
  • HDFS——fsimage

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/650115.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在windows安装python版本的tensorrt

文章目录 一、进入官网&#xff0c;下载tensorrt包二、下载后解压并把相应文件拷入对应cuda的文件夹2.1 拷贝头文件2.2 拷贝静态库2.3 拷贝动态库 三、安装whl文件四、验证 一、进入官网&#xff0c;下载tensorrt包 https://developer.nvidia.com/tensorrt-download 这里需要…

ElasticSearch的集群管理命令

ElasticSearch版本 {"name" : "data-slave1","cluster_name" : "data-es","cluster_uuid" : "xxxxxxxxxx-eMwxw","version" : {"number" : "7.2.1","build_flavor" : &…

QT 范例阅读:Vector Deformation

效果图&#xff1a; 主要代码&#xff1a; 实现放大镜效果QPainter painter;//两种方式if (1) {m_lens_image QImage(bounds.size(), QImage::Format_ARGB32_Premultiplied);m_lens_image.fill(0);painter.begin(&m_lens_image);} else {m_lens_pixmap QPixmap(bounds.si…

云手机哪一款好用?

随着海外市场的不断发展&#xff0c;云手机市场也呈现蓬勃的态势&#xff0c;众多云设备软件纷纷涌现。企业在选择云手机软件时&#xff0c;如何找到性能卓越的软件成为一项关键任务。在众多选择中&#xff0c;OgPhone云手机凭借其卓越的性能和独特功能脱颖而出。以下是OgPhone…

C#在图片上输出文字和保存

winform&#xff0c;图片控件&#xff0c;加载一个图片&#xff0c;在图片上输出文字&#xff1b; 输出文字的代码如下&#xff1b; private void pictureBox1_Paint(object sender, PaintEventArgs e){Graphics g1 e.Graphics;g1.DrawString("测试", this.Font, B…

搞定App关键词和评论

从关键词优化的三大基本概念走起&#xff01; 关联性 优化师一般如何选择关联性高的关键词呢&#xff1f; 主要思路如下&#xff1a;品牌词-关联词-竞品词-竞品关键词&#xff0c;优先级从前到后依次降低&#xff0c;通过ASO优化工具筛选出合适的关键词。做ASO有一个好处就是…

大型语言模型基础知识的可视化指南

直观分解复杂人工智能概念的工具和文章汇总 如今&#xff0c;LLM&#xff08;大型语言模型的缩写&#xff09;在全世界都很流行。没有一天不在宣布新的语言模型&#xff0c;这加剧了人们对错过人工智能领域的恐惧。然而&#xff0c;许多人仍在为 LLM 的基本概念而苦苦挣扎&…

8.16单调递增的数字(LC738-M)

算法&#xff1a; 拿一个两位的数字来举例。 例如&#xff1a;98&#xff0c;一旦出现strNum[i - 1] > strNum[i]的情况&#xff08;非单调递增&#xff09;&#xff0c;首先想让strNum[i - 1]--&#xff0c;然后strNum[i]给为9&#xff0c;这样这个整数就是89&#xff0c…

《动手学深度学习(PyTorch版)》笔记4.1

注&#xff1a;书中对代码的讲解并不详细&#xff0c;本文对很多细节做了详细注释。另外&#xff0c;书上的源代码是在Jupyter Notebook上运行的&#xff0c;较为分散&#xff0c;本文将代码集中起来&#xff0c;并加以完善&#xff0c;全部用vscode在python 3.9.18下测试通过。…

tf卡被格式化怎么恢复里面的数据?恢复指南在此

在日常生活中&#xff0c;我们经常使用TF卡来存储各种数据&#xff0c;如照片、视频、文档等。然而&#xff0c;有时候我们会误将TF卡格式化&#xff0c;导致其中的数据丢失。为了挽救这些宝贵的数据&#xff0c;我们需要采取一些措施来进行恢复。本文将为你介绍如何恢复TF卡中…

华为二层交换机与防火墙配置上网示例

二层交换机与防火墙对接上网配置示例 组网图形 图1 二层交换机与防火墙对接上网组网图 二层交换机简介配置注意事项组网需求配置思路操作步骤配置文件相关信息 二层交换机简介 二层交换机指的是仅能够进行二层转发&#xff0c;不能进行三层转发的交换机。也就是说仅支持二层…

sklearn 学习-混淆矩阵 Confusion matrix

混淆矩阵Confusion matrix&#xff1a;也称为误差矩阵&#xff0c;通过计算得出矩阵的结果用来表示分类器的精度。其每一列代表预测值&#xff0c;每一行代表的是实际的类别。 from sklearn.metrics import confusion_matrixy_true [2, 0, 2, 2, 0, 1] y_pred [0, 0, 2, 2, 0…

Executors工具类

concurrent包提供了Executors工具类&#xff0c;jdk基于Executors提供了很多种线程池。 public class Executors {/*** Creates a thread pool that reuses a fixed number of threads*/public static ExecutorService newFixedThreadPool(int nThreads) {return new ThreadPo…

《WebKit技术内幕》学习之十五(2):Web前端的未来

2 嵌入式应用模式 2.1 嵌入式模式 读者可能会奇怪本章重点表达的是Web应用和Web运行平台&#xff0c;为什么会介绍嵌入式模式&#xff08;Embedded Mode&#xff09;呢&#xff1f;这是因为很多Web运行平台是基于嵌入式模式的接口开发出来的&#xff0c;所以这里先解释一下什…

npm create vue3项目特别慢

问题&#xff1a;Vue CLI v5.0.8在配置了淘宝镜像的情况下&#xff0c;创建项目报Failed to check for updates&#xff0c;还特别慢&#xff0c;等了好久都创建不好 查看 npm config get registry更换npm镜像 npm config set registryhttps://registry.npmmirror.com这样创建…

电脑文件pdf怎么转换成word?30秒教你轻松转换

现在我们在工作和学习中经常接触到的文件类型一种是word文件&#xff0c;另一种就是pdf文件啦&#xff0c;这两种文件各有各的有点&#xff0c;适用的使用场景也不太一样&#xff0c;但是难免遇到需要把pdf转word的情况&#xff0c;那么pdf怎么转word呢&#xff1f;除了下载安装…

设计模式—行为型模式之责任链模式

设计模式—行为型模式之责任链模式 责任链&#xff08;Chain of Responsibility&#xff09;模式&#xff1a;为了避免请求发送者与多个请求处理者耦合在一起&#xff0c;于是将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链&#xff1b;当有请求发生时&am…

华清远见作业第三十二天——C++(第一天)

思维导图&#xff1a; 提示并输入一个字符串&#xff0c;统计字符中大写、小写个数、空格个数以及其他字符个数要求使用C风格完成。 代码&#xff1a; #include <iostream> #include<array> using namespace std;int main() {string str;cout << "请输…

5G时代下的融合CDN新风口

近年来&#xff0c;随着网络技术的飞速发展&#xff0c;互联网流量视频化的趋势日益明显&#xff0c;视频应用使互联网的可扩展性、可演进性、服务质量和网络安全面临诸多挑战。为克服传统IP网络在服务视频应用当中的不足&#xff0c;内容分发网络CDN被提出&#xff0c;并迅速成…

stm32中的SDIO

SDIO-SD卡 文章目录 SDIO-SD卡SD卡结构物理结构SD卡寄存器列表 SDIO总线SDIO总线拓扑SDIO总线SDIO总线协议常规数据传输宽位数据包 命令命令格式命令的类型命令集 SD卡的操作模式数据传输模式 STM32 的 SDIO 功能框图控制单元命令路径CPSM 状态机描述图数据路径数据 FIFO SDIO结…