Hadoop源码分析(一)——hdfs-client(2)

hadoop

2017-05-04

564

0

一、代码分析

通过执行代码来分析,hdfs-client在我们操作hdfs的文件时,做了些什么。

1、初始化Hdfs-Client

URI uri = URI.create("hdfs://172.16.38.159:8020");
Configuration conf = new Configuration();
FileSystem fileSystem = new DistributedFileSystem();
fileSystem.initialize(uri, conf);

(1)Configuration

Configuration中的内部类
Resource:resource模型,有两个属性,Object resource 和String name。
DeprecatedKeyInfo:此类保留有关替换已弃用的key的信息也存储替换不推荐使用的键的新密钥,并且还提供了为每个被替换的不推荐使用的密钥提供自定义消息的规定。
它还提供了获得适当的方法,每当使用不推荐使用的密钥时,可以记录警告消息。
DeprecationDelta:存放已经弃用的key。
DeprecationContext:所有被弃用的key的合集。
NegativeCacheSentinel:一个独特的类,用作缓存中的哨兵

当new Configuration时,初始化一些属性,同时清空已经注册的Configuration。
在Configuration这个类中,有一个静态块,会调用addDefaultResource("core-default.xml")和addDefaultResource("core-site.xml")方法
来清空已经注册的Configuration。

public static synchronized void addDefaultResource(String name) {
    if(!defaultResources.contains(name)) {
      defaultResources.add(name);
      for(Configuration conf : REGISTRY.keySet()) {
        if(conf.loadDefaults) {
          conf.reloadConfiguration();
        }
      }
    }
  }

defaultResources:类型为线程安全的CopyOnWriteArrayList, 存储配置文件的文件名,防止重复加载。
最后遍历REGISTRY集合中的Configuration,如果标识为加载默认值,则通过reloadConfiguration()方法清空conf里的属性。

Configuration的构造方法

public Configuration() {
    this(true);
  }
 public Configuration(boolean loadDefaults) {
    this.loadDefaults = loadDefaults;//标识是否加载默认配置
    updatingResource = new ConcurrentHashMap<String, String[]>();//用于存储最近修改或最近的key
    synchronized(Configuration.class) {
      REGISTRY.put(this, null);//是一个存储Configuration Object 的WeakHashMap集合
    }
  }

loadDefaults 标识是否加载默认配置
updatingResource 用于存储最近修改或最近的key
REGISTRY 是一个存储Configuration Object 的WeakHashMap集合

(2)DistributedFileSystem

DistributedFileSystem继承了FileSystem,FileSystem是一个抽象类,继承了Configured和Closeable接口。

FileSystem的内部类

Cache:缓存FileSystem对象,Cache里面又有两个内部类,分别是Key和ClientFinalizer,Key作为缓存FileSystem的key,ClientFinalizer是继承Runnable的新线程,调用closeAll(true)方法来终结缓存。

Statistics:跟踪有关在FileSystem中完成了多少读取,写入等的统计信息。由于每个FileSystem只有一个对象,所以通常会有很多线程写入此对象。 打开文件中的每个操作几乎都将涉及到此对象的写入。 相比之下,大多数程序的读取统计数据很少,而不是其他程序。 因此,这是针对写入进行了优化的。 每个线程都会写入自己的线程局部内存区域。 这消除了争用,并允许我们扩展到许多线程。 要读取统计信息,Reader线程总计了所有线程本地数据区域的内容。

new DistributedFileSystem之后并没有做过多的初始化,需要调用initialize(uri, conf)方法来对DistributedFileSystem进行初始化。

FileSystem fileSystem = new DistributedFileSystem();
fileSystem.initialize(uri, conf);

initialize(uri, conf)方法会调用父类FileSystem的initialize(uri, conf)。在FileSystem中调用getStatistics(final String scheme,Class<? extends FileSystem> cls)方法来初始化Statistics类,获取文件系统的统计信息。之后 new DFSClient(uri, conf, statistics)。

(3)、DFSClient

DFSClient可以连接到Hadoop文件系统并执行基本的文件任务。 它使用ClientProtocol与NameNode守护程序通信,并直接连接到DataNodes以读/写块数据。

 

 

转载请注明出处: http://www.julyme.com/20170504/86.html

发表评论

全部评论:0条

Julyme

感觉还行吧。

Julyme的IT技术分享



/sitemap