基于Hadoop3.2.1--------------------------------------------------------------------------------------------------
利用之前的文章下载hdfs文件底层原始写法代码中,跟踪分析数据源码
文章链接:下载hdfs中的文件(原始写法)
1.首先在FileSystem fs=FileSystem.get(conf);处加断点
2.选中main右键debug as -------Java Application--------显示debug视图
3.此时将鼠标放到本句的conf位置就会显示Configuration: core-default.xml, core-site.xml 表示它会读取这些配置文件
注:为了方便下面的过程,需要先下载Hadoop源码,并解压
tar -zxvf hadoop-3.2.1-src.tar.gz -C app/
再将其压缩为zip
[centosdvd@weekend110 app]$ zip -r hadoop-3.2.1-src.zip hadoop-3.2.1-src
4.按住Ctrl键左键get进入FileSystem.class(抽象类)中一个具体的实现方法get
return get(getDefaultUri(conf), conf); 处加入断点后,Resume(F8)
5.选中getDefaultUri(conf)后Shift+Ctrl+I 显示从conf中获得了什么东西,即hdfs://weekend110:9000
6.按住Ctrl进入这个get,再次加断点后F8可以知道这个Scheme就是hdfs(可由Shift+Ctrl+I方法得到),uri是hdfs://weekend110:9000,authority是主机名加端口号 即 weekend110:9000
7.如果二者均为空会返回一个默认的文件系统,即本地文件系统
8.disableCacheName是一个配置参数,然后从这个参数获得某个值,没有就为false(注:disableCacheName顾名思义禁用缓存,如果为false就表明要用缓存,调用缓存的get,CACHE是一个内部类)
9.进入CACHE的get,,key的内容(centosdvd (auth:SIMPLE))@hdfs://weekend110:9000
10.进入getInternal,,此处map相当于一个缓存的作用
11.进入createFileSystem,clazz就是class org.apache.hadoop.hdfs.DistributedFileSystem,,从conf中得知是DistributedFileSystem,而不是别的。
FileSystem fs = (FileSystem)ReflectionUtils.newInstance(clazz, conf);此句子执行后还是空的为DFS[null]
所以还需要初始化赋值
12.下面进入initialize,但此时按住Ctrl+左键不能选择Open Declaration而是打开Implementation并选择DistributedFileSystem才能到下一个执行的地方
13.DistributedFileSystem中:
① this.dfs = new DFSClient(uri, conf, statistics);
② this.uri = URI.create(uri.getScheme()+"://"+uri.getAuthority());
③ this.workingDir = getHomeDirectory();
①
(1)进入DFSClient后Ctrl O 可以看 DFSClient 的成员,其中namenode ClientProtocol 就是fs和远程都需要实现的那个接口,即fs中有DFSClient,DFSClient中肯定会获取动态代理对象,来获取namenode,即一定有RPC框架的痕迹,去getProxy
(2)this.ugi 是用户身份
(3)ProxyAndInfo<ClientProtocol> proxyInfo = null; 初始为空
proxyInfo = NameNodeProxiesClient.createProxyWithClientProtocol(conf, nameNodeUri, nnFallbackToSimpleAuth);
(4)进入createProxyWithClientProtocol
(5)因为有两个namenode,当其中一个坏了切换的时候客户端也需要适应这种切换,所以就有了failoverProxyProvider,我建立的伪分布式中没有这种切换机制,所以一定是空即会简历非HA case的即createNonHAProxyWithClientProtocol
(6)进入createNonHAProxyWithClientProtocol再进入createProxyWithAlignmentContext
withRetries是重试的机制,一次没连上再次重试
此处getProtocolProxy其实就是之前我们写的getProxy(注意结尾部分)
(7)最后封装一下再返回(因为Hadoop想做通用的序列化,所以再封装一层,使得其他语言如Python写通信的时候可以用与Java无关的序列化机制,所以把java的proxy再封装一层)
(8)一路返回到createProxyWithClientProtocol(第四步)中有下面代码,多了dtService
(9)此时回到 DFSClient中 ,,,,dtService其实就是192.168.184.128:9000
(10)返回到DistributedFileSystem
整个①其实就是在给this.dfs赋值
②uri就是个字符串
③workingDir表示工作目录 -------hdfs://weekend110:9000/user/centosdvd
14.此时createFileSystem中的initialize完成,即DistributedFileSystem实例对象构造完成
15.一路返回到我们的代码中了
我们注意到以上过程仅仅只是一句代码,即FileSystem fs=FileSystem.get(conf);,所以其封装性是很好的
附:大致结构