Hadoop基于文件的数据结构及实例

基于文件的数据结构
两种文件格式:
1、SequenceFile
2、MapFile

SequenceFile

1、SequenceFile文件是Hadoop用来存储二进制形式的<key,value>对而设计的一种平面文件(Flat File)。

2、可以把SequenceFile当做一个容器,把所有文件打包到SequenceFile类中可以高效的对小文件进行存储和处理。

3、SequenceFile文件并不按照其存储的key进行排序存储,SequenceFile的内部类Writer**提供了append功能**。

4、SequenceFile中的key和value可以是任意类型Writable或者是自定义Writable类型。

SequenceFile压缩

1、SequenceFile的内部格式取决于是否启用压缩,如果是,要么是记录压缩,要么是块压缩。
2、三种类型:
A.无压缩类型:如果没有启用压缩(默认设置),那么每个记录就由它的记录长度(字节数)、键的长度,键和值组成。长度字段为四字节。

B.记录压缩类型:记录压缩格式与无压缩格式基本相同,不同的是值字节是用定义在头部的编码器来压缩。注意,键是不压缩的。

C.块压缩类型:块压缩一次压缩多个记录,因此它比记录压缩更紧凑,而且一般优先选择。当记录的字节数达到最小大小,才会添加到块。该最小值由io.seqfile.compress.blocksize中的属性定义。默认值是1000000字节。格式为记录数、键长度、键、值长度、值。

无压缩格式与记录压缩格式

块压缩格式

SequenceFile文件格式的好处
A.支持基于记录(Record)或块(Block)的数据压缩。
B.支持splittable,能够作为MapReduce的输入分片。
C.修改简单:主要负责修改相应的业务逻辑,而不用考虑具体的存储格式。
SequenceFile文件格式的坏处
坏处是需要一个合并文件的过程,且合并后的文件将不方便查看。因为它是二进制文件。

读写SequenceFile

写过程:
1)创建Configuration
2)获取FileSystem
3)创建文件输出路径Path
4)调用SequenceFile.createWriter得到SequenceFile.Writer对象
5)调用SequenceFile.Writer.append追加写入文件
6)关闭流
读过程:
1)创建Configuration
2)获取FileSystem
3)创建文件输出路径Path
4)new一个SequenceFile.Reader进行读取
5)得到keyClass和valueClass
6)关闭流

<code class="hljs livecodeserver has-numbering">org.apache.hadoop.io 
Class SequenceFile
There are <span class="hljs-constant">three</span> SequenceFile Writers based <span class="hljs-command"><span class="hljs-keyword">on</span> <span class="hljs-title">the</span> <span class="hljs-title">SequenceFile</span>.<span class="hljs-title">CompressionType</span> <span class="hljs-title">used</span> <span class="hljs-title">to</span> <span class="hljs-title">compress</span> <span class="hljs-title">key</span>/<span class="hljs-title">value</span> <span class="hljs-title">pairs</span>: </span>
<span class="hljs-number">1</span>、Writer : Uncompressed records. 
<span class="hljs-number">2</span>、RecordCompressWriter : Record-compressed <span class="hljs-built_in">files</span>, only <span class="hljs-built_in">compress</span> values. 
<span class="hljs-number">3</span>、BlockCompressWriter : Block-compressed <span class="hljs-built_in">files</span>, both <span class="hljs-built_in">keys</span> & values are collected <span class="hljs-operator">in</span> <span class="hljs-string">'blocks'</span> separately <span class="hljs-operator">and</span> compressed. The size <span class="hljs-operator">of</span> <span class="hljs-operator">the</span> <span class="hljs-string">'block'</span> is configurable</code>

无压缩方式、记录压缩、块压缩实例

<code class="hljs avrasm has-numbering">package SequenceFile<span class="hljs-comment">;</span>

import java<span class="hljs-preprocessor">.io</span><span class="hljs-preprocessor">.IOException</span><span class="hljs-comment">;</span>
import java<span class="hljs-preprocessor">.net</span><span class="hljs-preprocessor">.URI</span><span class="hljs-comment">;</span>


