前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >HDFS——JN扩容的正确姿势

HDFS——JN扩容的正确姿势

作者头像
陈猿解码
发布2023-02-28 14:27:57
4520
发布2023-02-28 14:27:57
举报
文章被收录于专栏:陈猿解码

【前言】


有一段时间没有更文了,一方面是之前准备的hudi系列由于一些细节还没研究得很清楚,暂时没有继续更新。另一方面,最近事情相当多,回家后收拾收拾就十一二点了,也就没有再进行总结输出了。

不过,最近还是囤积了不少可以总结复盘的知识点,后续不管怎样还是尽量保证一周至少一篇原创文章,倒逼自己总结输出~

本文来聊聊HDFS里面,如果正确将JN从一个节点扩容到多个节点。

可能有的小伙伴会好奇,怎么会有这种需求或场景,需要将JN从一个节点扩容到3个以上的节点。

实际可能的情况是:在资源不够充足的情况下,整体部署舍弃一部分服务的高可用,例如NN还是以HA模式部署,但JN仅部署1个。此后,可能条件富裕了,相应的高可用也就需要做得更完善些,这个时候就需要将JN从1个节点扩容到3个及以上的节点。

【理想中的扩容步骤】


咋一看,JN的扩容应该是一件很简单的事情,涉及的操作步骤为:

第一步:新增多个节点,并部署启动JN

第二步:在NN的配置中添加新的JN的IP

第三步:重启NN,就可以完成JN的扩容操作了

操作步骤及流程看似没有什么问题,但结果却不是我们所期望的。实际上,NN重新启动后,会持续报错并抛出异常,最终自行结束,其报错信息为:

代码语言:javascript
复制
172.168.3.12:8485: Journal Storage Directory /home/hncscwc/hadoop/dfs/journal/hdfsHACluster not formatted
        at org.apache.hadoop.hdfs.qjournal.server.Journal.checkFormatted(Journal.java:480)
        at org.apache.hadoop.hdfs.qjournal.server.Journal.getEditLogManifest(Journal.java:662)
        at org.apache.hadoop.hdfs.qjournal.server.JournalNodeRpcServer.getEditLogManifest(JournalNodeRpcServer.java:191)
        at org.apache.hadoop.hdfs.qjournal.protocolPB.QJournalProtocolServerSideTranslatorPB.getEditLogManifest(QJournalProtocolServerSideTranslatorPB.java:224)
        at org.apache.hadoop.hdfs.qjournal.protocol.QJournalProtocolProtos$QJournalProtocolService$2.callBlockingMethod(QJournalProtocolProtos.java:25431)
        at org.apache.hadoop.ipc.ProtobufRpcEngine$Server$ProtoBufRpcInvoker.call(ProtobufRpcEngine.java:447)
        at org.apache.hadoop.ipc.RPC$Server.call(RPC.java:989)
        at org.apache.hadoop.ipc.Server$RpcCall.run(Server.java:850)
        at org.apache.hadoop.ipc.Server$RpcCall.run(Server.java:793)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.security.auth.Subject.doAs(Subject.java:422)
        at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1922)
        at org.apache.hadoop.ipc.Server$Handler.run(Server.java:2489)

        at org.apache.hadoop.hdfs.qjournal.client.QuorumException.create(QuorumException.java:81)
        at org.apache.hadoop.hdfs.qjournal.client.QuorumCall.rethrowException(QuorumCall.java:286)
        at org.apache.hadoop.hdfs.qjournal.client.AsyncLoggerSet.waitForWriteQuorum(AsyncLoggerSet.java:142)
        at org.apache.hadoop.hdfs.qjournal.client.QuorumJournalManager.selectInputStreams(QuorumJournalManager.java:477)
        at org.apache.hadoop.hdfs.server.namenode.JournalSet.selectInputStreams(JournalSet.java:278)
        at org.apache.hadoop.hdfs.server.namenode.FSEditLog.selectInputStreams(FSEditLog.java:1590)
        at org.apache.hadoop.hdfs.server.namenode.FSEditLog.selectInputStreams(FSEditLog.java:1614)
        at org.apache.hadoop.hdfs.server.namenode.FSImage.loadFSImage(FSImage.java:695)
        at org.apache.hadoop.hdfs.server.namenode.FSImage.recoverTransitionRead(FSImage.java:317)
        at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.loadFSImage(FSNamesystem.java:1045)
        at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.loadFromDisk(FSNamesystem.java:707)
        at org.apache.hadoop.hdfs.server.namenode.NameNode.loadNamesystem(NameNode.java:635)
        at org.apache.hadoop.hdfs.server.namenode.NameNode.initialize(NameNode.java:696)
        at org.apache.hadoop.hdfs.server.namenode.NameNode.<init>(NameNode.java:906)
        at org.apache.hadoop.hdfs.server.namenode.NameNode.<init>(NameNode.java:885)
        at org.apache.hadoop.hdfs.server.namenode.NameNode.createNameNode(NameNode.java:1626)
        at org.apache.hadoop.hdfs.server.namenode.NameNode.main(NameNode.java:1694)

