HDFS的滚动升级: Rolling Upgrade

前言


目前Hadoop版本更新迭代的速度还是比较快的,每次新版本的发布,都是一件令人期待的事情.因为这意味着用户可以使用新的功能特性,又或者说在新版中某某模块性能得到了巨大提升等等.现在问题来了,如果我们想用新的Hadoop版本,那么我们必须对现有版本进行升级.在一定程度上来讲,Hadoop的升级说白了其实就是HDFS的升级,也就是数据上的升级.在传统的升级方案中,我们往往需要停止集群服务来做这样的操作.如果集群规模已经是非常大的情况下时,这样做的代价实在太高.为了解决这类的问题,HDFS在2.4.0以及以上版本中引入了Rolling Upgrade的概念,也就是滚动升级的意思.Rolling Upgrade升级方式最重要的一点是它可以保证在升级过程中集群依然可以对外提供服务.本文将会从升级原理以及实际步骤操作两方面进行相关内容的阐述.

Rolling Upgrade相关指令以及原理


在讲述Rolling Upgrade实际操作步骤之前,我们有必要事先了解其中相关的使用命令,以及这些命令的作用和原理.主要是下面这6个:

  • 1.hdfs dfsadmin下的子命令
    • 1.1 hdfs dfsadmin -rollingUpgrade prepare
    • 1.2 hdfs dfsadmin -rollingUpgrade query
    • 1.3 hdfs dfsadmin -rollingUpgrade finalize
  • 2.hdfs namenode下的子命令
    • 2.1 hdfs namenode -rollingUpgrade rollback
    • 2.2 hdfs namenode -rollingUpgrade started
  • 3.hdfs datanode下的子命令
    • 3.1 hdfs datanode rollback

下面我们对上面的命令一一做分析.

hdfs dfsadmin下的升级命令


首先是hdfs dfsadmin下的3条命令,这是官方文档对这3条命令的解释:

query: Query the current rolling upgrade status.
prepare: Prepare a new rolling upgrade.
finalize : Finalize the current rolling upgrade.

可能看完官方文档的解释,我们还是会有点迷惑,没有关系,下面我们直接定位到相关代码,来深入了解其背后的操作原理.

hdfs dfsadmin的入口类为DFSAdmin,顺着此类,我们可以找到对应服务端的处理方法,在NameNodeRpcServer类中,如下:

  public RollingUpgradeInfo rollingUpgrade(RollingUpgradeAction action) throws IOException {
    checkNNStartup();
    LOG.info("rollingUpgrade " + action);
    // 不同hdfs dfsadmin -rollingUpgrade操作对应不同action处理
    switch(action) {
    case QUERY:
      // 对应hdfs dfsadmin -rollingUpgrade query
      return namesystem.queryRollingUpgrade();
    case PREPARE:
      // 对应hdfs dfsadmin -rollingUpgrade prepare
      return namesystem.startRollingUpgrade();
    case FINALIZE:
      // 对应hdfs dfsadmin -rollingUpgrade finalize
      return namesystem.finalizeRollingUpgrade();
    default:
      throw new UnsupportedActionException(action + " is not yet supported.");
    }
  }

NameNodeRpcServer类的rollingUpgrade方法继而调用FSNamesystem的方法完成最后的操作.我们首先分析Prepare的处理逻辑,代码如下:

  RollingUpgradeInfo startRollingUpgrade() throws IOException {
    checkSuperuserPrivilege();
    checkOperation(OperationCategory.WRITE);
    writeLock();
    try {
      checkOperation(OperationCategory.WRITE);
      // 判断是否正处于rolling upgrade状态,如果是,则返回相关信息
      if (isRollingUpgrade()) {
        return rollingUpgradeInfo;
      }
      // 如果不是,则执行rolling upgrade开始动作,分为HA和非HA模式
      long startTime = now();
      if (!haEnabled) { // for non-HA, we require NN to be in safemode
        startRollingUpgradeInternalForNonHA(startTime);
      } else { // for HA, NN cannot be in safemode
        checkNameNodeSafeMode("Failed to start rolling upgrade");
        startRollingUpgradeInternal(startTime);
      }
      // 执行editlog相关记录操作
      getEditLog().logStartRollingUpgrade(rollingUpgradeInfo.getStartTime());
      if (haEnabled) {
        // roll the edit log to make sure the standby NameNode can tail
        getFSImage().rollEditLog();
      }
    } finally {
      writeUnlock();
    }
    ...
    // 返回升级对象信息
    return rollingUpgradeInfo;
  }

在startRollingUpgrade执行方法中,主要创建了将来用于rollback的镜像文件,但是在实现方式上,HA与非HA模式并不完全相同,以非HA模式为例:

  private void startRollingUpgradeInternalForNonHA(long startTime)
      throws IOException {
    Preconditions.checkState(!haEnabled);
    if (!isInSafeMode()) {
      throw new IOException("Safe mode should be turned ON "
          + "in order to create namespace image.");
    }
    checkRollingUpgrade("start rolling upgrade");
    getFSImage().checkUpgrade();
    // 做一次checkpoint,生成一个新的用于rollback的镜像
    // in non-HA setup, we do an extra checkpoint to generate a rollback image
    getFSImage().saveNamespace(this, NameNodeFile.IMAGE_ROLLBACK, null);
    LOG.info(
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值