import org<span class="hljs-preprocessor">.apache</span><span class="hljs-preprocessor">.hadoop</span><span class="hljs-preprocessor">.conf</span><span class="hljs-preprocessor">.Configuration</span><span class="hljs-comment">;</span>
import org<span class="hljs-preprocessor">.apache</span><span class="hljs-preprocessor">.hadoop</span><span class="hljs-preprocessor">.fs</span><span class="hljs-preprocessor">.FileSystem</span><span class="hljs-comment">;</span>
import org<span class="hljs-preprocessor">.apache</span><span class="hljs-preprocessor">.hadoop</span><span class="hljs-preprocessor">.fs</span><span class="hljs-preprocessor">.Path</span><span class="hljs-comment">;</span>
import org<span class="hljs-preprocessor">.apache</span><span class="hljs-preprocessor">.hadoop</span><span class="hljs-preprocessor">.io</span><span class="hljs-preprocessor">.IOUtils</span><span class="hljs-comment">;</span>
import org<span class="hljs-preprocessor">.apache</span><span class="hljs-preprocessor">.hadoop</span><span class="hljs-preprocessor">.io</span><span class="hljs-preprocessor">.IntWritable</span><span class="hljs-comment">;</span>
import org<span class="hljs-preprocessor">.apache</span><span class="hljs-preprocessor">.hadoop</span><span class="hljs-preprocessor">.io</span><span class="hljs-preprocessor">.SequenceFile</span><span class="hljs-comment">;</span>
import org<span class="hljs-preprocessor">.apache</span><span class="hljs-preprocessor">.hadoop</span><span class="hljs-preprocessor">.io</span><span class="hljs-preprocessor">.SequenceFile</span><span class="hljs-preprocessor">.CompressionType</span><span class="hljs-comment">;</span>
import org<span class="hljs-preprocessor">.apache</span><span class="hljs-preprocessor">.hadoop</span><span class="hljs-preprocessor">.io</span><span class="hljs-preprocessor">.Text</span><span class="hljs-comment">;</span>
import org<span class="hljs-preprocessor">.apache</span><span class="hljs-preprocessor">.hadoop</span><span class="hljs-preprocessor">.io</span><span class="hljs-preprocessor">.Writable</span><span class="hljs-comment">;</span>
import org<span class="hljs-preprocessor">.apache</span><span class="hljs-preprocessor">.hadoop</span><span class="hljs-preprocessor">.io</span><span class="hljs-preprocessor">.compress</span><span class="hljs-preprocessor">.BZip</span>2Codec<span class="hljs-comment">;</span>
import org<span class="hljs-preprocessor">.apache</span><span class="hljs-preprocessor">.hadoop</span><span class="hljs-preprocessor">.util</span><span class="hljs-preprocessor">.ReflectionUtils</span><span class="hljs-comment">;</span>

public class Demo01 {

    final static String uri= <span class="hljs-string">"hdfs://liguodong:8020/liguodong"</span><span class="hljs-comment">;</span>
    final static String[] data = {
        <span class="hljs-string">"apache,software"</span>,<span class="hljs-string">"chinese,good"</span>,<span class="hljs-string">"james,NBA"</span>,<span class="hljs-string">"index,pass"</span>
    }<span class="hljs-comment">;</span>

    public static void main(String[] args) throws IOException {
        //<span class="hljs-number">1</span>
        Configuration configuration = new Configuration()<span class="hljs-comment">;</span>
        //<span class="hljs-number">2</span>
        FileSystem fs = FileSystem<span class="hljs-preprocessor">.get</span>(URI<span class="hljs-preprocessor">.create</span>(uri),configuration)<span class="hljs-comment">;</span>
        //<span class="hljs-number">3</span>
        Path path = new Path(<span class="hljs-string">"/tmp.seq"</span>)<span class="hljs-comment">;</span>

        write(fs,configuration,path)<span class="hljs-comment">;</span>
        read(fs,configuration,path)<span class="hljs-comment">;</span>

    }

