Hadoop序列文件优于HDFS平面文件(文本)的优势是什么?Sequence文件以什么方式有效?
可以将小文件组合并写入序列文件,但也可以对HDFS文本文件执行相同的操作.需要知道这两种方式的区别.我已经谷歌搜索了一段时间,如果我明白这个会有帮助吗?
我希望能够创建一个读取序列文件的自定义InputFormat,但另外公开记录所在文件中的文件路径和偏移量.
退一步,这是用例:我有一个包含可变大小数据的序列文件.密钥几乎不相关,并且值高达几兆字节,包含各种不同的字段.我想将elasticsearch中的一些字段与文件名和偏移量一起索引.这样,我可以从elasticsearch中查询这些字段,然后使用文件名和偏移量返回到序列文件并获取原始记录,而不是将整个内容存储在ES中.
我将整个过程作为单个java程序运行.该SequenceFile.Reader类提供了方便getPosition和seek方法来实现这一目标.
但是,最终会涉及到数TB的数据,所以我需要将其转换为MapReduce作业(可能只有Map).由于序列文件中的实际键是无关紧要的,我希望采用的方法是创建一个自定义的InputFormat,它扩展或以某种方式利用SquenceFileInputFormat,而不是返回实际的键,而是返回一个由文件组成的复合键和抵消.
然而,事实证明这在实践中更加困难.看起来它应该是可能的,但考虑到实际的API以及暴露的内容,它很棘手.有任何想法吗?也许我应该采取另一种方法?
我正在尝试从map-reduce作业中编写一个snappy块压缩序列文件.我正在使用hadoop 2.0.0-cdh4.5.0和snappy-java 1.0.4.1
这是我的代码:
package jinvestor.jhouse.mr;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.List;
import jinvestor.jhouse.core.House;
import jinvestor.jhouse.core.util.HouseAvroUtil;
import jinvestor.jhouse.download.HBaseHouseDAO;
import org.apache.commons.io.IOUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.LocatedFileStatus;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.RemoteIterator;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.apache.hadoop.hbase.mapreduce.TableMapReduceUtil;
import org.apache.hadoop.hbase.mapreduce.TableMapper;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.SequenceFile;
import org.apache.hadoop.io.compress.CompressionCodec;
import org.apache.hadoop.io.compress.SnappyCodec;
import org.apache.hadoop.mapred.FileOutputFormat;
import org.apache.hadoop.mapred.JobConf;
import org.apache.hadoop.mapreduce.lib.output.SequenceFileOutputFormat;
import org.apache.hadoop.mapreduce.Job;
import org.apache.mahout.math.DenseVector;
import org.apache.mahout.math.NamedVector;
import org.apache.mahout.math.VectorWritable;
/**
* Produces mahout vectors from House entries in HBase.
*
* …Run Code Online (Sandbox Code Playgroud) 如何RDD[Array[Byte]]使用Apache Spark 写入文件并再次阅读?
我希望能够在hdfs文件系统上读/写图像并利用hdfs局部性.
我有一组图像,每个图像由一组图像组成
我想在hdfs文件系统上创建一个存档,并使用spark来分析存档.现在,我正在努力克服在hdfs文件系统上存储数据的最佳方式,以便能够充分利用spark + hdfs结构.
据我所知,最好的方法是创建一个sequenceFile包装器.我有两个问题:
我有一堆Hadoop SequenceFiles,它们是用我编写的一些Writable子类编写的.我们称之为FishWritable.
这个Writable很好地工作了一段时间,直到我决定为了清晰起见需要重命名包.所以现在FishWritable的完全限定名称com.vertebrates.fishes.FishWritable不是com.mammals.fishes.FishWritable.考虑到有关包裹的范围是如何演变的,这是一个合理的变化.
然后我发现我的MapReduce作业都不会运行,因为它们在尝试初始化SequenceFileRecordReader时崩溃:
java.lang.RuntimeException: java.io.IOException: WritableName can't load class: com.mammals.fishes.FishWritable
at org.apache.hadoop.io.SequenceFile$Reader.getKeyClass(SequenceFile.java:1949)
at org.apache.hadoop.io.SequenceFile$Reader.init(SequenceFile.java:1899)
...
Run Code Online (Sandbox Code Playgroud)
处理这个问题的几个选项很明显.我可以简单地重新运行以前的所有作业,使用最新的密钥类名重新生成输出,依次运行任何依赖的作业.这显然是非常耗时的,有时甚至是不可能的.
另一种可能性是编写一个简单的作业,将SequenceFile作为文本读取,并用新的实例替换类名的任何实例.这基本上是方法#1,带有调整,使其不那么复杂.如果我有很多大文件,它仍然是不切实际的.
有没有更好的方法来处理SequenceFiles中使用的完全限定类名的重构?理想情况下,我正在寻找一些方法来指定新的回退类名称(如果找不到指定的名称),以允许针对此SequenceFile的日期和更新类型运行.
我有一个CSV文件,我想将其转换为SequenceFile,我最终会用它来创建NamedVectors以用于群集作业.我一直在使用seqdirectory命令尝试创建一个SequenceFile,然后使用-nv选项将该输出提供给seq2sparse以创建NamedVectors.看起来这是一个大向量作为输出,但我最终希望我的CSV的每一行成为NamedVector.我哪里错了?
我有一些来自Common Crawl的mapred数据,我已经以SequenceFile格式存储了这些数据.我已经多次尝试使用Hive"按原样"使用这些数据,因此我可以在各个阶段查询和采样.但是我的作业输出总是出现以下错误:
LazySimpleSerDe: expects either BytesWritable or Text object!
Run Code Online (Sandbox Code Playgroud)
我甚至构建了一个更简单(和更小)的[Text,LongWritable]记录数据集,但这也失败了.如果我将数据输出为文本格式,然后在其上创建一个表,它工作正常:
hive> create external table page_urls_1346823845675
> (pageurl string, xcount bigint)
> location 's3://mybucket/text-parse/1346823845675/';
OK
Time taken: 0.434 seconds
hive> select * from page_urls_1346823845675 limit 10;
OK
http://0-italy.com/tag/package-deals 643 NULL
http://011.hebiichigo.com/d63e83abff92df5f5913827798251276/d1ca3aaf52b41acd68ebb3bf69079bd1.html 9 NULL
http://01fishing.com/fly-fishing-knots/ 3437 NULL
http://01fishing.com/flyin-slab-creek/ 1005 NULL
...
Run Code Online (Sandbox Code Playgroud)
我尝试使用自定义inputformat:
// My custom input class--very simple
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapred.SequenceFileInputFormat;
public class UrlXCountDataInputFormat extends
SequenceFileInputFormat<Text, LongWritable> { }
Run Code Online (Sandbox Code Playgroud)
我创建表然后:
create external table page_urls_1346823845675_seq
(pageurl string, xcount bigint)
stored …Run Code Online (Sandbox Code Playgroud) 我想使用Apache Spark从/向HDFS读取/写入协议缓冲区消息。我发现了以下建议的方法:
1)使用Google的Gson库将protobuf消息转换为Json,然后由SparkSql对其进行读写。该解决方案在此链接中进行了解释,但是我认为这样做(转换为json)是一项额外的任务。
2)转换为Parquet文件。有这样的parquet-mr和sparksql-protobuf github项目,但是我不想要Parquet文件,因为我总是处理所有列(而不是某些列),并且Parquet Format不会给我带来任何收益(至少我认为)。
3)ScalaPB。可能正是我要找的东西。但是用斯卡拉语言我对此一无所知。我正在寻找基于Java的解决方案。此youtube视频介绍了scalaPB并说明了如何使用它(适用于scala开发人员)。
4)通过使用序列文件,这就是我想要的,但是对此一无所获。因此,我的问题是:如何将protobuf消息写到HDFS上的序列文件中?任何其他建议将是有用的。
5)通过推特的象鸟图书馆。
在我的一个MapReduce任务中,我将BytesWritable重写为KeyBytesWritable,并将ByteWritable重写为ValueBytesWritable.然后我使用SequenceFileOutputFormat输出结果.
我的问题是,当我开始下一个MapReduce任务时,我想将此SequenceFile用作输入文件.那么我怎样才能设置jobclass,以及Mapper类如何识别我之前覆盖的SequenceFile中的键和值?
我明白我可以通过SequenceFile.Reader来读取键和值.
Configuration config = new Configuration();
Path path = new Path(PATH_TO_YOUR_FILE);
SequenceFile.Reader reader = new SequenceFile.Reader(FileSystem.get(config), path, config);
WritableComparable key = (WritableComparable) reader.getKeyClass().newInstance();
Writable value = (Writable) reader.getValueClass().newInstance();
while (reader.next(key, value))
Run Code Online (Sandbox Code Playgroud)
但我不知道如何使用此Reader将键和值作为参数传递给Mapper类.我怎样才能将conf.setInputFormat设置为SequenceFileInputFormat,然后让Mapper获取密钥和值?
谢谢