最近仔细研究了以下公司中使用的SequenceFile文件格式,SequenceFile的格式比较紧凑,实现了从中间读取文件内容(便于hadoop将文件进行适当地切分),同时也可以支持仅读取文件的元数据功能。
概述
经过总结后的文件格式图大概如下:
其中进入到SequenceFile的所有记录,都需要根据一定的hash规则确定一个HashKey。相对而言,记录块是比较简单的,每个记录块中仅包含块的大小,以及该块的数据;元数据就相对而言比较复杂,其中Metadata size是总体的记录数,每个HashKey均可以直接定位到记录的位置(offset, length, number记载着这些信息)。
其中需要注意的是,记录是严格有序的,写文件需要按照HashKey的顺序进行写入,也就是说,不能向该文件中append一条HashKey在当前Key之前的数据,一旦文件写完成,可能不能再更改。
实现的类图大概如下:
其中Writer负责写入文件,最重要的方法就是append,注意append的key顺序要保证;Reader负责读取文件,遍历next直到没有可用数据。
文件的写入
写入是由多次append执行的,每次append仅仅会写入其中的RecordBlock数据,而将元数据放在内存中:
if (length < 0) { throw new IOException("negative length values not allowed: " + length); } this.out.write(val, offset, length); ++this.number;
等到最后所有数据都已经写入完成后,执行writeTailer写入尾部的文件特征码,版本,元数据和元数据长度等信息:
private void writeTailer() throws IOException { this.lastPos = this.out.getPos(); this.out.write(XXSequenceFile.VERSION, 0, XXSequenceFile.VERSION.length); Text.writeString(this.out, valClass.getName()); this.metadata.write(this.out); long currentPos = this.out.getPos(); this.out.writeInt((int) (currentPos - this.lastPos)); }
经过测试,我们向其中写入3条String数据:{“A”, “BA”, “Cba”}(其hash值分别为1,63,2)的结果为:
0000000: 0141 0343 6261 0242 414d 5a53 4551 0119 .A.Cba.BAXXSEQ.. 0000010: 6f72 672e 6170 6163 6865 2e68 6164 6f6f org.apache.hadoo 0000020: 702e 696f 2e54 6578 7400 0000 0003 0000 p.io.Text....... 0000030: 0001 3100 0000 0000 0000 0000 0000 0000 ..1............. 0000040: 0000 0200 0000 0000 0000 0100 0000 0132 ...............2 0000050: 0000 0000 0000 0002 0000 0000 0000 0004 ................ 0000060: 0000 0000 0000 0001 0000 0002 3633 0000 ............63.. 0000070: 0000 0000 0006 0000 0000 0000 0003 0000 ................ 0000080: 0000 0000 0001 0000 007d 0a .........}.
文件的读取
那么这种类型的文件,读取从哪里开始?就是从最后面的length(int格式),我们直接跳转到最后4个字节:
this.in.seek(this.length - 4); int tailLength = this.in.readInt(); this.contentEnd = this.length - 4 - tailLength; this.in.seek(this.contentEnd);
这样可以直接定位到元数据的位置,然后将读取元数据至内存:
this.metadata.readFields(this.in);
最后通过setMeta()方法,设置key要读取的位置,其中参数就为HashKey,根据HashKey已经能够查找到对应的offset偏移量,定位到记录的所在:
XXSequenceFileMeta smeta = this.metadata.get(meta); if (smeta != null) { this.partIn = new XXSequenceFile.PartInputStream(this.in, smeta.getOffset(), smeta.getOffset() + smeta.getLength()); this.number = smeta.getNumber(); } else { this.partIn = new MzSequenceFile.PartInputStream(this.in); this.number = 0; }
这样就实现了一整套SequenceFile文件写入/读取的功能,文件格式紧凑,并且可以从任意地方开始读取。
相关推荐
针对铁道供电监控数据的存储和压缩问题,研究对比了不同的文件存储格式,包括RCFile、TextFile和SequenceFile,并对这些文件格式应用了Deflate、Gzip、Lzo等压缩算法。经过实验数据分析,RCFile在数据查询性能和压缩...
解决这个问题的一种方法是将`hive-site.xml`文件复制到`apache-hive`目录下的`conf`目录,但这种方法并不理想,建议深入研究更稳定的方法来解决这个问题。 关于sequencefile格式,它是Hadoop中的一个二进制文件格式...
MapReduce是一种编程模型,用于大规模数据集的并行计算,其工作原理是将大任务拆分成许多小的Map任务和Reduce任务,在多台机器上并行执行。HDFS则是分布式文件系统,以高容错性和高吞吐量为目标设计。 HDFS采用主从...
- **志愿计算**:这是一种利用个人计算机空闲时间进行分布式计算的方式,通常用于科学研究项目。 #### 2. Hadoop的历史与发展 - **Hadoop简介**:Hadoop 项目始于2006年,由雅虎公司的工程师 Doug Cutting 和 ...
HDFS是一种高度容错性的系统,适合在廉价硬件上存储大量数据。MapReduce是一种处理和生成大数据集的编程模型。Hadoop的生态系统还包括HBase、Hive、Pig等其他项目,它们都建立在Hadoop的基础之上。 Hadoop生态系统...
- **MapReduce简介**:MapReduce是一种编程模型,用于处理和生成大型数据集,其核心思想是将数据处理任务分解成两部分:Map阶段和Reduce阶段。 - **Java MapReduce**:本书提供了详细的Java MapReduce编程指南,包括...
5. **Hive的存储结构**:Hive将数据存储在HDFS上,可以是文本文件、SequenceFile或其他Hadoop支持的格式。数据可以通过分区和桶化来提高查询效率。 6. **Hive的表和分区**:Hive表可以被分区,以优化查询性能。例如...
在这些算法中,随机森林(Random Forest)是一种广泛使用的集成学习方法,适用于分类和回归任务。本篇文章将详细解释如何在 Mahout 中使用随机森林进行数据分类。 首先,我们需要了解随机森林的基本概念。随机森林...
HDFS提供了高容错性和可扩展性的分布式文件系统,而MapReduce则是一种编程模型,用于处理和生成大型数据集。 在《Hadoop权威指南》第三版中,你可以了解到以下关键知识点: 1. **HDFS基础**:HDFS的设计原则、架构...
Naive Bayes是一种基于概率的分类方法,它假设特征之间相互独立。尽管“naive”一词暗示了对特征独立性的假设过于简单,但在许多实际问题中,该算法表现出令人惊讶的效率和准确性。在入侵检测中,Naive Bayes可以...
3. **MapReduce**:MapReduce是一种编程模型,用于大规模数据集的并行处理。它将大型任务分解为小的Map任务和Reduce任务,在集群中的各个节点上并行执行。Map阶段处理数据并生成中间键值对,Reduce阶段则对这些中间...
- **SequenceFile**:一种高效的二进制文件格式,用于存储键值对,适合Hadoop的分布式环境。 #### 网络拓扑和机架感知 Hadoop能识别数据节点所在的机架,优化数据传输路径,提高效率。 #### RPC(Remote ...
(2) 使用Hadoop的SequenceFile、Avro或Parquet等格式,这些格式能更高效地处理小文件;(3) 使用HBase等NoSQL数据库进行数据存储,它们更适用于大量小键值对。 5. **NCDC数据应用**:NCDC的气候数据可以用于多种分析...
每种模式对应不同的数据存储格式,如TEXTFILE是最基本的文本格式,而PARQUET则是优化过的列式存储格式,更适合大规模数据分析。Metastore会记录每个表的存储模式,以便于在查询时选择合适的读取策略。 Hive Server2...
协同过滤是一种基于用户行为的历史数据,通过分析用户之间的相似性或者物品之间的相似性来预测用户可能对哪些物品感兴趣的方法。在这个系统中,Mahout作为强大的机器学习库,提供了实现这种算法的工具和框架。 首先...
- **Hadoop流**和**Hadoop管道**:提供了一种将MapReduce作业与其他系统(如Unix命令或脚本)连接的方法,增强了灵活性。 3. **Hadoop分布式文件系统(HDFS)** - **HDFS设计**:基于主从结构,保证高可用性和...