    public static void write(FileSystem fs,Configuration configuration,Path path) throws IOException{
        //<span class="hljs-number">4</span>
        IntWritable key = new IntWritable()<span class="hljs-comment">;</span>
        Text value = new Text()<span class="hljs-comment">;</span>
        //无压缩
        <span class="hljs-comment">/*@SuppressWarnings("deprecation")
        SequenceFile.Writer writer = SequenceFile.createWriter
                (fs,configuration,path,key.getClass(),value.getClass());*/</span>
        //记录压缩
        @SuppressWarnings(<span class="hljs-string">"deprecation"</span>)
        SequenceFile<span class="hljs-preprocessor">.Writer</span> writer = SequenceFile<span class="hljs-preprocessor">.createWriter</span>
                (fs,configuration,path,key<span class="hljs-preprocessor">.getClass</span>(),
                        value<span class="hljs-preprocessor">.getClass</span>(),CompressionType<span class="hljs-preprocessor">.RECORD</span>,new BZip2Codec())<span class="hljs-comment">;</span>
        //块压缩
        <span class="hljs-comment">/*@SuppressWarnings("deprecation")
        SequenceFile.Writer writer = SequenceFile.createWriter
                (fs,configuration,path,key.getClass(),
                value.getClass(),CompressionType.BLOCK,new BZip2Codec());*/</span>

        //<span class="hljs-number">5</span>
        for (int i = <span class="hljs-number">0</span><span class="hljs-comment">; i < 30; i++) {</span>
            key<span class="hljs-preprocessor">.set</span>(<span class="hljs-number">100</span>-i)<span class="hljs-comment">;</span>
            value<span class="hljs-preprocessor">.set</span>(data[i%data<span class="hljs-preprocessor">.length</span>])<span class="hljs-comment">;</span>
            writer<span class="hljs-preprocessor">.append</span>(key, value)<span class="hljs-comment">;</span>
        }
        //<span class="hljs-number">6</span>、关闭流
        IOUtils<span class="hljs-preprocessor">.closeStream</span>(writer)<span class="hljs-comment">;        </span>
    }

    public static void read(FileSystem fs,Configuration configuration,Path path) throws IOException {
        //<span class="hljs-number">4</span>
        @SuppressWarnings(<span class="hljs-string">"deprecation"</span>)
        SequenceFile<span class="hljs-preprocessor">.Reader</span> reader = new SequenceFile<span class="hljs-preprocessor">.Reader</span>(fs, path,configuration)<span class="hljs-comment">;</span>
        //<span class="hljs-number">5</span>
        Writable key = (Writable) ReflectionUtils<span class="hljs-preprocessor">.newInstance</span>
                (reader<span class="hljs-preprocessor">.getKeyClass</span>(), configuration)<span class="hljs-comment">;</span>
        Writable value = (Writable) ReflectionUtils<span class="hljs-preprocessor">.newInstance</span>
                (reader<span class="hljs-preprocessor">.getValueClass</span>(), configuration)<span class="hljs-comment">;</span>

        while(reader<span class="hljs-preprocessor">.next</span>(key,value)){
            System<span class="hljs-preprocessor">.out</span><span class="hljs-preprocessor">.println</span>(<span class="hljs-string">"key = "</span> + key)<span class="hljs-comment">;</span>
            System<span class="hljs-preprocessor">.out</span><span class="hljs-preprocessor">.println</span>(<span class="hljs-string">"value = "</span> + value)<span class="hljs-comment">;</span>
            System<span class="hljs-preprocessor">.out</span><span class="hljs-preprocessor">.println</span>(<span class="hljs-string">"position = "</span>+ reader<span class="hljs-preprocessor">.getPosition</span>())<span class="hljs-comment">;</span>
        }
        IOUtils<span class="hljs-preprocessor">.closeStream</span>(reader)<span class="hljs-comment">;</span>
    }
}</code>

运行结果:

<code class="hljs makefile has-numbering"><span class="hljs-constant">key</span> = 100
<span class="hljs-constant">value</span> = apache,software
<span class="hljs-constant">position</span> = 164
<span class="hljs-constant">key</span> = 99
<span class="hljs-constant">value</span> = chinese,good
<span class="hljs-constant">position</span> = 197
<span class="hljs-constant">key</span> = 98
<span class="hljs-constant">value</span> = james,NBA
<span class="hljs-constant">position</span> = 227
<span class="hljs-constant">key</span> = 97
<span class="hljs-constant">value</span> = index,pass
<span class="hljs-constant">position</span> = 258
<span class="hljs-constant">key</span> = 96
<span class="hljs-constant">value</span> = apache,software
<span class="hljs-constant">position</span> = 294
<span class="hljs-constant">key</span> = 95
<span class="hljs-constant">value</span> = chinese,good
<span class="hljs-constant">position</span> = 327
......
<span class="hljs-constant">key</span> = 72
<span class="hljs-constant">value</span> = apache,software
<span class="hljs-constant">position</span> = 1074
<span class="hljs-constant">key</span> = 71
<span class="hljs-constant">value</span> = chinese,good
<span class="hljs-constant">position</span> = 1107</code>