为什么会这样呢?

回顾《一文搞定journal node原理》文章中讲到的,NN启动后首先会向JN发送多个rpc请求,完成从JN同步editlog信息,以及JN集群之间的editlog同步。

每个RPC请求都必须有多数以上的节点成功响应,该次rpc请求才算是真的成功。

JN在收到NN的rpc请求时,会对自身情况进行判断,如果所在的持久化路径中没有保存NN集群的元数据信息(存储在VERSION文件中),则认为自身没有格式化,因此返回错误,并最终导致NN退出。

而JN保存的NN的元数据信息仅在整个集群部署时,NN通过格式化命令下发给所有JN,此后均不再进行集群信息的同步。

那是不是再次触发一次格式化就可以了呢?

这种方法,可以是可以的,但存在的问题是:格式化这个动作是将当前的元数据全部清除。也就是说,如果已有的数据全部不需要了,那么可以考虑采用这种方式。

但一般来说,进行升级扩容时,还是希望所有已经存储的数据保留,因此该方法是行不通的。

【正确姿势】


了解了问题的本质后(JN缺少NN的集群信息,认为未格式化),剩下的就是对症下药了,即只要保证新增的JN节点上有NN集群的元数据信息就可以了。

那么可行的方式有:

  • 将原有JN中的文件拷贝到新增JN节点对应的持久化位置

整体扩容流程和前面讲到的雷同,先新增JN节点;然后将原有节点中的VERSION文件拷贝到新JN节点中对应配置文件中指定的存储目录,并启动JN;接着修改NN的配置项,之后重启NN即可。

注意:在JN配置文件指定的目录下,还需要手动创建 $NAMESPACE/current目录,然后将VERSION文件,放到current目录下。

$NAMESPACE为配置项"dfs.nameservices"的值。

  • 通过NN对新增的节点进行初始化

同样是先新增并部署启动JN;然后修改NN的配置文件,并在ActiveNN中,通过执行下面的命令完成对JN节点的初始化动作,最后重启NN即可。

代码语言:javascript
复制
hdfs namenode -f ./hdfs-site.xml -initializeSharedEdits

这里使用的配置文件可以就是nn当前使用的配置文件,但需要注意的是:

配置文件中的配置项不能包含已有的JN节点信息,否则会报错失败。因为已经格式化过的JN节点不能再次进行格式化操作,重复格式化会报错。

或者通过手动指定JN节点的ip完成JN的初始化动作,具体命令如下:

代码语言:javascript
复制
hdfs namenode -Ddfs.namenode.shared.edits.dir="qjournal://$JN2:8485;$JN3:8485/$NAMESPACE" -initializeSharedEdits

## JN2,JN3为新增jn节点的ip
## NAMESPACE为配置项 dfs.nameservices 的值

tips:initializeSharedEdits原本用于hdfs从standalone模式升级到HA模式,即standalone模式下不会配置JN节点,到HA模式后,需要配置JN节点。因此需要对JN进行格式化,包括同步NN的集群信息,以及将该NN上存储的editlog文件同步到JN中。

在这种场景下,原理是一样的,只需要注意不要对已有的JN节点再次进行初始化操作即可。

【总结】


一句话简单总结就是:新增或首次部署的jn,需要有nn的集群信息(即先进行格式化)才能正常提供服务

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-03-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 陈猿解码 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档