在用Hadoop框架处理大数据时使用最多就是HDFS--分布式文件系统,但Hadoop的文件系统不仅只有分布式文件系统,例如:hfs,HSFTP,HAR等在Hadoop中都是有集成的,用来处理存储在不同体系中的数据。事实上应该这么说,Hadoop其实是一个综合性的文件系统。
下面来看看文件系统的结构体系
当然上面的UML图解事实上有些冗余,但是为了能清楚的表达fs这个体系中的成员,我尽量把所有的成员罗列了进来。在Hadoop的文件系统体系中FileSystem是其他成员的父类,它是一个抽象类,旨在通过它来定义一个访问文件系统的标准,在Hadoop框架中的其他组件在使用到文件系统时只认识FileSystem类提供的标准,所以如果自己在定义一个文件系统是定要按照这个标准来(当然,说说而已,我也没尝试过),面对抽象编程在我看来就是按照某些标准来编程。至于在FileSystem的子类中,到底仅仅是实现了抽象的方法,还是同时也重写了父类的方法,我觉得不重要,最重要的是明白这种设计思想。
在使用文件系统是一般的通过FileSystem.get (Configuration conf)或者是FileSystem.get (URI uri,Configuration conf)来获取文件系统的实例,这两种方法时高度一致的,我们来看看源码
public static FileSystem get(URI uri, Configuration conf) throws IOException {
String scheme = uri.getScheme();
String authority = uri.getAuthority();
if (scheme == null) { // no scheme: use default FS
return get(conf);
}
if (authority == null) { // no authority
URI defaultUri = getDefaultUri(conf);
if (scheme.equals(defaultUri.getScheme()) // if scheme matches default
&& defaultUri.getAuthority() != null) { // & default has authority
return get(defaultUri, conf); // return default
}
}
String disableCacheName = String.format("fs.%s.impl.disable.cache", scheme);
if (conf.getBoolean(disableCacheName, false)) {
return createFileSystem(uri, conf);
}
return CACHE.get(uri, conf);
}
/** Returns the configured filesystem implementation.*/
public static FileSystem get(Configuration conf) throws IOException {
return get(getDefaultUri(conf), conf);
}
public static URI getDefaultUri(Configuration conf) {
return URI.create(fixName(conf.get(FS_DEFAULT_NAME_KEY, "file:///")));
}
在调用FileSystem.get (Configuration conf)的时候,事实上还是调用了FileSystem.get (URI uri,Configuration conf),使用FileSystem.get (Configuration conf)来获取文件系统的实例时会去读取配置文件core-site.xml中键fs.default.name对应的value,如果不存在该项配置,默认使用的file:///也就是本地文件系统。使用FileSystem.get(conf) 方法时,会去读取配置文件,这样在后期更换文件系统时就很方便了。当然使用FileSystem.get (uri,conf)时也可以很好的实现后期文件系统的修改,直接在程序运行时加入参数就行了。现在剩下的问题就落在FileSystem.get (uri,conf)的头上了,大权握在它的手上了。来看看通过这个方法是怎么得到具体的文件系统实例的,在验证uri的结构完整后,通过createFileSystem(uri, conf)来返回FileSystem的实例,在CACHE.get(uri, conf)方法的内部同样也会调用createFileSystem(uri, conf),那么问题就落在了这个方法上了,下面来看看createFileSystem(uri, conf)的源码,就明白了是怎么回事了
private static FileSystem createFileSystem(URI uri, Configuration conf
) throws IOException {
Class clazz = conf.getClass("fs." + uri.getScheme() + ".impl", null);
LOG.debug("Creating filesystem for " + uri);
if (clazz == null) {
throw new IOException("No FileSystem for scheme: " + uri.getScheme());
}
FileSystem fs = (FileSystem)ReflectionUtils.newInstance(clazz, conf);
fs.initialize(uri, conf);
return fs;
}
这下就明了了,Class clazz = conf.getClass("fs." + uri.getScheme() + ".impl", null);通过读取core-default.xml中fs.[scheme].impl的value值来得到FileSystem实现类的字节码文件,有了Class文件其他的事情就好说了,此时相当于是把整个类的所有细节都暴露给programmer了,通过反射技术操作Class从而就得到了文件系统的实例。下面是core-default.xml中关于这部分的配置片段
fs.file.impl
org.apache.hadoop.fs.LocalFileSystem
The FileSystem for file: uris.
fs.hdfs.impl
org.apache.hadoop.hdfs.DistributedFileSystem
The FileSystem for hdfs: uris.
fs.s3.impl
org.apache.hadoop.fs.s3.S3FileSystem
The FileSystem for s3: uris.
fs.s3n.impl
org.apache.hadoop.fs.s3native.NativeS3FileSystem
The FileSystem for s3n: (Native S3) uris.
fs.kfs.impl
org.apache.hadoop.fs.kfs.KosmosFileSystem
The FileSystem for kfs: uris.
fs.hftp.impl
org.apache.hadoop.hdfs.HftpFileSystem
fs.hsftp.impl
org.apache.hadoop.hdfs.HsftpFileSystem
fs.webhdfs.impl
org.apache.hadoop.hdfs.web.WebHdfsFileSystem
fs.ftp.impl
org.apache.hadoop.fs.ftp.FTPFileSystem
The FileSystem for ftp: uris.
fs.ramfs.impl
org.apache.hadoop.fs.InMemoryFileSystem
The FileSystem for ramfs: uris.
fs.har.impl
org.apache.hadoop.fs.HarFileSystem
The filesystem for Hadoop archives.
在上面的文件系统体系图中有三处被标记的类,下面通过这三个类来说说文件系统能否支持验证检验和的设置。什么是检验和?检验和是在文件写入或者是读取阶段用来验证数据大小是否存在差池的数据统计信息(姑且这么说),检验和的作用主要是保证数据的完整性。在hadoop中保证数据的完整性就是通过读写时对检验和的验证来实现。在hadoop的FS中,不是所有的底层文件系统都支持验证检验和的。通过LocalFileSystem和RawLocalFileSystem来说明什么样的底层文件系统支持验证检验和。
LocalFileSystem是一个支持验证检验和的文件系统
public LocalFileSystem() {
this(new RawLocalFileSystem());
}
public FileSystem getRaw() {
return rfs;
}
public LocalFileSystem(FileSystem rawLocalFileSystem) {
super(rawLocalFileSystem);
rfs = rawLocalFileSystem;
}
上面是LocalFileSystem的构造函数,从构造函数可以看出,LocalFileSystem底层使用就是RawLocalFileSystem(不支持验证检验和),在这里应该可以看出此处使用的设计模式中的装饰模式。
从图中可以看出LocalFileSystem并没直接实现FileSystem,并且在hadoop权威指南中这样说的在hadoop的FS中继承了ChecksumFileSystem的FS才具有验证检验和的能力,不难想象,验证和的功能是在FilterFileSystem中完成的。看看源码就知道这种设计模式是策略模式,FilterFileSystem只对继承了FileSystem的类感兴趣。下面简单的看下ChecksumFileSystem和FilterFileSystem的构造函数。
ChecksumFileSystem
public ChecksumFileSystem(FileSystem fs) {
super(fs);
}
FilterFileSystem
protected FileSystem fs;
/*
* so that extending classes can define it
*/
public FilterFileSystem() {
}
public FilterFileSystem(FileSystem fs) {
this.fs = fs;
this.statistics = fs.statistics;
}
从上面的三个类构造函数可以看出,RawLocalFileSystem的实例最终存储在FilterFileSystem的protected字段FileSystem fs中,然后调用FilterFileSystem的访问文件系统的相关方法实际上最后都避免不了调用字段fs对应的方法。so,hadoop中的FS继承了ChecksumFileSystem的就具有验证检验和的能力,例如还有InMemoryFileSystem也支持验证检验和。那么对于hadoop中其他的没有继承ChecksumFileSystem的文件系统该怎么支持验证检验和?从checkSumFileSystem和FilterFileSystem的构造函数不能看出,将任何一个继承了FileSystem的类包装下就可以实现验证检验和的功能。如想对DistributedFileSystem的实例添加验证检验和的能力,使用 new ChecksumFileSystem(dfs)就ok了,我把ChecksumFileSystem这个类称作文件系统的外套,披上了这层外套文件系统就变得更加强壮。
以上的内容是对自己学习hadoop的阶段总结,我在这里抛砖引玉,有错误的地方希望大家帮忙指出哈。
运维网声明
1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网 享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com