Hadoop源码分析笔记(一):Hadoop Configuration详解
来源:互联网 发布:软件开发工作计划模板 编辑:程序博客网 时间:2024/05/16 10:58
Hadoop Conguration详解:
本文着重讲述Hadoop配置模块的基础类:org.apache.hadoop.conf.Configuration。
Java配置文件
JDK本身提供了java.util.Properties类,用户处理简单的配置文件。Properties类,它是继承自Hashtable,表示一个持久的属性集,该集可保存在流中,或者从流中加载。属性列表中的每个键及其对应值都是字符串类型。下面是Properties提供的几个主要的方法。
//从流中加载属性public void load(InputStrem inStream)//从一个Reader中加载属性public void load(Reader reader)//从一个XML文件流中加载属性public void loadFromXML(InputStrem in)//根据指定的Key在属性列表中查找属性public String getProperty(String Key)//根据指定的Key在属性列表中查找属性,如果没有则用给定的默认值public String getProperty(String key,String defaultValue)//同步方法,给属性列表添加值,最终调用Hashtable的方法putpublic synchronized Object setProperty(String key,String value)
从以上的API中,我们可以实现一个简单的配置文件。
Hadoop配置文件
Hadoop没有使用Java本身提供的java.util.Properties管理配置文件,它使用一套独有的配置文件管理系统,并提供API。既使用org.apache.hadoop.conf.Configuration处理配置信息。下面摘录一段Hadoop的配置信息如下:
<?xml version="1.0"?><?xml-stylesheet type="text/xsl"href="configuration.xsl"?><configuration><property> <name>fs.default.name</name> <value>hdfs://node1:49000</value></property><property> <name>hadoop.tmp.dir</name> <value>/home/hadoop/hadoop_home/var</value></property></configuration>
从以上的配置中,我们不难发现Hadoop配置文件的根元素是configuration,一般只包含子元素property。每一个property元素就是一个配置项,配置文件不支持分层或分级。没个配置项一般包括配置属性的名称name、值value和一个关于配置项的描述description。
在Configuration中,每个元素都是String类型的,但是值类型基本上包括Java的基本类型。
Configuration的成员
//configuration的成员boolean quietmode;ArrayList<Object> resources;Set<String> finalParameters;boolean loadDefaults;ArrayList<String> defaultResources;Properties properties;properties overlay;ClassLoader classLoader;//方法public void addResource(InputStream in);public void addResource(Path file);public void addResource(String name);public void addResouce(URL url);private synchronized void addResourceObject(Object resource);public synchronized void reloadConfiguration();private synchronized Properties getProps();
Confuguration中的布尔变量loadDefaults用于确定是否加载默认资源,这些默认资源将保持在defaultResources中。在HDFS中,会把hdfs-default.xml和hdfs-site.xml作为默认资源,并且通过addDefaultResource保持在defaultResources中。在MapReduce中,默认资源是mapred-default.xml和mapred-site.xml。
properties、overlay和finalParameters都是和配置项相关的成员变量。其中,properties和overlay的类型就是前面介绍的java.util.Properties。Hadoop配置文件解析后的键值对都存放在properties中。变量finalParameters的类型是Set<String>,用来保存所有在配置文件中已经被申明为final的键-值对的键。
Hadoop的配置文件都是XML形式,Java本身提供稳定和可靠的XML处理API,如SAX和DOM两种XML处理方法。
DOM和SAX的不同之处在于,DOM首先需要将XML文档一次性装入内存,然后根据文档中定义的元素和属性在内存中创建一个文档对象模型,并且提供使用对象的编程API操作XML文档。下面截取一段DOM解析XML的源代码如下:
private void loadResource(Properties properties, Object name, boolean quiet) { try {//得到用户创建DOM解析器的工厂 DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); //ignore all comments inside the xml file docBuilderFactory.setIgnoringComments(true); //allow includes in the xml file docBuilderFactory.setNamespaceAware(true); try { docBuilderFactory.setXIncludeAware(true); } catch (UnsupportedOperationException e) { LOG.error("Failed to set setXIncludeAware(true) for parser " + docBuilderFactory + ":" + e, e); }//获取解析XML的Builder对象 DocumentBuilder builder = docBuilderFactory.newDocumentBuilder(); Document doc = null; Element root = null; //根据不同的资源,做出不同的判断 if (name instanceof URL) { // an URL resource URL url = (URL)name; if (url != null) { if (!quiet) { LOG.info("parsing " + url); } doc = builder.parse(url.toString()); } } else if (name instanceof String) { // a CLASSPATH resource URL url = getResource((String)name); if (url != null) { if (!quiet) { LOG.info("parsing " + url); } doc = builder.parse(url.toString()); } } else if (name 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)name).toUri().getPath()) .getAbsoluteFile(); if (file.exists()) { if (!quiet) { LOG.info("parsing " + file); } InputStream in = new BufferedInputStream(new FileInputStream(file)); try { doc = builder.parse(in); } finally { in.close(); } } } else if (name instanceof InputStream) { try { doc = builder.parse((InputStream)name); } finally { ((InputStream)name).close(); } } else if (name instanceof Element) { root = (Element)name; } if (doc == null && root == null) { if (quiet) return; throw new RuntimeException(name + " not found"); } if (root == null) { root = doc.getDocumentElement(); }//解析一下节点 if (!"configuration".equals(root.getTagName())) LOG.fatal("bad conf file: top-level element not <configuration>"); NodeList props = root.getChildNodes(); 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(properties, prop, 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; 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 = ((Text)field.getFirstChild()).getData().trim(); if ("value".equals(field.getTagName()) && field.hasChildNodes()) value = ((Text)field.getFirstChild()).getData(); if ("final".equals(field.getTagName()) && field.hasChildNodes()) finalParameter = "true".equals(((Text)field.getFirstChild()).getData()); } // Ignore this parameter if it has already been marked as 'final' if (attr != null) { if (value != null) { if (!finalParameters.contains(attr)) { properties.setProperty(attr, value); if (storeResource) { updatingResource.put(attr, name.toString()); } } else if (!value.equals(properties.getProperty(attr))) { LOG.warn(name+":a attempt to override final parameter: "+attr +"; Ignoring."); } } if (finalParameter) { finalParameters.add(attr); } } } } catch (IOException e) { LOG.fatal("error parsing conf file: " + e); throw new RuntimeException(e); } catch (DOMException e) { LOG.fatal("error parsing conf file: " + e); throw new RuntimeException(e); } catch (SAXException e) { LOG.fatal("error parsing conf file: " + e); throw new RuntimeException(e); } catch (ParserConfigurationException e) { LOG.fatal("error parsing conf file: " + e); throw new RuntimeException(e); } }
版权申明:本文部分摘自【蔡斌、陈湘萍】所著【Hadoop技术内幕 深入解析Hadoop Common和HDFS架构设计与实现原理】一书,仅作为学习笔记,用于技术交流,其商业版权由原作者保留,推荐大家购买图书研究,转载请保留原作者,谢谢!
- Hadoop源码分析笔记(一):Hadoop Configuration详解
- Hadoop Configuration 源码详解
- Hadoop源码分析之Configuration
- Hadoop源码分析之Configuration
- hadoop源码学习(一)--configuration类详解
- Hadoop源码分析笔记(一)
- hadoop 源码分析一
- Hadoop源码分析 之Configuration配置
- Hadoop 2.6.0 Configuration源码分析
- hadoop-common源码分析之-Configuration
- (一)hadoop源码学习之Configuration
- hadoop Configured Configrable Configuration Tool 源码详解
- 2.2 Hadoop Configuration详解
- Hadoop Configuration详解
- Hadoop Configuration详解
- Hadoop Configuration详解
- Hadoop Configuration详解
- Hadoop configuration详解
- 学习笔记-隐藏键盘的一个方法例子
- 一个毕业6年的程序员工作经历和成长感悟(下)
- 过剩数
- 某大型银行深化系统之二十一:Log4j执行性能
- 将内存扩大缩小的函数 realloc(){}
- Hadoop源码分析笔记(一):Hadoop Configuration详解
- 四种解析XML文档的方法详解(介绍+优缺点比较+示例)
- myeclipse8.6安装svn插件
- 路径查找脚本pathfind (shell)
- 网络异步请求(1)
- MFC中鼠标事件=onMouse
- 计算日志中的时间段重合时间差,适合时长计算
- Windows 8.1(Windows Blue)新特性
- 前端结构解析系列之一:汉堡式结构