HADOOP动态加载配置

16 January 2013

简介

Hadoop集群运行过程中有时会需要对配置进行修改,而通常需要重启才能生效,如该HDFS Namenode的一个配置,需要重启NN才能生效。而对于规模较大的系统,重启的成本较高。HADOOP-7001引入了一个reconfigurable机制。简述如下:

Reconfig_class

HADOOP-7001提供了一个Reconfigure接口用于定义可动态配置的的行为。并提供了一个ReconfigurableBase抽象的基类实现。该基类有两个抽象方法,所有想要实现动态配置的节点,都需要实现这两个方法:

//某个可以动态配置的属性变化时需要进行的处理
protected abstract void reconfigurePropertyImpl(String property, String newVal) 
    throws ReconfigurationException;

//定义该节点上所有可以进行动态配置的属性集合
public abstract Collection<String> getReconfigurableProperties();

为了便于完成配置项变更,HADOOP-7001还提供了一个ReconfigurationServlet工具便于从web端变更配置。使用时只需要将该servelt加入到相应节点的httpserver中,并在context中加入conf.servlet.reconfigurable.$P的参数,值为对应的Reconfigurable实现(一般为节点自身实现),其中$P表示的是ReconfigurationServlet在httpServer中对应的path。

NameNode中的使用

HDFS-1477中提供了NameNode Reconfigurable的实现。概要分析如下:

1. 扩展ReconfigurableBase

首先需要扩展Reconfigurable来使NameNode支持动态配置

public class NameNode extends ReconfigurableBase implements ClientProtocol, 
    DatanodeProtocol,NamenodeProtocol, FSConstants {

      //。。。。
      //此处省略N多无关代码
      //        

      //实现当发生配置变更时Namenode的具体处理行为
      @Override
      public void reconfigurePropertyImpl(String property, String newVal) 
        throws ReconfigurationException {
        // just pass everything to the namesystem
        if (namesystem.isPropertyReconfigurable(property)) {
         namesystem.reconfigureProperty(property, newVal);
        } else if ("fs.trash.interval".equals(property)) {
          try {
            if (newVal == null) {
              // set to default
              trash.setDeleteInterval(60L * Trash.MSECS_PER_MINUTE);
            } else {
              trash.setDeleteInterval((long)(
                  Float.valueOf(newVal) * Trash.MSECS_PER_MINUTE));
            }
            LOG.info("RECONFIGURE* changed trash deletion interval to " +
                newVal);
          } catch (NumberFormatException e) {
            throw new ReconfigurationException(property, newVal,
                getConf().get(property));
          }
        } else {
          throw new ReconfigurationException(property, newVal,
                                             getConf().get(property));
        }
      }

      //设置NameNode上允许动态配置的属性值
      @Override
      public List<String> getReconfigurableProperties() {
        // only allow reconfiguration of namesystem's reconfigurable properties
        List<String> properties = namesystem.getReconfigurableProperties();
        properties.add("fs.trash.interval");
        return properties;
      }

2. 在httpserver中配置ReconfigurationServlet

为了便于配置,需要在httpserver中添加ReconfigurationServlet,具体代码如下

private void startHttpServer(Configuration conf) throws IOException {

    //省略无关代码

    //设置context属性
    httpServer.setAttribute(ReconfigurationServlet.
                            CONF_SERVLET_RECONFIGURABLE_PREFIX +
                            CONF_SERVLET_PATH, NameNode.this);
    //添加servelt, path为nnconfchange
    httpServer.addServlet("nnconfchange", CONF_SERVLET_PATH,
                          ReconfigurationServlet.class);
    this.httpServer.start();

    // The web-server port can be ephemeral... ensure we have the correct info
    infoPort = this.httpServer.getPort();
    this.httpAddress = new InetSocketAddress(infoHost, infoPort);
    conf.set("dfs.http.address", infoHost + ":" + infoPort);
    LOG.info("Web-server up at: " + infoHost + ":" + infoPort);
  }

3.具体使用

登录到NN,修改配置文件,通过web访问 http://hdfsnn:port/nnconfchange来查看配置项,点击apply可以是新的配置项生效,如果配置项变更出错会返回500.



blog comments powered by Disqus