Ozone作为同样隶属于Hadoop大数据生态圈的一个系统,尽管它提供的是K-V对象存储能力,但是它和其它现有的Hadoop生态圈组件之间的结合使用依然十分重要。比如说Ozone是否能够支持Hive,Spark应用程序的文件读写呢?但是用户Job,Spark程序是以FileSystem的方式做文件的读写的,而Ozone是K-V形式。假设Ozone能够Hadoop兼容性的FileSystem方式对外提供访问操作,在底层还是Ozone的存储形式不变,这样不就能够很好的解决现有Job程序,Spark程序的数据访问问题嘛,本文笔者就来聊聊这个有意思的主题。Ozone内部实现了基于Ozone的Hadoop FileSystem,叫做Ozone FileSystem,简写为Ozfs。此篇内容笔者将只会介绍怎么配置使用Ozone FileSystem,后面再介绍其原理实现内容。
这里简单介绍Ozone FileSystem的工作原理。对于外部应该程序包(包含用户Job,Spark Job)来说,它们如果在不改变原有通过FileSystem的方式的情况下是不能够访问Ozone的数据的。不过Hadoop在这里提供了一个Hadoop Compatible FileSystem的概念,意为Hadoop兼容性文件系统,简称为HCFS。在这个抽象的FileSystem内,定义了作为文件系统而言最基本的API操作方法。有了这个最最的基本文件系统定义之后,后续上层的应用系统基于自身系统的存储设计实现这样的Hadoop兼容文件系统。
目前HDFS中默认使用的DistributedFileSystem和ViewFs模式下的ViewFileSystem都是底层Hadoop FileSystem的子类。
Ozone在这里实现了OzoneFileSystem类,它的一个主要原理是将所有的namespace操作都限定在了一个bucket内。简单地来说,OzoneFileSystem用一个现有的bucket,作为这个文件系统的root目录。后续的创建文件,目录行为如下:
这里如果大家还是不太理解,没有关系,笔者在后续的例子中还会进行具体文件目录创建的演示。
下面来正式介绍Ozone FileSystem的配置使用了。这里笔者使用的是Hadoop Client进行文件的测试,用hadoop fs下的命令。hadoop fs命令触发的代码操作中会进行实际FileSystem的实例初始化以及后续的操作访问。
因此这里首先我们要下载到一个完整的Hadoop按照包,比如笔者使用的Hadoop-2.7版本的按照包。
然后进入hadoop配置目录,
cd $HADOOP_HOME/etc/hadoop
在此目录的core-site.xml文件中添加如下Ozone FileSystem相关配置,
<configuration>
<property>
<name>fs.o3fs.impl</name>
<value>org.apache.hadoop.fs.ozone.BasicOzoneFileSystem</value>
</property>
<property>
<name>fs.AbstractFileSystem.o3fs.impl</name>
<value>org.apache.hadoop.fs.ozone.OzFs</value>
</property>
<property>
<name>fs.defaultFS</name>
<value>o3fs://buckettest.volumetest</value>
</property>
</configuration>
然后在hadoop-env.sh环境变量配置中新增Hadoop ClassPath的配置,因为Hadoop安装包中并没有OzoneFileSystem的实现类,它是实现在Ozone的工程包内的,我们要将包含OzoneFileSystem的jar路径加到Hadoop ClassPath下。
笔者测试环境中的Ozone按照包路径为
/home/hdfs/ozone
因此笔者将ozone-filesytem的lib jar引入到Hadoop ClassPath下,此处编辑的文件是Hadoop安装包内的hadoop-env.sh。
export HADOOP_CLASSPATH=/home/hdfs/ozone/share/ozone/lib/hadoop-ozone-filesystem-lib-legacy-0.5.0-SNAPSHOT.jar:$HADOOP_CLASSPATH
针对不同版本的Hadoop,所需要的ozone lib filesystem并不完全一致。它有legacy和current两jar,Ozone社区给出了下面的映射规则,注意这里的OzoneFileSystem也是有区别的。
Hadoop version | Required jar | OzoneFileSystem implementation (fs.o3fs.impl的配置使用值) |
---|---|---|
3.2 | filesystem-lib-current | org.apache.hadoop.fs.ozone.OzoneFileSystem |
3.1 | filesystem-lib-legacy | org.apache.hadoop.fs.ozone.OzoneFileSystem |
2.9 | filesystem-lib-legacy | org.apache.hadoop.fs.ozone.BasicOzoneFileSystem |
2.7 | filesystem-lib-legacy | org.apache.hadoop.fs.ozone.BasicOzoneFileSystem |
低于2.7版本的Hadoop version,同样适用于上面2.7 version的映射规则。笔者测试使用的按照包是Hadoop-2.7,因此笔者在这里配置使用的是legacy+BasicOzoneFileSystem的值。
到了这里,我们对于Hadoop的配置已经完毕,后续是Ozone这边的初始化操作了。上面也说看OzoneFileSystem是采用Ozone中的一个bucket作为根目录的。因此我们要事先在Ozone中创建好这个bucket。这个bucket的volume和bucket名称会被传入fs.defaultFS作为使用值,如刚刚的配置所示:
<property>
<name>fs.defaultFS</name>
<value>o3fs://buckettest.volumetest</value>
</property>
笔者在测试环境中已经事先建好了volume为volumetest,其下bucket为buckettest的bucket。
OK,到了这里,Ozone FileSystem的配置宣告结束,后面是具体的操作使用了。
下面是笔者在测试环境中以bucket /volumetest/buckettest为root目录的测试,这里笔者以带schema的路径方式进行访问。不过如果在fs.defaultFS已经配置完整了schema,这部分可以在使用时省略。
首先通过ozone sh命令查看现有buckettest的key文件,文件如下,就一个testfile文件(因为测试环境中笔者开启了OM HA,因此需要带上om service id的模式访问),
[hdfs@lyq hadoop]$ /home/hdfs/ozone/bin/ozone sh key list o3://om-service-test/volumetest/buckettest/
{
"volumeName" : "volumetest",
"bucketName" : "buckettest",
"name" : "testfile",
"dataSize" : 12,
"creationTime" : "2020-01-19T15:20:06.493Z",
"modificationTime" : "2020-01-19T15:20:12.071Z",
"replicationType" : "RATIS",
"replicationFactor" : 3
}
这个key文件在hadoop fs -ls中被显示为根目录下的一个文件,
[hdfs@lyq hadoop]$ /apache/releases/hadoop-2.7/bin/hadoop fs -ls o3fs://buckettest.volumetest.lyq-m2-xx.xx.xx.xx/
Found 1 items
-rw-rw-rw- 3 hdfs hdfs 12 2020-01-19 08:20 o3fs://buckettest.volumetest.lyq-m2-xx.xx.xx.xx/testfile
lyq-m2-xx.xx.xx.xx信息为OM服务所在的hostname,端口号不填的情况下则使用的是默认9862的端口,如果hostname不填,则会查找本地OM服务。
然后我们通过hadoop fs命令进行目录以及二级子目录的创建,
[hdfs@lyq hadoop]$ /apache/releases/hadoop-2.7/bin/hadoop fs -mkdir o3fs://buckettest.volumetest.lyq-m2-xx.xx.xx.xx/testdir
[hdfs@lyq ~]$ /apache/releases/hadoop-2.7/bin/hadoop fs -mkdir o3fs://buckettest.volumetest.lyq-m2-xx.xx.xx.xx/testdir/subdir
[hdfs@lyq hadoop]$ /apache/releases/hadoop-2.7/bin/hadoop fs -ls o3fs://buckettest.volumetest.lyq-m2-xx.xx.xx.xx/
Found 2 items
drwxrwxrwx - hdfs hdfs 0 2020-01-30 07:42 o3fs://buckettest.volumetest.lyq-m2-xx.xx.xx.xx/testdir
-rw-rw-rw- 3 hdfs hdfs 12 2020-01-19 08:20 o3fs://buckettest.volumetest.lyq-m2-xx.xx.xx.xx/testfile
在Ozone中,它们都以key的形式存放在bucket下,区别是value值和key值的不同,
[hdfs@lyq ~]$ /home/hdfs/ozone/bin/ozone sh key list o3://om-service-test/volumetest/buckettest/
{
"volumeName" : "volumetest",
"bucketName" : "buckettest",
"name" : "testdir/",
"dataSize" : 0,
"creationTime" : "2020-01-30T14:39:12.067Z",
"modificationTime" : "2020-01-30T14:39:12.067Z",
"replicationType" : "RATIS",
"replicationFactor" : 1
}
{
"volumeName" : "volumetest",
"bucketName" : "buckettest",
"name" : "testdir/subdir/",
"dataSize" : 0,
"creationTime" : "2020-01-30T14:46:31.687Z",
"modificationTime" : "2020-01-30T14:46:31.687Z",
"replicationType" : "RATIS",
"replicationFactor" : 1
}
{
"volumeName" : "volumetest",
"bucketName" : "buckettest",
"name" : "testfile",
"dataSize" : 12,
"creationTime" : "2020-01-19T15:20:06.493Z",
"modificationTime" : "2020-01-19T15:20:12.071Z",
"replicationType" : "RATIS",
"replicationFactor" : 3
}
如果某个Key在Ozone FS代表的是目录的话,它的key name后会带个’/’,而且data size为0。
当然我们也能在刚刚的创建的目录下再写入文件,
[hdfs@lyq ~]$ /apache/releases/hadoop-2.7/bin/hadoop fs -put testfile o3fs://buckettest.volumetest.lyq-m2-xx.xx.xx.xx/testdir/
Ozone的key list结果如下所示,
[hdfs@lyq ~]$ /home/hdfs/ozone/bin/ozone sh key list o3://om-service-test/volumetest/buckettest/
{
"volumeName" : "volumetest",
"bucketName" : "buckettest",
"name" : "testdir/",
"dataSize" : 0,
"creationTime" : "2020-01-30T14:39:12.067Z",
"modificationTime" : "2020-01-30T14:39:12.067Z",
"replicationType" : "RATIS",
"replicationFactor" : 1
}
{
"volumeName" : "volumetest",
"bucketName" : "buckettest",
"name" : "testdir/testfile",
"dataSize" : 12,
"creationTime" : "2020-01-30T15:37:20.194Z",
"modificationTime" : "2020-01-30T15:37:23.930Z",
"replicationType" : "RATIS",
"replicationFactor" : 3
}
...
此外,OzoneFileSystem还能支持rename和delete操作,
Rename操作,
[hdfs@lyq ~]$ /apache/releases/hadoop-2.7/bin/hadoop fs -mv o3fs://buckettest.volumetest.lyq-m2-xx.xx.xx.xx/testfile o3fs://buckettest.volumetest.lyq-m2-xx.xx.xx.xx/testfile2
[hdfs@lyq ~]$ /apache/releases/hadoop-2.7/bin/hadoop fs -ls o3fs://buckettest.volumetest.lyq-m2-xx.xx.xx.xx/
Found 2 items
drwxrwxrwx - hdfs hdfs 0 2020-01-30 07:53 o3fs://buckettest.volumetest.lyq-m2-xx.xx.xx.xx/testdir
-rw-rw-rw- 3 hdfs hdfs 12 2020-01-30 07:52 o3fs://buckettest.volumetest.lyq-m2-xx.xx.xx.xx/testfile2
Ozone中的此key名字同样马上被更新,
[hdfs@lyq ~]$ /home/hdfs/ozone/bin/ozone sh key list o3://om-service-test/volumetest/buckettest/
...
{
"volumeName" : "volumetest",
"bucketName" : "buckettest",
"name" : "testfile2",
"dataSize" : 12,
"creationTime" : "2020-01-19T15:20:06.493Z",
"modificationTime" : "2020-01-30T14:52:43.563Z",
"replicationType" : "RATIS",
"replicationFactor" : 3
}
Delete删除操作,无trash保留,直接清除,
[hdfs@lyq ~]$ /apache/releases/hadoop-2.7/bin/hadoop fs -rm o3fs://buckettest.volumetest.lyq-m2-xx.xx.xx.xx/testfile2
Deleted o3fs://buckettest.volumetest.lyq-m2-xx.xx.xx.xx/testfile2
目前Ozone FileSystem只支持文件数据读写相关的操作,至于其它额外的属性修改操作(例如setrep, chown,setquota等等)暂不支持。
上述命令行的调用方式和用户程序通过Hadoop配置得到Ozone FileSystem实例进行API的调用操作,效果完全一致,程序所需要的配置值的方式同上小节内容所介绍的一致。
本文就是笔者介绍的关于Ozone FileSystem的使用方式,下文笔者将简单其中的原理相关的内容,Ozone是如何基于自身的存储实现设计做Hadoop FileSystem的适配的。
[1]. https://hadoop.apache.org/ozone/docs/0.4.1-alpha/interface/ozonefs.html