资源描述
通用大数据存储与分析处理平台
总体建设方案
(Hadoop)
目 录
1 Hadoop 1
1.1 概述 1
1.1.1 Hadoop能做什么 1
1.2 特点 1
1.3 软件设计 1
1.3.1 Hadoop 中的文件格式 1
1.3.2 机架感知 10
1.4 Hadoop知识学习篇 11
1.4.1 RPC 11
1.4.2 Avro、Thrift 11
1.4.3 Java接口 11
1.4.4 FileSystem总结 1
1.4.5 文件读取过程/文件写入过程 4
1.4.6 Hadoop均衡器 1
1.4.7 Hadoop存档 1
1.4.8 数据完整性 3
1.4.9 压缩 4
1.4.10 序列化【优点】 6
1.4.11 序列化框架 11
1.4.12 MapReduce过程中的序列化与反序列化 20
1.4.13 √HDFS数据结构 25
1.4.14 MapReduce框架 26
1.4.15 MapReduce工作机制 39
1.4.16 推测执行【优点】 42
1.4.17 重用JVM【优化】 43
1.4.18 IDS 43
1.4.19 输入格式 43
1.4.20 输出格式 15
1.4.21 计数器 20
1.4.22 √排序技术 24
1.4.23 √连接 33
1.4.24 DistributedCache 38
1.4.25 √作业链接 42
1.4.26 √默认的MapReduce作业 43
1.4.27 集群规范 43
1.4.28 网络拓扑[优点] 44
1.4.29 环境设置 48
1.4.30 守护进程的关键属性 49
1.4.31 安全性 53
1.4.32 安全模式 53
1.4.33 fsck工具 53
1.4.34 日常维护 55
1.5 Hadoop知识总结篇 57
1.5.1 Hadoop通信协议总结 57
1.5.2 通过日志掌握Hadoop运行过程(HDFS/MAPREDUCE) 1
1.5.3 MapReduce配置调优 1
1.5.4 MapReduce过程配置 1
1.6 应用程序运行JOB 2
1.7 Hadoop源码篇 2
2 Accumulo 4
3 海量数据查询支撑分系统 4
3.1 Dremel 4
3.1.1 概述 4
3.1.2 软件设计 5
3.1.3 一句话总结 9
3.2 Drill 9
3.2.1 概述 9
3.3 Tez 10
3.4 Impala*** 14
3.5 Tajo*** 14
3.6 序列化框架与RPC 15
3.6.1 Avro 15
3.6.2 Protocol 15
3.6.3 Thrift 15
3.7 缓存 15
4 算法研究***** 16
4.1 BloomFilter 16
4.1.1 集合表示和元素查询 16
4.1.2 错误率估计 17
4.1.3 最优的哈希函数个数 18
4.1.4 位数组的大小 18
4.1.5 总结 19
4.2 Bit Map(BitSet) 20
4.2.1 Bit Map的基本思想 20
4.2.2 Map映射表 22
4.2.3 位移转换 22
4.2.4 扩展 25
4.2.5 Bit-Map的应用 25
4.2.6 Bit-Map的具体实现 25
4.3 哈希算法 32
4.4 二叉树 43
4.5 堆与堆排序 43
4.6 双层桶划分 49
4.7 trie树 50
4.8 外排序 56
5 海量数据处理思路 58
5.1 Bloom filter 80
5.2 Hashing 81
5.3 bit-map 82
5.4 堆 83
5.5 双层桶划分 83
5.6 数据库索引 84
5.7 倒排索引(Inverted index) 84
5.8 外排序 85
5.9 trie树 86
6 经典博文 88
从Hadoop框架与MapReduce模式中谈海量数据处理 88
6.1.1 前言 88
6.1.2 第一部分、mapreduce模式与hadoop框架深入浅出 88
6.1.3 架构扼要 88
6.1.4 Mapreduce模式 89
6.1.5 Hadoop框架 90
6.1.6 Hadoop的组成部分 90
6.1.7 第二部分、淘宝海量数据产品技术架构解读—学习海量数据处理经验 92
6.1.8 淘宝海量数据产品技术架构 92
mapreduce的二次排序 SecondarySort 95
V
1 Hadoop
1.1 概述
1.1.1 Hadoop能做什么
1、搜索引擎(Doug Cutting 设计Hadoop的初衷,为了针对大规模的网页快速建立索引)。
2、大数据存储,利用Hadoop的分布式存储能力,例如数据备份、数据仓库等。
3、大数据处理,利用Hadoop的分布式处理能力,例如数据挖掘、数据分析等。
4、科学研究,Hadoop是一种分布式的开源框架,对于分布式计算有很大程度地参考价值。
Ø 大数据存储
Ø 海量数据批量处理:
n 排序、连接
n ETL(去重、转化)
n 数据挖掘
n 日志处理
n 用户细分特征建模
n 个性化广告推荐
n 智能仪器推荐
1.2 特点
1. 高可靠性。Hadoop按位存储和处理数据的能力值得人们信赖。
2. 高扩展性。Hadoop是在可用的计算机集簇间分配数据并完成计算任务的,这些集簇可以方便地扩展到数以千计的节点中。
3. 高效性。Hadoop能够在节点之间动态地移动数据,并保证各个节点的动态平衡,因此处理速度非常快。
4. 高容错性。Hadoop能够自动保存数据的多个副本,并且能够自动将失败的任务重新分配。
5. 低成本。与一体机、商用数据仓库以及QlikView、Yonghong Z-Suite等数据集市相比,hadoop是开源的,项目的软件成本因此会大大降低。
1.3 软件设计
1.3.1 Hadoop 中的文件格式
SequenceFile
SequenceFile是Hadoop API 提供的一种二进制文件,它将数据以<key,value>的形式序列化到文件中。这种二进制文件内部使用Hadoop 的标准的Writable 接口实现序列化和反序列化。它与Hadoop API中的MapFile 是互相兼容的。Hive 中的SequenceFile 继承自Hadoop API 的SequenceFile,不过它的key为空,使用value 存放实际的值, 这样是为了避免MR 在运行map 阶段的排序过程。如果你用Java API 编写SequenceFile,并让Hive 读取的话,请确保使用value字段存放数据,否则你需要自定义读取这种SequenceFile 的InputFormat class 和OutputFormat class。
图1:Sequencefile 文件结构
SequenceFile读写实例
private static final String [] DATA =
{
"One,Two,buckle my shoe",
"Three,four,shut the door",
"File,six,pick up sticks",
"Seven,eight,lay them straight",
"Nie,ten,a big fat hen"
};
public static void writeToHDFS(String[] args) throws IOException {
for(int j=1;j<=5;j++)
{
String uri ="hdfs://mylinux:9000/data/exam/seqfiles/seq_"+System.currentTimeMillis();
Configuration conf =new Configuration();
FileSystem fs = FileSystem.get(URI.create(uri),conf);
Path path =new Path(uri);
IntWritable key = new IntWritable();
Text value =new Text();
SequenceFile.Writer writer= null;
writer =SequenceFile.createWriter(fs, conf, path, key.getClass(), value.getClass());
for(int i=0;i<100;i++)
{
key.set((100-i)*j);
value.set(DATA[i%DATA.length]);
writer.append(key, value);
}
}
}
public static void readFromHDFS(String[] args) throws IOException
{
String uri ="hdfs://mylinux:9000/data/exam/seqfiles/seq_1399127337932";
Configuration conf =new Configuration();
FileSystem fs = FileSystem.get(URI.create(uri),conf);
Path path =new Path(uri);
SequenceFile.Reader reader =new SequenceFile.Reader(fs, path, conf);
Writable key =(Writable)ReflectionUtils.newInstance(reader.getKeyClass(),conf);
Writable value =(Writable)ReflectionUtils.newInstance(reader.getValueClass(),conf);
long pos =reader.getPosition();
while(reader.next(key, value))
{
System.out.println(key+"=>"+value);
}
}
RCFile
RCFile是Hive推出的一种专门面向列的数据格式。 它遵循“先按列划分,再垂直划分”的设计理念。当查询过程中,针对它并不关心的列时,它会在IO上跳过这些列。需要说明的是,RCFile在map阶段从远端拷贝仍然是拷贝整个数据块,并且拷贝到本地目录后RCFile并不是真正直接跳过不需要的列,并跳到需要读取的列, 而是通过扫描每一个row group的头部定义来实现的,但是在整个HDFS Block 级别的头部并没有定义每个列从哪个row group起始到哪个row group结束。所以在读取所有列的情况下,RCFile的性能反而没有SequenceFile高。
图2:RCFile 文件结构
3 Avro
Avro是一种用于支持数据密集型的二进制文件格式。它的文件格式更为紧凑,若要读取大量数据时,Avro能够提供更好的序列化和反序列化性能。并且Avro数据文件天生是带Schema定义的,所以它不需要开发者在API 级别实现自己的Writable对象。最近多个Hadoop 子项目都支持Avro 数据格式,如Pig 、Hive、Flume、Sqoop和Hcatalog。
图3:Avro MR 文件格式
4. 文本格式
除上面提到的3种二进制格式之外,文本格式的数据也是Hadoop中经常碰到的。如TextFile 、XML和JSON。 文本格式除了会占用更多磁盘资源外,对它的解析开销一般会比二进制格式高几十倍以上,尤其是XML 和JSON,它们的解析开销比Textfile 还要大,因此强烈不建议在生产系统中使用这些格式进行储存。 如果需要输出这些格式,请在客户端做相应的转换操作。 文本格式经常会用于日志收集,数据库导入,Hive默认配置也是使用文本格式,而且常常容易忘了压缩,所以请确保使用了正确的格式。另外文本格式的一个缺点是它不具备类型和模式,比如销售金额、利润这类数值数据或者日期时间类型的数据,如果使用文本格式保存,由于它们本身的字符串类型的长短不一,或者含有负数,导致MR没有办法排序,所以往往需要将它们预处理成含有模式的二进制格式,这又导致了不必要的预处理步骤的开销和储存资源的浪费。
5. 外部格式
Hadoop实际上支持任意文件格式,只要能够实现对应的RecordWriter和RecordReader即可。其中数据库格式也是会经常储存在Hadoop中,比如Hbase,Mysql,Cassandra,MongoDB。 这些格式一般是为了避免大量的数据移动和快速装载的需求而用的。他们的序列化和反序列化都是由这些数据库格式的客户端完成,并且文件的储存位置和数据布局(Data Layout)不由Hadoop控制,他们的文件切分也不是按HDFS的块大小(blocksize)进行切割。
文件存储大小比较与分析
我们选取一个TPC-H标准测试来说明不同的文件格式在存储上的开销。因为此数据是公开的,所以读者如果对此结果感兴趣,也可以对照后面的实验自行做一遍。Orders 表文本格式的原始大小为1.62G。 我们将其装载进Hadoop 并使用Hive 将其转化成以上几种格式,在同一种LZO 压缩模式下测试形成的文件的大小。
Orders_text1
1732690045
1.61G
非压缩
TextFile
Orders_tex2
772681211
736M
LZO压缩
TextFile
Orders_seq1
1935513587
1.80G
非压缩
SequenceFile
Orders_seq2
822048201
783M
LZO压缩
SequenceFile
Orders_rcfile1
1648746355
1.53G
非压缩
RCFile
Orders_rcfile2
686927221
655M
LZO压缩
RCFile
Orders_avro_table1
1568359334
1.46G
非压缩
Avro
Orders_avro_table2
652962989
622M
LZO压缩
Avro
表1:不同格式文件大小对比
从上述实验结果可以看到,SequenceFile无论在压缩和非压缩的情况下都比原始纯文本TextFile大,其中非压缩模式下大11%, 压缩模式下大6.4%。这跟SequenceFile的文件格式的定义有关: SequenceFile在文件头中定义了其元数据,元数据的大小会根据压缩模式的不同略有不同。一般情况下,压缩都是选取block 级别进行的,每一个block都包含key的长度和value的长度,另外每4K字节会有一个sync-marker的标记。对于TextFile文件格式来说不同列之间只需要用一个行间隔符来切分,所以TextFile文件格式比SequenceFile文件格式要小。但是TextFile 文件格式不定义列的长度,所以它必须逐个字符判断每个字符是不是分隔符和行结束符。因此TextFile 的反序列化开销会比其他二进制的文件格式高几十倍以上。
RCFile文件格式同样也会保存每个列的每个字段的长度。但是它是连续储存在头部元数据块中,它储存实际数据值也是连续的。另外RCFile 会每隔一定块大小重写一次头部的元数据块(称为row group,由hive.io.rcfile.record.buffer.size控制,其默认大小为4M),这种做法对于新出现的列是必须的,但是如果是重复的列则不需要。RCFile 本来应该会比SequenceFile 文件大,但是RCFile 在定义头部时对于字段长度使用了Run Length Encoding进行压缩,所以RCFile 比SequenceFile又小一些。Run length Encoding针对固定长度的数据格式有非常高的压缩效率,比如Integer、Double和Long等占固定长度的数据类型。在此提一个特例——Hive 0.8引入的TimeStamp 时间类型,如果其格式不包括毫秒,可表示为”YYYY-MM-DD HH:MM:SS”,那么就是固定长度占8个字节。如果带毫秒,则表示为”YYYY-MM-DD HH:MM:SS.fffffffff”,后面毫秒的部分则是可变的。
Avro文件格式也按group进行划分。但是它会在头部定义整个数据的模式(Schema), 而不像RCFile那样每隔一个row group就定义列的类型,并且重复多次。另外,Avro在使用部分类型的时候会使用更小的数据类型,比如Short或者Byte类型,所以Avro的数据块比RCFile 的文件格式块更小。
序列化与反序列化开销分析
我们可以使用Java的profile工具来查看Hadoop 运行时任务的CPU和内存开销。以下是在Hive 命令行中的设置:
hive>set mapred.task.profile=true;
hive>set mapred.task.profile.params =-agentlib:hprof=cpu=samples,heap=sites, depth=6,force=n,thread=y,verbose=n,file=%s
当map task 运行结束后,它产生的日志会写在$logs/userlogs/job- 文件夹下。当然,你也可以直接在JobTracker的Web界面的logs或jobtracker.jsp 页面找到日志。
我们运行一个简单的SQL语句来观察RCFile 格式在序列化和反序列化上的开销:
hive> select O_CUSTKEY,O_ORDERSTATUS from orders_rc2 where O_ORDERSTATUS='P';
其中的O_CUSTKEY列为integer类型,O_ORDERSTATUS为String类型。在日志输出的最后会包含内存和CPU 的消耗。
下表是一次CPU 的开销:
rank
self
accum
count
trace
method
20
0.48%
79.64%
65
315554
org.apache.hadoop.hive.ql.io.RCFile$Reader.getCurrentRow
28
0.24%
82.07%
32
315292
org.apache.hadoop.hive.serde2.columnar.ColumnarStruct.init
55
0.10%
85.98%
14
315788
org.apache.hadoop.hive.ql.io.RCFileRecordReader.getPos
56
0.10%
86.08%
14
315797
org.apache.hadoop.hive.ql.io.RCFileRecordReader.next
表2:一次CPU的开销
其中第五列可以对照上面的Track信息查看到底调用了哪些函数。比如CPU消耗排名20的函数对应Track:
TRACE 315554: (thread=200001)
org.apache.hadoop.hive.ql.io.RCFile$Reader.getCurrentRow(RCFile.java:1434)
org.apache.hadoop.hive.ql.io.RCFileRecordReader.next(RCFileRecordReader.java:88)
org.apache.hadoop.hive.ql.io.RCFileRecordReader.next(RCFileRecordReader.java:39)
org.apache.hadoop.hive.ql.io.CombineHiveRecordReader.doNext(CombineHiveRecordReader.java:98)
org.apache.hadoop.hive.ql.io.CombineHiveRecordReader.doNext(CombineHiveRecordReader.java:42)
org.apache.hadoop.hive.ql.io.HiveContextAwareRecordReader.next(HiveContextAwareRecordReader.java:67)
其中,比较明显的是RCFile,它为了构造行而消耗了不必要的数组移动开销。其主要是因为RCFile 为了还原行,需要构造RowContainer,顺序读取一行构造RowContainer,然后给其中对应的列进行赋值,因为RCFile早期为了兼容SequenceFile所以可以合并两个block,又由于RCFile不知道列在哪个row group结束,所以必须维持数组的当前位置,类似如下格式定义:
Array<RowContainer extends List<Object>>
而此数据格式可以改为面向列的序列化和反序列化方式。如:
Map<array<col1Type>,array<col2Type>,array<col3Type>....>
这种方式的反序列化会避免不必要的数组移动,当然前提是我们必须知道列在哪个row group开始到哪个row group结束。这种方式会提高整体反序列化过程的效率。
关于Hadoop文件格式的思考
1 高效压缩
Hadoop目前尚未出现针对数据特性的高效编码(Encoding)和解码(Decoding)数据格式。尤其是支持Run Length Encoding、Bitmap 这些极为高效算法的数据格式。HIVE-2065 讨论过使用更加高效的压缩形式,但是对于如何选取列的顺序没有结论。关于列顺序选择可以看Daniel Lemire的一篇论文 《Reordering Columns for Smaller Indexes》[1]。作者同时也是Hive 0.8中引入的bitmap 压缩算法基础库的作者。该论文的结论是:当某个表需要选取多个列进行压缩时,需要根据列的选择性(selectivity)进行升序排列,即唯一值越少的列排得越靠前。 事实上这个结论也是Vertica多年来使用的数据格式。其他跟压缩有关的还有HIVE-2604和HIVE-2600。
2 基于列和块的序列化和反序列化
不论排序后的结果是不是真的需要,目前Hadoop的整体框架都需要不断根据数据key进行排序。除了上面提到的基于列的排序,序列化和反序列化之外,Hadoop的文件格式应该支持某种基于块(Block) 级别的排序和序列化及反序列化方式,只有当数据满足需要时才进行这些操作。来自Google Tenzing论文中曾将它作为MR 的优化手段提到过。
“Block Shuffle:正常来说,MR 在Shuffle 的时候使用基于行的编码和解码。为了逐个处理每一行,数据必须先排序。然而,当排序不是必要的时候这种方式并不高效,我们在基于行的shuffle基础上实现了一种基于block的shuffle方式,每一次处理大概1M的压缩block,通过把整个block当成一行,我们能够避免MR框架上的基于行的序列化和反序列化消耗,这种方式比基于行的shuffle 快上3倍以上。”
3 数据过滤(Skip List)
除常见的分区和索引之外,使用排序之后的块(Block)间隔也是常见列数据库中使用的过滤数据的方法。Google Tenzing同样描述了一种叫做ColumnIO 的数据格式,ColumnIO在头部定义该Block的最大值和最小值,在进行数据判断的时候,如果当前Block的头部信息里面描述的范围中不包含当前需要处理的内容,则会直接跳过该块。Hive社区里曾讨论过如何跳过不需要的块 ,可是因为没有排序所以一直没有较好的实现方式。包括RCFile格式,Hive的index 机制里面目前还没有一个高效的根据头部元数据就可以跳过块的实现方式。
4 延迟物化
真正好的列数据库,都应该可以支持直接在压缩数据之上不需要通过解压和排序就能够直接操作块。通过这种方式可以极大的降低MR 框架或者行式数据库中先解压,再反序列化,然后再排序所带来的开销。Google Tenzing里面描述的Block Shuffle 也属于延迟物化的一种。更好的延迟物化可以直接在压缩数据上进行操作,并且可以做内部循环, 此方面在论文《Integrating Compression and Execution in Column-Oriented Database System》[5]的5.2 章节有描述。 不过考虑到它跟UDF 集成也有关系,所以,它会不会将文件接口变得过于复杂也是一件有争议的事情。
5 与Hadoop框架集成
无论文本亦或是二进制格式,都只是最终的储存格式。Hadoop运行时产生的中间数据却没有办法控制。包括一个MR Job在map和reduce之间产生的数据或者DAG Job上游reduce 和下游map之间的数据,尤其是中间格式并不是列格式,这会产生不必要的IO和CPU 开销。比如map 阶段产生的spill,reduce 阶段需要先copy 再sort-merge。如果这种中间格式也是面向列的,然后将一个大块切成若干小块,并在头部加上每个小块的最大最小值索引,就可以避免大量sort-mege操作中解压—反序列化—排序—合并(Merge)的开销,从而缩短任务的运行时间。
其他文件格式
Hadoop社区也曾有对其他文件格式的研究。比如,IBM 研究过面向列的数据格式并发表论文《Column-Oriented Storage Techniques for MapReduce》[4],其中特别提到IBM 的CIF(Column InputFormat)文件格式在序列化和反序列化的IO消耗上比RCFile 的消耗要小20倍。里面提到的将列分散在不同的HDFS Block 块上的实现方式RCFile 也有考虑过,但是最后因为重组行的消耗可能会因分散在远程机器上产生的延迟而最终放弃了这种实现。此外,最近Avro也在实现一种面向列的数据格式,不过目前Hive 与Avro 集成尚未全部完成。有兴趣的读者可以关注avro-806 和hive-895。
总结
Hadoop 可以与各种系统兼容的前提是Hadoop MR 框架本身能够支持多种数据格式的读写。但如果要提升其性能,Hadoop 需要一种高效的面向列的基于整个MR 框架集成的数据格式。尤其是高效压缩,块重组(block shuffle),数据过滤(skip list)等高级功能,它们是列数据库相比MR 框架在文件格式上有优势的地方。相信随着社区的发展以及Hadoop 的逐步成熟,未来会有更高效且统一的数据格式出现。
1.3.2 机架感知
HDFS作为Hadoop中的一个分布式文件系统,而且是专门为它的 MapReduce设计,所以HDFS除了必须满足自己作为分布式文件系统的高可靠性外,还必须为MapReduce提供高效的读写性能,那么HDFS是 如何做到这些的呢?首先,HDFS将每一个文件的数据进行分块存储,同时每一个数据块又保存有多个副本,这些数据块副本分布在不同的机器节点上,这种数据 分块存储+副本的策略是HDFS保证可靠性和性能的关键,这是因为:一.文件分块存储之后按照数据块来读,提高了文件随机读的效率和并发读的效率;二.保 存数据块若干副本到不同的机器节点实现可靠性的同时也提高了同一数据块的并发读效率;三.数据分块是非常切合MapReduce中任务切分的思想。在这 里,副本的存放策略又是HDFS实现高可靠性和搞性能的关键。
HDFS采用一种称为机架感知的策略来改进数据的可靠性、可用性和网络带宽的利用率。通过一个机架感知的过程,NameNode可以确定每一个 DataNode所属的机架id(这也是NameNode采用NetworkTopology数据结构来存储数据节点的原因,也是我在前面详细介绍NetworkTopology类 的原因)。一个简单但没有优化的策略就是将副本存放在不同的机架上,这样可以防止当整个机架失效时数据的丢失,并且允许读数据的时候充分利用多个机架的带 宽。这种策略设置可以将副本均匀分布在集群中,有利于当组件失效的情况下的均匀负载,但是,因为这种策略的一个写操作需要传输到多个机架,这增加了写的代 价。
在大多数情况下,副本系数是3,HDFS的存放策略是将一个副本存放在本地机架节点上,一个副本存放在同一个机架的另一个节点上,最后一个副本放在不同机 架的节点上。这种策略减少了机架间的数据传输,提高了写操作的效率。机架的错误远远比节点的错误少,所以这种策略不会影响到数据的可靠性和可用性。与此同 时,因为数据块只存放在两个不同的机架上,所以此策略减少了读取数据时需要的网络传输总带宽。在这种策略下,副本并不是均匀的分布在不同的机架上:三分之 一的副本在一个节点上,三分之二的副本在一个机架上,其它副本均匀分布在剩下的机架中,这种策略在不损害数据可靠性和读取性能的情况下改进了写的性能。下 面就来看看HDFS是如何来具体实现这一策略的。
1.4 Hadoop知识学习篇
1.4.1 Java接口
从HDAOOP 的URL中读取数据:
FsUrlStreamHandlerFactory实例让java识别Hadoop URL;但Java虚拟机只能调用一次;故使用静态代码。
static
{
URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());
}
public static void main(String args[])
{
String hdfsUri ="hdfs://mylinux:9000/data/mapred/wcout1/1397662485603/part-r-00000";
InputStream in =null;
try {
in = new URL(hdfsUri).openStream();
IOUtils.copy(in, System.out, 4096);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
使用FileSystem API
1、获取文件系统实例
static FileSystem get(URI uri, Configuration conf)
2、使用open函数获取文件的输入流
FSDataInputStream open(Path f, int bufferSize)
3、创建文件
FSDataOutputStream create(Path f,FsPermission permission,boolean overwrite,int bufferSize,short replication,long blockSize,Progressable progress)
4、创建目录
boolean mkdirs(Path f, FsPermission permission)
5、获取文件元数据
abstract FileStatus getFileStatus(Path f)
6、列出文件
abstract FileStatus[] listStatus(Path f)
FileStatus[] listStatus(Path f, PathFilter filter)
7、globalStatus(通配)
FileStatus[] globStatus(Path pathPattern)
FileStatus[] globStatus(Path pathPattern, PathFilter filter)
表 1通配符及其含义
8、删除数据
boolean delete(Path f, boolean recursive)
只有recursive 为true时,非空目录才能被删除。
9、创建文件并写入数据
String localSrc =args[0];
String dest = args[1];
InputStream in =new BufferedInputStream(new FileInputStream(localSrc));
Configuration conf =new Configuration();
FileSystem fs = FileSystem.get(URI.create(dest), conf);
OutputStream out =fs.create(new Path(dest),new Progressable(){
@Override
public void progress() {
System.out.print(".... ");
}
});
IOUtils.copyBytes(in, out,4096,true);
10、获取数据并输出
String uri="hdfs://mylinux:9000/data/exam/movie10m/users.dat";
Configuration conf=new Configuration();
try {
FileSystem fs = FileSystem.get(URI.create(uri), conf);
System.out.println(fs.getClass().toString());
InputStream in=null;
in = fs.open(new Path(uri));
IOUtils.copyBytes(in, System.out, conf);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
97
1.4.2 FileSystem总结
图 1 FileSystem继承体系
FileSy
展开阅读全文