Hadoop的顺序文件—— Hadoop权威指南9

  • 《Hadoop权威指南》的5.4节,讲述了一些二进制文件格式:顺序文件(SequenceFile)、MapFile、Avro等
  • 自己也没有特别大的体会,只能暂时先记录学到的一些知识

1. 顺序文件 —— SequenceFile

  • 考虑日志文件,每一行代表一条日志记录。
  • Hadoop的SequenceFile,支持二进制key-value对的持久化存储,适合用作日志文件的存储
  • 因为你可以使用IntWritable类型的时间戳,作为日志记录的key;使用Writable类型的数据,作为日志记录的value
  • 除此之外,SequenceFile还可以作为小文件的容器,通过key-value形式将将若干个小文件合并到一个SequenceFile文件中。
1.1 SequenceFile的写操作
  • 通过静态方法createWriter(),获取SequenceFile.Writer对象
  1. 如下的createWriter()虽然已被废弃,但是非常具有代表性
  2. 获取SequenceFile.Writer对象时,需要指定 FileSystemPath(对应输入数据流)、ConfigurationkeyClassvalClass对应key-value的类型
  3. 同时,还有可选的压缩类型、显示数据写入进度的回调函数
    public static SequenceFile.Writer createWriter(FileSystem fs, Configuration conf, Path name, 
    		Class keyClass, Class valClass, SequenceFile.CompressionType compressionType, 
    		Progressable progress) throws IOException {
         return createWriter(conf, SequenceFile.Writer.file(name), SequenceFile.Writer.filesystem(fs), SequenceFile.Writer.keyClass(keyClass), SequenceFile.Writer.valueClass(valClass), SequenceFile.Writer.compression(compressionType), SequenceFile.Writer.progressable(progress));
     }
    
  • SequenceFile.Writer写顺序文件的示例:
  1. 通过writer.append()方法,将key-value以顺序写的方式写入顺序文件
  2. 通过writer.getLength()获取顺序文件的当前位置,也就是写入C语言中写入指针指向的位置。
    public class SequenceTest {
        public static void main(String[] args) throws IOException {
            String uri = "hdfs://user/hadoop/input/test.seq";
    
            // 准备输入流的相关配置
            Path path = new Path(uri);
            Configuration configuration = new Configuration();
            FileSystem fileSystem = FileSystem.get(URI.create(uri), configuration);
    
            IntWritable key = new IntWritable();
            Text value = new Text();
            SequenceFile.Writer writer = SequenceFile.createWriter(fileSystem, configuration, path, key.getClass(), value.getClass());
    
            for (int i = 1; i <= 10; i++) {
                // 准备key-value
                key = new IntWritable(i);
                value = new Text(RandomStringUtils.random(8, false, true));
                System.out.printf("[%d]\t%d\t%s\n", writer.getLength(), key.get(), value.toString());
    
                // 将key-value追加到顺序文件中
                writer.append(key, value);
            }
    
            // 关闭输入流
            IOUtils.closeStream(writer);
        }
    }
    
1.2 顺序文件的读取
  • 读取顺序文件,需要SequenceFile.Reader类,reader实例的创建可以直接通过SequenceFile.Reader的构造函数实现

    // 其中一种构造函数
    public Reader(FileSystem fs, Path file, Configuration conf) throws IOException {
        this(conf, file(file.makeQualified(fs)));
    }
    
  • 创建好SequenceFile.Reader实例后,反复调用next()方法获取顺序文件中存储的key-value,就可以实现顺序文件的读取。

    public synchronized boolean next(Writable key, Writable val) throws IOException
    

    next()方法返回true,表示读取到了一条key-value记录;
    ② 返回false,表示读到了顺序文件的末尾,可以停止文件读取。

  • 顺序文件中,一条key-value称为一条记录。

  1. 如果通过seek()方法设置文件读取的位置,很容易出现该位置不是一条记录的边界(start或end)

  2. 顺序文件提供了同步点这一数据结构,用于标记数据流中、与记录边界同步的位置。

  3. 可以通过syncSeen(),判断当前位置是否是一个同步点

    public synchronized boolean syncSeen()
    
  4. 通过sync(),跳到指定position的下一个同步点。若无同步点,则跳到文件末尾

    public synchronized void sync(long position) throws IOException
    
  5. 可以通过getPosition() 获取文件的当前读取位置。

    public synchronized long getPosition() throws IOException 
    
  • SequenceFile.Writer类,也有sync()方法,它用于在当前位置插入同步点
1.3 顺序文件的格式
  • 顺序文件的结构如下图所示,由文件头、掺杂同步点的若干记录组成。
    在这里插入图片描述

  • 其中,文件头主要包含以下内容:

    名称大小备注
    SEQ3 byte顺序文件代码
    version1 byte顺序文件的版本号
    keyClass书中未提及,后续补充key类名
    valueClass书中未提及,后续补充value类名
    数据压缩类型、同步标识、用户定义的元数据等这些内容都是简单提及
  • 顺序文件支持对记录进行压缩,可以按RECORDBLOCK压缩。

  1. 与之前,Hadoop的压缩中,MR有专门针对顺序文件的压缩设置,决定是按记录RECORD压缩,还是按块BLOCK压缩相呼应。
  2. 如果是按RECORD压缩,则是对记录中的value进行压缩:每条记录的开头处,是记录的长度。
  3. 如果是按BLOCK压缩,则是对多条记录中的key和value都进行压缩:每个块的开头处,是记录的条数;同时,每个块的开始处紧跟一个同步点。
    在这里插入图片描述
  • 从两张图中,可以看出:是否进行压缩以及按马忠压缩,顺序文件中record的组织方式都会发生变化。