MapFile

<code class="hljs java has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MapFile</span> {</span>
  <span class="hljs-javadoc">/** The name of the index file. */</span>
  <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String INDEX_FILE_NAME = <span class="hljs-string">"index"</span>;

  <span class="hljs-javadoc">/** The name of the data file. */</span>
  <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String DATA_FILE_NAME = <span class="hljs-string">"data"</span>;
}</code>

MapFile是经过排序的索引的SequenceFile,可以根据key进行查找。

与SequenceFile不同的是, MapFile的Key一定要实现WritableComparable接口 ,即Key值是可比较的,而value是Writable类型的。
可以使用MapFile.fix()方法来重建索引,把SequenceFile转换成MapFile。
它有两个静态成员变量:

<code class="hljs java has-numbering"><span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String INDEX_FILE_NAME
<span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String DATA_FILE_NAME</code>

通过观察其目录结构可以看到MapFile由两部分组成,分别是data和index。
index作为文件的数据索引,主要记录了每个Record的key值,以及该Record在文件中的偏移位置。

在MapFile被访问的时候,索引文件会被加载到内存,通过索引映射关系可迅速定位到指定Record所在文件位置。
因此,相对SequenceFile而言, MapFile的检索效率是高效的,缺点是会消耗一部分内存来存储index数据。
需注意的是, MapFile并不会把所有Record都记录到index中去,默认情况下每隔128条记录存储一个索引映射。当然,记录间隔可人为修改,通过MapFIle.Writer的setIndexInterval()方法,或修改io.map.index.interval属性;

读写MapFile

写过程:
1)创建Configuration
2)获取FileSystem
3)创建文件输出路径Path
4)new一个MapFile.Writer对象
5)调用MapFile.Writer.append追加写入文件
6)关闭流
读过程:
1)创建Configuration
2)获取FileSystem
3)创建文件输出路径Path
4)new一个MapFile.Reader进行读取
5)得到keyClass和valueClass
6)关闭流

具体操作与SequenceFile相似。

命令行查看二进制文件
hdfs dfs -text /liguodong/tmp.seq



