文档章节

hadoop 配置文件处理

政委007
 政委007
发布于 2017/05/03 09:18
字数 1636
阅读 37
收藏 1

hadoop 配置文件处理

[toc]

Configuration 类

Configuration 作用

1.加载配置文件 2.可以加载多个配置文件 3.支持动态修改配置 4.快速保存配置文件

构造方法

    public Configuration();
    //是否加载默认的配置文件,默认为true 加载
    public Configuration(boolean loadDefaults);
    //根据其他实例 构件一个新的实例
    public Configuration(Configuration other);

主要成员变量

    //加载配置文件过程中是否输出日志,默认为true 不输出,主要用于开发调试
    private boolean quietmode = true;
    //保存通过addResource加载的对象
    private ArrayList<Resource> resources = new ArrayList<Resource>();
    //保存final属性为true的属性值
    private Set<String> finalParameters = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>());
    //保存解析配置文件后的健-值对
    private Properties properties;
    //保存通过set修改的配置项
    private Properties overlay;
    private ClassLoader classLoader;
    //保存了 健-来源数组 
    private Map<String, String[]> updatingResource;
    //被弃用的配置属性列表, AtomicReference 是确保赋值的原子操作, DeprecationContext 主要是被弃用的属性map
    private static AtomicReference<DeprecationContext> deprecationContext ;

加载资源方法

    //把其他配置文件中的name , 和value 值加载到当前配置中,其他像final等值放弃
    public void addResource(Configuration conf)
    public void addResource(InputStream in)
    //name加载在资源名称,主要在source中用到
    public void addResource(InputStream in, String name)
    public void addResource(Path file)
    //加载classpath下的文件 文件名=name
    public void addResource(String name)
    public void addResource(URL url)

addSource方法的具体实现

  public synchronized void reloadConfiguration() {
    properties = null;  // trigger reload
    finalParameters.clear(); // clear site-limits
  }
  
  private synchronized void addResourceObject(Resource resource) {
    //添加资源到资源列表的list中
    resources.add(resource); // add to resources
    //准备重新加载资源,实际上在getProps()方法中才会触发加载资源的动作
    reloadConfiguration();
  }

set方法

作用: 设置修改或添加一个键-值对

public void set(String name, String value, String source) {
    //判断name ,value 是否为null 如果为null 抛出异常IllegalArgumentException ,并携带错误信息
    Preconditions.checkArgument(
        name != null,
        "Property name must not be null");
    Preconditions.checkArgument(
        value != null,
        "The value of property " + name + " must not be null");
    name = name.trim();
    //获取被弃用的属性列表对象
    DeprecationContext deprecations = deprecationContext.get();
    //如果为空 ,调用getProps()方法 ,加载配置文件,解析配置项,加载配置文件
    if (deprecations.getDeprecatedKeyMap().isEmpty()) {
      getProps();
    }
    //添加到更新value的列表中
    getOverlay().setProperty(name, value);
    //添加到现在可用配置属性中
    getProps().setProperty(name, value);
    String newSource = (source == null ? "programatically" : source);
    //判断是否是被弃用的key
    if (!isDeprecated(name)) {
      updatingResource.put(name, new String[] {newSource});
      String[] altNames = getAlternativeNames(name);
      if(altNames != null) {
        for(String n: altNames) {
          if(!n.equals(name)) {
            getOverlay().setProperty(n, value);
            getProps().setProperty(n, value);
            updatingResource.put(n, new String[] {newSource});
          }
        }
      }
    }
    else {
      String[] names = handleDeprecation(deprecationContext.get(), name);
      String altSource = "because " + name + " is deprecated";
      for(String n : names) {
        getOverlay().setProperty(n, value);
        getProps().setProperty(n, value);
        updatingResource.put(n, new String[] {altSource});
      }
    }
  }

get方法

   public String get(String name) {
   //获取相关的name列表,包括被弃用的,或者新增的
    String[] names = handleDeprecation(deprecationContext.get(), name);
    String result = null;
    for(String n : names) {
      // 获取结果
      result = substituteVars(getProps().getProperty(n));
    }
    return result;
  }