2. MapFile

  • 对顺序文件中的记录,按照key进行排序将得到MapFile。其具有以下特点:
  1. MapFile拥有索引,使得MapFile可以按key查找记录。
  2. 索引自身就是个顺序文件,包含了主数据文件中的一小部分key。默认情况,每隔128个key,创建索引。
  3. 索引可以加载进内存,可以提供对主数据文件的快速查找
  4. MapFile的主数据文件就是按照key排序后的顺序文件

3. 行式存储和列式存储

  • 除了刚才提及的顺序文件、MapFile,面向大规模数据处理而设计的Avro文件,都采用行式存储
  • 如果将数据看作一张表,则行式存储,一行中的数据在存储介质中是连续存储的
    先按列依次存储第一行中的数据,然后存储第二行中的数据。。。。以此类推
  • 与之对应的是列式存储:一列中的数据,在存储介质中是连续存储的
    先对行进行split(若干行为一个split),然后将每个split中的数据按列存储。
    先存储split中第一列的数据,再存储第二列的数据。。。以此类推
    在这里插入图片描述
  • Hadoop中,使用列式存储的文件格式有:Hive的ORC文件、基于Google Dremel的Parquet文件

行式存储与列式存储的比较:

  1. 行式存储适合的场景:
    ① 适合随机的增删改查操作(增删改查,只是局部操作,而列式存储中则是全局操作
    ② 适合访问一行中大部分数据的情况
    ③ 需要频繁插入或更新的操作,与索引和操作范围更相关
  2. 列式存储适合的场景:
    ① 适合访问一行中少部分数据的情况,可以避免全表扫描。
    ② 可以针对各列进行并发运算,在内存中聚合完整的记录集,最大可能地提高查询效率
    ③ 每列数据独立存储,可以按列进行压缩,节省存储空间

4. 总结

关于顺序文件:

  1. 二进制key-value的持久存储格式,适合日志文件存储、大量小文件的合并
  2. 顺序文件的写:通过createWriter()获取SequenceFile.Writer对象,通过append()实现顺序写,通过getLength()获取写入指针的当前位置
  3. 顺序文件的读:通过构造方法获取SequenceFile.Reader对象,通过next()按记录读取顺序文件(文件末尾返回false),通过getPosition()获取文件的读指针的位置
  4. 关于同步点:reader.syncSeen()获取当前位置是否为同步点,reader.sync()跳到指定position的之后的第一个同步点,writer.sync()插入同步点
  5. 顺序文件的格式:文件头 + records + record中穿插的同步点;基于RECORDBLOCK压缩的顺序文件,结构差异

关于MapFile

  1. 带索引的、按key排序后的顺序文件
  2. 索引是一个顺序文件,包含主数据文件中的一小部分key(默认128个key),可以加载到内存中,提供对主数据文件的快速查找

Hadoop中常见的文件格式:

  1. 顺序文件、MapFile和Avro都是行式存储
  2. ORC和parquet都是列式存储

行式存储与列式存储

  1. 行式存储与列式存储的概念
  2. 行式存储:适合随机的增删该查、适合访问一行中的大部分数据、适合频繁的增加和删除操作
  3. 列式存储:适合访问一行中的少部分数据、适合按行压缩以减少存储空间、适合并发计算以提交查询效率
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
二手房统计分析是一个基于Hadoop的综合项目,旨在帮助人们深入了解二手房市场情况并进行相应的统计分析。 首先,我们需要收集大量的二手房交易数据。可以从不同的渠道收集数据,如网络房产平台、中介公司等。通过使用Hadoop的分布式文件系统(HDFS),可以将这些数据存储在集群中的多个节点上,以便后续的处理和分析。 然后,需要对收集到的数据进行清洗和预处理。这包括去除重复数据、处理缺失值和异常值等。通过使用Hadoop的MapReduce框架,可以将清洗和预处理任务并行化处理,以提高处理效率和准确性。 接下来,可以进行一些常见的统计分析。比如,可以计算不同城市二手房价格的平均值、中位数和标准差,以了解各个城市的房价水平和波动程度。同样地,还可以计算不同地区的交易量和均价,以找到二手房交易的热点区域。 此外,也可以进行数据可视化的工作,以方便人们更直观地理解二手房市场情况。通过使用Hadoop的数据处理工具和可视化库,如Hive和Tableau,可以将统计分析的结果以图表或地图的形式展示出来。 最后,还可以通过机器学习技术进行更深入的分析。比如,可以建立预测模型来预测二手房价格,或者进行聚类分析找到不同类型的二手房市场。通过使用Hadoop的机器学习库,如Spark MLlib,可以更高效地处理大规模的数据和模型训练。 总之,通过Hadoop的分布式计算和数据处理能力,二手房统计分析项目可以帮助人们更好地了解二手房市场情况,并提供相应的统计和预测分析,以支持人们做出更明智的决策。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值