原文转载至:http://blog.csdn.net/scgaliguodong123_/article/details/46391061

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
⼤数据离线计算的架构与组件 ⼤数据离线计算的架构与组件             ⼤数据离线计算的架构与组件                                      作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任。 ⼀.什么是⼤数据离线计算 1>.⼤数据离线计算概述   (1)所谓⼤数据离线计算,就是利⽤⼤数据的技术栈(主要是Hadoop),在计算开始前准备好所有输⼊数据,该输⼊数据不会产⽣变化,且在解决⼀个问题后就要⽴即得到计算结果的计算模式。   (2)离线(offline)计算也可以理解为批处理(batch)计算,与其相对应的是在线(online)计算或实时(realtime)计算 2>.离线计算的特点   (1)数据量巨⼤,保存时间长   (2)在⼤量数据上进⾏复杂的批量运算   (3)数据在计算之前已经完全到位,不会发⽣变化   (4)能够⽅便地查询计算结果 3>.⼤数据离线计算应⽤场景 (1)⼤数据离线计算主要⽤于数据分析、数据挖掘等领域。我们说这部分的技术栈主要是Hadoop,但在以Hadoop为代表的⼤数据技术出现之前,数据分析、数据挖掘已经经历了长⾜的发展。尤其以BI系统为主的数据分析领域,已经有了⽐较成熟稳 (2)BI(全称为Business Intelligence,即商业智能)系统能够辅助业务经营决策。其需要综合利⽤数据仓库(基于关系型数据库)、联机分析处理(OLAP)⼯具(如各种SQL)和数据挖掘等技术。 (3)如Oracle、IBM、Microsoft等数据库⼚商都有⾃⼰的BI产品,MicroStrategy、SAP等独⽴BI⼚商也有⾃⼰的软件产品。 4>.传统BI暴漏的问题 然⽽传统BI随着时间的推移暴露出⼀些问题: (1)BI系统以分析业务系统产⽣的结构化数据为主,对⾮结构化和半结构化数据处理困难,如⽂本、图⽚、⾳视频等。 (2)由于数据仓库为结构化存储,在数据从其它系统进⼊数据仓库前需要⼀个ETL过程,ETL通常和业务强绑定,需要专门的⼈员去做这个⼯作。 (3)当数据量增⼤的时候,性能会成为瓶颈,传统关系型数据库在TB级别时已经表现得吃⼒,在PB级别时基本⽆能为⼒。 (4)数据库的设计⼀般会遵循某种范式,其着⼒于解决数据冗余和⼀致性问题。但数据仓库设计时为了性能和⽅便的考虑,通常会使⽤⼀些反范式的设计。如何在范式和反范式间权衡没有确定的标准,需要⼩⼼设计。 (5)对于包含机器学习应⽤的BI系统,由于ETL的存在,其获取到的数据为已经按某种假设清洗后的数据,会造成机器学习的效果不理想或完全没有效果。 5>.⼤数据离线计算的优势 针对这⼀系列问题,以Hadoop为代表的⼤数据解决⽅案表现出其优越性,Hadoop技术栈中的各种组件不断丰富,已经完全能实现传统BI的功能,并解决了其容量和性能的瓶颈。 但⼤数据技术也带来了⼀些新问题:   从传统数据仓库升级到⼤数据的数据仓库,不可能平滑演进,基本等于重新开发。这和软硬件架构的不⼀致、SQL⽅⾔的差异都有关系。   ⼤数据解决⽅案在功能和性能上有很多取舍,如HDFS不⽀持修改⽂件,Hive要⽀持update和delete的话有⾮常苛刻的限制且效率也远低于关系型数据库。类似这些都是⼤数据解决⽅案的局限性。 ⼤数据离线计算侧重于从以下⼏个维度解决传统BI⾯临的瓶颈:   分布式存储:     将⼤⽂件按照⼀定⼤⼩拆分成多份,分别存储到独⽴的机器上,并且每⼀份可以设置⼀定的副本数,防⽌机器故障导致数据丢失,这种存储⽅式⽐传统关系型数据库/数据仓库使⽤的集中式存储,⽆论是容量、价格、吞吐率、鲁棒性等各⽅⾯   分布式计算:     核⼼思想是让多个机器并⾏计算,并通过对数据本地性的利⽤,尽量处理本机器上的那⼀部分数据,减少跨⽹络的数据传输。很多传统的数据库/数据仓库也⽀持利⽤多核CPU、集群技术来进⾏分布式计算,但Hadoop的分布式计算架构更为   检索和存储的结合:     在早期的⼤数据组件中,存储和计算相对⽐较单⼀,但⽬前的⽅向是对存储进⼀步优化, 升查询和计算的效率,其⽅法是除了存储数据的内容外,还存储很多元数据信息,如数据的schema、索引等。类似parquet、kudu等技术都是利⽤了这 ⼆.⼤数据离线计算的架构 三.⼤数据离线计算涉及组件 1>.HDFS HDFS   是Hadoop上的分布式⽂件系统。 HDFS采⽤主从模式,其架构主要包含NameNode,DataNode,Client三个部分:   NameNode:     ⽤于存储、⽣成⽂件系统的元数据。运⾏⼀个实例,因此需要解决单点故障问题。   DataNode:     ⽤于存储实际的数据,并将⾃⼰管理的数据块信息上报给NameNode,运⾏多个实例
随着数字化时代的到来,海量的数据已经成为改变人们生活和工作的重要动力,而hadoop则是目前应用最广泛的大数据处理平台之一。基于hadoop的电影数据分析系统,是一种利用hadoop技术来处理、分析、挖掘海量电影数据的一种工具。 这个电影数据分析系统最大的特点就是对大数据进行有效处理。据统计,全球每天产生的数据量已经超过20个奇字节,而hadoop成功应对了大数据处理的挑战。此系统可以利用hadoop的分布式架构,提高数据的处理效率,支持海量数据的存储和处理。同时,它可以将处理好的数据提供给用户进行分析和挖掘,为用户提供更准确、更有价值的电影数据分析结果。 此系统的应用范围非常广泛。它可以为电影制作人提供一些重要的决策依据,如选择演员、剧本设计、市场预测等。此系统还可以为电影投资人提供市场趋势分析,为票房收入提供参考。此外,这个系统还可以被影城、影视公司以及相关企业所使用,提供更好的营销策略、媒体扩展以及消费者行为预测等服务。 综上所述,基于hadoop的电影数据分析系统已经成为一种利用大数据技术进行电影数据处理和分析的重要工具。此系统集成了海量的数据和各种算法,为用户提供预测、分析、挖掘和决策等全方位服务,为电影业务提供了更加准确和深度的支持。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值