`

Hadoop-commons分析

 
阅读更多

 

hadoop的配置文件相关类 Configuration

所有大型的系统都有一套自己的配置系统或模块,用于方便系统扩展用,hadoop有自己独立的一套配置方式

采用XML文件,使用SAX解析

配置文件my-config.xml格式

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
	<property>
		<name>name</name>
		<value>Girls Generation</value>
		<final>true</final>
		<description>The boys~</description>
	</property>
</configuration>

 

可以加载多个配置文件如:

Configuration cfg = new Configuration();
cfg.addResource(new URL("http://mytest.com/hadoop.xml"));
cfg.addResource(new FileInputStream("/data0/test/hadoop.xml"));
cfg.addResource(new Path("hdfs://hadoop-test/data/test.xml"));
cfg.addResource("mytest.xml");

如果第一个配置文件f1.xml中的age字段是final的,则不会被第二个文件f2.xml中同名的元素覆盖;

反之则会覆盖

 

Configuration类的静态代码块中显示加载了hadoop相关的几个xml文件,都是通过类加载方式加载的

  static{
    //print deprecation warning if hadoop-site.xml is found in classpath
    ClassLoader cL = Thread.currentThread().getContextClassLoader();
    if (cL == null) {
      cL = Configuration.class.getClassLoader();
    }
    addDefaultResource("core-default.xml");
    addDefaultResource("core-site.xml");
  }

 

加载配置是延迟加载的,会优先加载hadoop相关的XML文件,然后才是自定义的XML文件

  private void loadResources(Properties properties,
                             ArrayList resources,
                             boolean quiet) {
    if(loadDefaults) {
      for (String resource : defaultResources) {
        loadResource(properties, resource, quiet);
      }
    
      //support the hadoop-site.xml as a deprecated case
      if(getResource("hadoop-site.xml")!=null) {
        loadResource(properties, "hadoop-site.xml", quiet);
      }
    }
    
    for (Object resource : resources) {
      loadResource(properties, resource, quiet);
    }
  }

 

配置文件支持表达式的方式

	<property>
		<name>hadoop.tmp.dir</name>
		<value>/data0/hadoop/tmp</value>
	</property>

	<property>
		<name>dir</name>
		<value>${hadoop.tmp.dir}/data</value>
	</property>

而表达式可以嵌套,${path1}又引用了${path2},path2又引用了${path3}

这个嵌套深度最多是20次

表达式可以写在配置文件中,也可以在启动时通过 -D 参数传入

 

此外还有一个接口Configurable,实现了这个接口的类都表示可以配置的

public interface Configurable {
  /** Set the configuration to be used by this object. */
  void setConf(Configuration conf);
  /** Return the configuration used by this object. */
  Configuration getConf();
}

 

 

 

 

hadoop的序列化

关于序列化有三种作用:

1.作为一种持久化格式,比如对象编码后存储到磁盘上

2.作为一种通信数据格式,将一个虚拟机上的对象通过网络传输到另一个虚拟机上

3.作为一种拷贝克隆机制,将对象序列化到内存中再反序列化读取

hadoop有自己的序列化机制,它主要用来解决1)和2)两种情况的,hadoop序列化使用方式

	public void run() throws IOException {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		DataOutputStream dos = new DataOutputStream(baos);
		IntWritable iw = new IntWritable(9527);
		iw.write(dos);
		dos.close();
                System.out.println(new String(baos.toByteArray()));
      }

 

而IntWritable的write()函数很简单

  public void write(DataOutput out) throws IOException {
    out.writeInt(value);
  }

 

DataOutputStream的write实际上就是把int分别按位取然后跟0xFF做与运算,最后写入

    public final void writeInt(int v) throws IOException {
        out.write((v >>> 24) & 0xFF);
        out.write((v >>> 16) & 0xFF);
        out.write((v >>>  8) & 0xFF);
        out.write((v >>>  0) & 0xFF);
        incCount(4);
    }

  

 

 

Writable相关的类图


 

Writable的子类

 

序列化类中还有一个可变长度vint和vlong,vint具体实现是用vlong去做的,可变长度vlong可以有效节省空间 

可变长度vlong的写入源码

  public static void writeVLong(DataOutput stream, long i) throws IOException {
    if (i >= -112 && i <= 127) {
      stream.writeByte((byte)i);
      return;
    }
      
    int len = -112;
    if (i < 0) {
      i ^= -1L; // take one's complement'
      len = -120;
    }
      
    long tmp = i;
    while (tmp != 0) {
      tmp = tmp >> 8;
      len--;
    }
      
    stream.writeByte((byte)len);
      
    len = (len < -120) ? -(len + 120) : -(len + 112);
      
    for (int idx = len; idx != 0; idx--) {
      int shiftbits = (idx - 1) * 8;
      long mask = 0xFFL << shiftbits;
      stream.writeByte((byte)((i & mask) >> shiftbits));
    }
  }

  

可变长度vlong的读取源码

  public static long readVLong(DataInput stream) throws IOException {
    byte firstByte = stream.readByte();
    int len = decodeVIntSize(firstByte);
    if (len == 1) {
      return firstByte;
    }
    long i = 0;
    for (int idx = 0; idx < len-1; idx++) {
      byte b = stream.readByte();
      i = i << 8;
      i = i | (b & 0xFF);
    }
    return (isNegativeVInt(firstByte) ? (i ^ -1L) : i);
  }

  public static int decodeVIntSize(byte value) {
    if (value >= -112) {
      return 1;
    } else if (value < -120) {
      return -119 - value;
    }
    return -111 - value;
  }

  public static boolean isNegativeVInt(byte value) {
    return value < -120 || (value >= -112 && value < 0);
  }

 

hadoop针对java的基本类型,字符串,枚举,Writable,空值等提供了一个ObjectWritable类,可以写入多种类型,这个类也适用于远程过程调用(RPC) 

ObjectWritable#writObject源码,就是先写入这个类的名称,然后判断类中的变量是数组,枚举还是普通类型,然后再依次写入到流中

  public static void writeObject(DataOutput out, Object instance,
                                 Class declaredClass, 
                                 Configuration conf) throws IOException {

    if (instance == null) {                       // null
      instance = new NullInstance(declaredClass, conf);
      declaredClass = Writable.class;
    }

    UTF8.writeString(out, declaredClass.getName()); // always write declared

    if (declaredClass.isArray()) {                // array
      int length = Array.getLength(instance);
      out.writeInt(length);
      for (int i = 0; i < length; i++) {
        writeObject(out, Array.get(instance, i),
                    declaredClass.getComponentType(), conf);
      }
      
    } else if (declaredClass == String.class) {   // String
      UTF8.writeString(out, (String)instance);
      
    } else if (declaredClass.isPrimitive()) {     // primitive type

      if (declaredClass == Boolean.TYPE) {        // boolean
        out.writeBoolean(((Boolean)instance).booleanValue());
      } else if (declaredClass == Character.TYPE) { // char
        out.writeChar(((Character)instance).charValue());
      } else if (declaredClass == Byte.TYPE) {    // byte
        out.writeByte(((Byte)instance).byteValue());
      } else if (declaredClass == Short.TYPE) {   // short
        out.writeShort(((Short)instance).shortValue());
      } else if (declaredClass == Integer.TYPE) { // int
        out.writeInt(((Integer)instance).intValue());
      } else if (declaredClass == Long.TYPE) {    // long
        out.writeLong(((Long)instance).longValue());
      } else if (declaredClass == Float.TYPE) {   // float
        out.writeFloat(((Float)instance).floatValue());
      } else if (declaredClass == Double.TYPE) {  // double
        out.writeDouble(((Double)instance).doubleValue());
      } else if (declaredClass == Void.TYPE) {    // void
      } else {
        throw new IllegalArgumentException("Not a primitive: "+declaredClass);
      }
    } else if (declaredClass.isEnum()) {         // enum
      UTF8.writeString(out, ((Enum)instance).name());
    } else if (Writable.class.isAssignableFrom(declaredClass)) { // Writable
      UTF8.writeString(out, instance.getClass().getName());
      ((Writable)instance).write(out);

    } else {
      throw new IOException("Can't write: "+instance+" as "+declaredClass);
    }
  }

 

 

hadoop序列化框架

1.Avro

2.Thrift

3.Google protocol Buffer

hadoop自身的简单的序列化框架API(在org.apache.hadoop.io.serializer包中)的类图


 

 

 

 

 

参考

抽象工厂模式-与-工厂方法模式区别

《JAVA与模式》之抽象工厂模式

 

  • 大小: 11.5 KB
  • 大小: 35.8 KB
  • 大小: 45.5 KB
分享到:
评论

相关推荐

    hadoop-2.10.0jar.zip

    commons-beanutils-1.9.4.jar commons-cli-1.2.jar commons-codec-1.4.jar commons-collections-3.2.2.jar commons-compress-1.19.jar commons-configuration-1.6.jar commons-digester-1.8.jar commons-io-2.4.jar ...

    hadoop-3.1.4.tar.zip

    5. **lib目录**:包含了Hadoop运行所需的第三方库和依赖,例如Apache Commons库,Zookeeper库等。 6. **share目录**:共享资源,包括文档、JavaDoc和示例。 7. **sbin目录**:系统级别的脚本,用于管理Hadoop集群...

    flink-shaded-hadoop-3-uber-3.1.1.7.1.1.0-565-9.0.jar

    Flink-1.11.2与Hadoop3集成JAR包,放到flink安装包的lib目录下,可以避免Caused by: org.apache.flink.core.fs.UnsupportedFileSystemSchemeException: Hadoop is not in the classpath/dependencies.这个报错,实现...

    ant打包hadoop-eclipse-plugin

    在编译之前,你需要确保 `%HADOOP_HOME%\build\ivy\lib\Hadoop\common` 目录下有`commons-cli-1.2.jar`,并且 `%HADOOP_HOME%\build` 目录下有`hadoop-core-1.0.4.jar`。这些是构建过程中必需的库文件。 现在,你...

    flink-shaded-hadoop-2-uber-2.7.5-10.0.jar

    5. `digesterRules.xml`:可能涉及到 Apache Commons Digester,这是一个解析 XML 文档并基于规则执行对象实例化的工具,常用于构建配置驱动的应用程序。 6. `javax` 目录:这可能是 Hadoop 集成的 javax.* 库,...

    hadoop-core-0.20.2-cdh3u3.jar

    export CLASSPATH="$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:${HADOOP_HOME}/lib/commons-logging-1.0.4.jar:${HADOOP_HOME}/lib/guava-r09-jarjar.jar:${HADOOP_HOME}/hadoop-core-0.20.2-cdh3u3.jar:/usr/...

    hadoop-eclipse-plugin-1.1.2.jar

    ${hadoop.root}/build/ivy/lib/Hadoop/common/commons-cli-${commons-cli.version}.jar" todir="${build.dir}/lib" verbose="true"/&gt; 改成 ${hadoop.root}/hadoop-core-${version}.jar" tofile="${build.dir}/lib/...

    hadoop-eclipse-plugin-1.2.0.jar

    其他hadoop-eclipse-plugin都是盖的,真正解决 An internal error occurred during: ... org/apache/commons/configuration/Configuration 注意版本为:hadoop 1.2.0 eclipse Version: Mars.1 Release (4.5.1)

    hadoop-eclipse-插件编译方法

    Bundle-ClassPath: classes/, lib/hadoop-core.jar, lib/commons-cli-1.2.jar, lib/commons-httpclient-3.0.1.jar, lib/jackson-core-asl-1.8.8.jar, lib/jackson-mapper-asl-1.8.8.jar, lib/commons-configuration...

    flume-hadoop-jar.zip

    Flume要想将数据输出到HDFS,必须持有Hadoop相关jar包:commons-configuration-1.6.jar、 hadoop-auth-2.7.2.jar、 hadoop-common-2.7.2.jar、 hadoop-hdfs-2.7.2.jar、 commons-io-2.4.jar、 htrace-core-...

    hadoop 依赖的jar包 包括asm-3.2什么的 一共21 个

    1.0.15 commons-digester-2.1 commons-el-1.0 commons-httpclient-3.1 commons-io-2.4 commons-lang-2.6 commons-logging-1.2 commons-logging-api-1.1 commons-math3-3.6.1 commons-net-3.3 core-3.1.1 hadoop-...

    hadoop-compile-depend.zip

    这些依赖涵盖了各种库、工具和其他开源项目,如Apache Commons、Zookeeper、protobuf等,它们为Hadoop提供了网络通信、序列化、配置管理等功能支持。 1. **依赖环境**:Hadoop的编译环境通常要求Java开发环境(JDK...

    htrace\hadoop\commons.jar

    htrace-core-3.0.4.jar\hadoop-hdfs-nfs-2.6.0 (1).jar hadoop-nfs\hadoop-hdfs\hadoop-common\hadoop-auth\hadoop-clientcommons-daemon-1.0.13.jar commons-configuration-1.6.jar

    hadoop 2.0.6的Eclipse插件

    commons-cli-1.2.jar commons-configuration-1.6.jar commons-httpclient-3.1.jar commons-lang-2.5.jar commons-logging-1.1.1.jar guava-11.0.2.jar hadoop-auth-2.0.6-alpha.jar hadoop-common-2.0.6-alpha.jar ...

    xwiki-commons-tool-xar-plugin-3.2.zip

    【标题】"xwiki-commons-tool-xar-plugin-3.2.zip" 提供的是XWiki Commons工具中的XAR插件,版本为3.2。这个插件是针对XWiki平台的一个扩展,它允许用户打包和部署XWiki内容以及相关的应用程序为XAR(XWiki Archive...

    PyPI 官网下载 | qctrl-commons-2.5.7.tar.gz

    **PyPI 官网下载 | qctrl-commons-2.5.7.tar.gz** 这个压缩包文件"qctrl-commons-2.5.7.tar.gz"来源于Python的官方软件仓库PyPI(Python Package Index),它是Python开发者发布和分享自己软件包的平台。"qctrl-...

    hadoop1.1.2 eclipse 插件

    ${hadoop.root}/build/ivy/lib/Hadoop/common/commons-cli-${commons-cli.version}.jar" todir="${build.dir}/lib" verbose="true"/&gt; ${hadoop.root}/build/hadoop-core-${version}.jar" tofile="${build.dir}/lib/...

    w7中编辑hadoop-2.6.4后的bin和lib的压缩包

    例如,它可能包含了Apache Commons库、Zookeeper客户端库、protobuf编解码库等。当你在Windows 7环境下编辑这个目录,可能是在为特定环境添加或替换某些JAR文件,以解决兼容性问题或引入特定功能。例如,你可能需要...

    集群环境下hdfs jar包

    最后,`commons-configuration-1.6.jar`是Apache Commons Configuration库,它提供了一种灵活的方式来管理和解析配置文件,对Hadoop的配置管理非常有用。 这些jar包的结合使用,构建了一个完整的HDFS集群环境,可以...

    访问hdfs用到的客户端jar包

    5. **commons-math3-3.1.1.jar**:Apache Commons Math库,用于数学和统计计算,可能在HDFS的某些算法中使用。 6. **htrace-core-3.1.0-incubating.jar**:HTrace是Hadoop的分布式跟踪系统,用于监控和诊断性能问题...

Global site tag (gtag.js) - Google Analytics