其中substituteVars()方法 会根据传入的值,自动扩展属性,也就是说,value中包含了${key}这种格式的变量时,变量会被替换成对应的值。

解析配置文件方法 getProps()

 protected synchronized Properties getProps() {
    //判断properties 是否为空,如果为空 加载配置文件
    if (properties == null) {
      properties = new Properties();
      Map<String, String[]> backup =
          new ConcurrentHashMap<String, String[]>(updatingResource);
      //加载配置文件
      loadResources(properties, resources, quietmode);
      //加载更新过的配置,更新source列表
      if (overlay != null) {
        properties.putAll(overlay);
        for (Map.Entry<Object,Object> item: overlay.entrySet()) {
          String key = (String)item.getKey();
          String[] source = backup.get(key);
          if(source != null) {
            updatingResource.put(key, source);
          }
        }
      }
    }
    return properties;
  }
  //加载配置文件
   private void loadResources(Properties properties,
                             ArrayList<Resource> resources,
                             boolean quiet) {
    //加载默认配置文件
    if(loadDefaults) {
      for (String resource : defaultResources) {
        loadResource(properties, new Resource(resource), quiet);
      }
    
      //support the hadoop-site.xml as a deprecated case
      if(getResource("hadoop-site.xml")!=null) {
        loadResource(properties, new Resource("hadoop-site.xml"), quiet);
      }
    }
    //加载addsource() 添加的source
    for (int i = 0; i < resources.size(); i++) {
      Resource ret = loadResource(properties, resources.get(i), quiet);
      if (ret != null) {
        resources.set(i, ret);
      }
    }
  }
  //加载单个配置文件
  private Resource loadResource(Properties properties, Resource wrapper, boolean quiet) {
    String name = UNKNOWN_RESOURCE;
    try {
      Object resource = wrapper.getResource();
      name = wrapper.getName();
      
      DocumentBuilderFactory docBuilderFactory 
        = DocumentBuilderFactory.newInstance();
      //ignore all comments inside the xml file ,是否忽略注释
      docBuilderFactory.setIgnoringComments(true);

      //allow includes in the xml file, 支持命名空间
      docBuilderFactory.setNamespaceAware(true);
      try {
          //支持include机制
          docBuilderFactory.setXIncludeAware(true);
      } catch (UnsupportedOperationException e) {
        LOG.error("Failed to set setXIncludeAware(true) for parser "
                + docBuilderFactory
                + ":" + e,
                e);
      }
      DocumentBuilder builder = docBuilderFactory.newDocumentBuilder();
      Document doc = null;
      Element root = null;
      boolean returnCachedProperties = false;
      //判断souurce 类型 ,解析资源,用dom方法,解析构建document对象
      if (resource instanceof URL) {                  // an URL resource
        doc = parse(builder, (URL)resource);
      } else if (resource instanceof String) {        // a CLASSPATH resource
        URL url = getResource((String)resource);
        doc = parse(builder, url);
      } else if (resource instanceof Path) {          // a file resource
        // Can't use FileSystem API or we get an infinite loop
        // since FileSystem uses Configuration API.  Use java.io.File instead.
        File file = new File(((Path)resource).toUri().getPath())
          .getAbsoluteFile();
        if (file.exists()) {
          if (!quiet) {
            LOG.debug("parsing File " + file);
          }
          doc = parse(builder, new BufferedInputStream(
              new FileInputStream(file)), ((Path)resource).toString());
        }
      } else if (resource instanceof InputStream) {
        doc = parse(builder, (InputStream) resource, null);
        returnCachedProperties = true;
      } else if (resource instanceof Properties) {
        overlay(properties, (Properties)resource);
      } else if (resource instanceof Element) {
        root = (Element)resource;
      }

      if (root == null) {
        if (doc == null) {
          if (quiet) {
            return null;
          }
          throw new RuntimeException(resource + " not found");
        }
        root = doc.getDocumentElement();
      }
      Properties toAddTo = properties;
      if(returnCachedProperties) {
        toAddTo = new Properties();
      }
      //判断是否为configuration 节点
      if (!"configuration".equals(root.getTagName()))
        LOG.fatal("bad conf file: top-level element not <configuration>");
      NodeList props = root.getChildNodes();
      DeprecationContext deprecations = deprecationContext.get();
      //循环子节点
      for (int i = 0; i < props.getLength(); i++) {
        Node propNode = props.item(i);
        if (!(propNode instanceof Element))
          continue;
        Element prop = (Element)propNode;
        //如果包含了其他配置文件, 递归解析配置文件
        if ("configuration".equals(prop.getTagName())) {
          loadResource(toAddTo, new Resource(prop, name), quiet);
          continue;
        }
        if (!"property".equals(prop.getTagName()))
          LOG.warn("bad conf file: element not <property>");
        NodeList fields = prop.getChildNodes();
        String attr = null;
        String value = null;
        boolean finalParameter = false;
        LinkedList<String> source = new LinkedList<String>();
        //解析 name ,value ,final,source等配置项
        for (int j = 0; j < fields.getLength(); j++) {
          Node fieldNode = fields.item(j);
          if (!(fieldNode instanceof Element))
            continue;
          Element field = (Element)fieldNode;
          if ("name".equals(field.getTagName()) && field.hasChildNodes())
            attr = StringInterner.weakIntern(
                ((Text)field.getFirstChild()).getData().trim());
          if ("value".equals(field.getTagName()) && field.hasChildNodes())
            value = StringInterner.weakIntern(
                ((Text)field.getFirstChild()).getData());
          if ("final".equals(field.getTagName()) && field.hasChildNodes())
            finalParameter = "true".equals(((Text)field.getFirstChild()).getData());
          if ("source".equals(field.getTagName()) && field.hasChildNodes())
            source.add(StringInterner.weakIntern(
                ((Text)field.getFirstChild()).getData()));
        }
        source.add(name);
        
        // Ignore this parameter if it has already been marked as 'final'
        if (attr != null) {
          if (deprecations.getDeprecatedKeyMap().containsKey(attr)) {
            DeprecatedKeyInfo keyInfo =
                deprecations.getDeprecatedKeyMap().get(attr);
            keyInfo.clearAccessed();
            for (String key:keyInfo.newKeys) {
              // update new keys with deprecated key's value 
              //更新新的key 用被弃用key的value,同时忽略final属性为ture的值
              loadProperty(toAddTo, name, key, value, finalParameter, 
                  source.toArray(new String[source.size()]));
            }
          }
          else {
            loadProperty(toAddTo, name, attr, value, finalParameter, 
                source.toArray(new String[source.size()]));
          }
        }
      }
      
      if (returnCachedProperties) {
        overlay(properties, toAddTo);
        return new Resource(toAddTo, name);
      }
      return null;
    } catch (IOException e) {
      LOG.fatal("error parsing conf " + name, e);
      throw new RuntimeException(e);
    } catch (DOMException e) {
      LOG.fatal("error parsing conf " + name, e);
      throw new RuntimeException(e);
    } catch (SAXException e) {
      LOG.fatal("error parsing conf " + name, e);
      throw new RuntimeException(e);
    } catch (ParserConfigurationException e) {
      LOG.fatal("error parsing conf " + name , e);
      throw new RuntimeException(e);
    }
  }

Configurable 接口

主要有两个方法 getConf(),setConf() 主要使用方法: 和org.apahce.hadoop.util.ReflectionUtils的newInstance()配合使用。

  public static <T> T newInstance(Class<T> theClass, Configuration conf) {
    T result;
    try {
      Constructor<T> meth = (Constructor<T>) CONSTRUCTOR_CACHE.get(theClass);
      if (meth == null) {
        meth = theClass.getDeclaredConstructor(EMPTY_ARRAY);
        meth.setAccessible(true);
        CONSTRUCTOR_CACHE.put(theClass, meth);
      }
      result = meth.newInstance();
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
    setConf(result, conf);
    return result;
  }
  public static void setConf(Object theObject, Configuration conf) {
    if (conf != null) {
      //检测到对象实现了Configuable 接口,会调用setConf()方法,初始化对象
      if (theObject instanceof Configurable) {
        ((Configurable) theObject).setConf(conf);
      }
      setJobConf(theObject, conf);
    }
  }

ConfServlet

主要作用: 处理来自页面的配置文件请求

© 著作权归作者所有

政委007
粉丝 10
博文 15
码字总数 15843
作品 0
洛阳
程序员
私信 提问
Spring Hadoop Yarn HA问题调研

Spring Hadoop Yarn HA问题调研 OneCoder2017-03-2461 阅读 Hadoop Spring XD on Yarn在使用过程中发现不论是YarnClient还是AppMaster对Yarn HA的支持都不好。在Yarn的RM重启或切换的情况下,...

OneCoder
2017/03/24
0
0
阿里云ECS构建大数据平台实践-基于Apache Hadoop

0. 项目背景 基于阿里云ECS云服务器进行搭建私有的大数据平台,采用Apache Hadoop生态,为大数据提供存储及处理。 1. 购买ECS云服务器实例 在这里,因为实验需要3个节点,所以我们购买3台ECS...

叶康铭
01/09
0
0
Hadoop3.0安装配置

Hadoop3.0安装配置 1.在主机上安装java8(hadoop3.0需要Java8,操作细节见上篇) 2.下载hadoop安装tar包(ubuntu下可以使用wget命令直接下载路径) 3.解压到/opt/ 4.创建hadoop3.0用户 添加用户...

qq_37423198
2017/12/13
0
0
【hadoop】4.伪分布式模式

简介 前面我们讲到了hadoop拥有3种运行模式,搭建了最简答的本地运行模式并在其上运行了两个简单案例。本章节我们学习伪分布模式。顾名思义,该模式外在看起来像是分布式,实际上只有一个节点...

落花时节又逢卿
01/03
5
0
Hadoop安装(Hadoop2.7.3)

在Ubantu14.04上部署Hadoop2.7.3 伪分布式集群 01.安装Ubantu14.04(过程略) 02.安装JDK1.8 01)下载JDK1.8,将jdk-8u131-linux-x64.tar.gz上传至ubantu中 02)在根目录下创建soft文件夹,并改变...

小马Ha
2017/07/08
0
0

没有更多内容

加载失败,请刷新页面

加载更多

DDD(五)

1、引言 之前学习了解了DDD中实体这一概念,那么接下来需要了解的就是值对象、唯一标识。值对象,值就是数字1、2、3,字符串“1”,“2”,“3”,值时对象的特征,对象是一个事物的具体描述...

MrYuZixian
59分钟前
3
0
数据库中间件MyCat

什么是MyCat? 查看官网的介绍是这样说的 一个彻底开源的,面向企业应用开发的大数据库集群 支持事务、ACID、可以替代MySQL的加强版数据库 一个可以视为MySQL集群的企业级数据库,用来替代昂贵...

沉浮_
今天
4
0
解决Mac下VSCode打开zsh乱码

1.乱码问题 iTerm2终端使用Zsh,并且配置Zsh主题,该主题主题需要安装字体来支持箭头效果,在iTerm2中设置这个字体,但是VSCode里这个箭头还是显示乱码。 iTerm2展示如下: VSCode展示如下: 2...

HelloDeveloper
今天
6
0
常用物流快递单号查询接口种类及对接方法

目前快递查询接口有两种方式可以对接,一是和顺丰、圆通、中通、天天、韵达、德邦这些快递公司一一对接接口,二是和快递鸟这样第三方集成接口一次性对接多家常用快递。第一种耗费时间长,但是...

程序的小猿
今天
5
0
Python机器学习之数据探索可视化库yellowbrick

背景介绍 从学sklearn时,除了算法的坎要过,还得学习matplotlib可视化,对我的实践应用而言,可视化更重要一些,然而matplotlib的易用性和美观性确实不敢恭维。陆续使用过plotly、seaborn,...

yeayee
今天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部