用Hadoop AVRO进行大量小文件的处理(转)
使用 使用使用 使用 HDFS 保存大量小文件的缺点:
1.Hadoop NameNode 在内存中保存所有文件的“元信息”数据。据统计,每一个文件需要消耗 NameNode600 字节内存。如果需要保存大量的小文件会对NameNode 造成极大的压力。
2.如果采用 Hadoop MapReduce 进行小文件的处理,那么 Mapper 的个数就会跟小文件的个数成线性相关(备注:FileInputFormat 默认只对大于 HDFS Block Size的文件进行划分)。如果小文件特别多,MapReduce 就会在消耗大量的时间进行Map 进程的创建和销毁。
为了解决大量小文件带来的问题,我们可以将很多小文件打包,组装成一个大文件。 Apache Avro 是语言独立的数据序列化系统。 Avro 在概念上分为两部分:模式(Schema)和数据(一般为二进制数据)。Schema 一般采用 Json 格式进行描述。Avro 同时定义了一些自己的数据类型如表所示:
Avro基础数据类型
|
类型 |
描述 |
模式 |
|
null |
The absence of a value |
"null" |
|
boolean |
A binary value |
"boolean" |
|
int |
32位带符号整数 |
"int" |
|
long |
64位带符号整数 |
"long" |
|
float |
32位单精度浮点数 |
"float" |
|
double |
64位双精度浮点数 |
"double" |
|
bytes |
byte数组 |
"bytes" |
|
string |
Unicode字符串 |
"string" |
|
类型 |
描述 |
模式 |
|
array |
An ordered collection of objects. All objects in a particular array must have the same schema. |
{ "type": "array", "items": "long" } |
|
map |
An unordered collection of key-value pairs. Keys must be strings and values may be any type, although within a particular map, all values must have the same schema. |
{ "type": "map", "values": "string" } |
|
record |
A collection of named fields of any type. |
{ "type": "record", "name": "WeatherRecord", "doc": "A weather reading.", "fields": [ {"name": "year", "type": "int"}, {"name": "temperature", "type": "int"}, {"name": "stationId", "type": "string"} ] } |
|
enum |
A set of named values. |
{ "type": "enum", "name": "Cutlery", "doc": "An eating utensil.", "symbols": ["KNIFE", "FORK", "SPOON"] } |
|
fixed |
A fixed number of 8-bit unsigned bytes. |
{ "type": "fixed", "name": "Md5Hash", "size": 16 } |
|
union |
A union of schemas. A union is represented by a JSON array, where each element in the array is a schema. Data represented by a union must match one of the schemas in the union. |
[ "null", "string", {"type": "map", "values": "string"} ] |
Avro复杂数据类型
通过上图所示,通过程序可以将本地的小文件进行打包,组装成一个大文件在HDFS中进行保存,本地的小文件成为Avro的记录。具体的程序如下面的代码所示:
- public class Demo {
- public static final String FIELD_CONTENTS = "contents";
- public static final String FIELD_FILENAME = "filename";
- public static final String SCHEMA_JSON = "{\"type\": \"record\",\"name\": \"SmallFilesTest\", "
- + "\"fields\": ["
- + "{\"name\":\""
- + FIELD_FILENAME
- + "\",\"type\":\"string\"},"
- + "{\"name\":\""
- + FIELD_CONTENTS
- + "\", \"type\":\"bytes\"}]}";
- public static final Schema SCHEMA = new Schema.Parser().parse(SCHEMA_JSON);
- public static void writeToAvro(File srcPath, OutputStream outputStream) throws IOException {
- DataFileWriter<Object> writer = new DataFileWriter<Object>(new GenericDatumWriter<Object>()).setSyncInterval(100);
- writer.setCodec(CodecFactory.snappyCodec());
- writer.create(SCHEMA, outputStream);
- for (Object obj : FileUtils.listFiles(srcPath, null, false)){
- File file = (File) obj;
- String filename = file.getAbsolutePath();
- byte content[] = FileUtils.readFileToByteArray(file);
- GenericRecord record = new GenericData.Record(SCHEMA);
- record.put(FIELD_FILENAME, filename);
- record.put(FIELD_CONTENTS, ByteBuffer.wrap(content));
- writer.append(record);
- System.out.println(file.getAbsolutePath() + ":"+ DigestUtils.md5Hex(content));
- }
- IOUtils.cleanup(null, writer);
- IOUtils.cleanup(null, outputStream);
- }
- public static void main(String args[]) throws Exception {
- Configuration config = new Configuration();
- FileSystem hdfs = FileSystem.get(config);
- File sourceDir = new File(args[0]);
- Path destFile = new Path(args[1]);
- OutputStream os = hdfs.create(destFile);
- writeToAvro(sourceDir, os);
- }
- }
- public class Demo {
- private static final String FIELD_FILENAME = "filename";
- private static final String FIELD_CONTENTS = "contents";
- public static void readFromAvro(InputStream is) throws IOException {
- DataFileStream<Object> reader = new DataFileStream<Object>(is,new GenericDatumReader<Object>());
- for (Object o : reader) {
- GenericRecord r = (GenericRecord) o;
- System.out.println(r.get(FIELD_FILENAME)+ ":"+DigestUtils.md5Hex(((ByteBuffer)r.get(FIELD_CONTENTS)).array()));
- }
- IOUtils.cleanup(null, is);
- IOUtils.cleanup(null, reader);
- }
- public static void main(String... args) throws Exception {
- Configuration config = new Configuration();
- FileSystem hdfs = FileSystem.get(config);
- Path destFile = new Path(args[0]);
- InputStream is = hdfs.open(destFile);
- readFromAvro(is);
- }
- }
用Hadoop AVRO进行大量小文件的处理(转)的更多相关文章
- Hadoop记录-hive merge小文件
1. Map输入合并小文件对应参数:set mapred.max.split.size=256000000; #每个Map最大输入大小set mapred.min.split.size.per.no ...
- hadoop 使用map合并小文件到SequenceFile
上一例是直接用SequenceFile的createWriter来实现,本例采用mapreduce的方式. 1.把小文件整体读入需要自定义InputFormat格式,自定义InputFormat格式需 ...
- Hadoop实战项目:小文件合并
项目背景 在实际项目中,输入数据往往是由许多小文件组成,这里的小文件是指小于HDFS系统Block大小的文件(默认128M),早期的版本所定义的小文件是64M,这里的hadoop-2.2.0所定义的小 ...
- hadoop文件系统上的小文件合并-Hadoop Archives
1. 什么是Hadoop archives Hadoop archives是特殊的档案格式.一个Hadoop archive对应一个文件系统目录. Hadoop archive的扩展名是.har.Ha ...
- [大牛翻译系列]Hadoop(17)MapReduce 文件处理:小文件
5.1 小文件 大数据这个概念似乎意味着处理GB级乃至更大的文件.实际上大数据可以是大量的小文件.比如说,日志文件通常增长到MB级时就会存档.这一节中将介绍在HDFS中有效地处理小文件的技术. 技术2 ...
- Hadoop MapReduce编程 API入门系列之小文件合并(二十九)
不多说,直接上代码. Hadoop 自身提供了几种机制来解决相关的问题,包括HAR,SequeueFile和CombineFileInputFormat. Hadoop 自身提供的几种小文件合并机制 ...
- 将众多小文件输入Hadoop的解决方案 可挂载的HDFS
配置HDFS为可挂载后: 1-可挂载后才支持非完整POSIX语义: 2-仍然不支持随机写入,仍然为“一次写入,多次读取”: 3-可能误用,导致众多小文件: : 1-使用Solr存储和检索小文件: 2- ...
- Hadoop合并小文件的几种方法
1.Hadoop HAR 将众多小文件打包成一个大文件进行存储,并且打包后原来的文件仍然可以通过Map-Reduce进行操作,打包后的文件由索引和存储两大部分组成: 缺点: 一旦创建就不能修改,也不支 ...
- Hive如何处理小文件问题?
一.小文件是如何产生的 1.动态分区插入数据,产生大量的小文件,从而导致map数量剧增. 2.reduce数量越多,小文件也越多(reduce的个数和输出文件是对应的). 3.数据源本身就包含大量的小 ...
随机推荐
- MySQL数据库InnoDB存储引擎中的锁机制(转载)
http://www.uml.org.cn/sjjm/201205302.asp 00 – 基本概念 当并发事务同时访问一个资源的时候,有可能导致数据不一致.因此需要一种致机制来将访问顺序化. 锁就是 ...
- hadoop本地运行模式调试
一:简介 最近学习hadoop本地运行模式,在运行期间遇到一些问题,记录下来备用:以运行hadoop下wordcount为例子. hadoop程序是在集群运行还是在本地运行取决于下面两个参数的设置,第 ...
- NFS应用场景及环境搭建
两台虚拟机,一台做服务端(server)用来存储,一台做客户端(client)用来访问. 注意,两台虚拟机都已经挂载完光盘,并配置好yum源.客户端client已经安装好lamp环境,服务端不做任何处 ...
- [UE4]控制流
虽然官方文档说复杂的蓝图循环是会跨域多帧运行,但实际上测试下来,如果在循环体进行大量复杂的运算,不足以在一帧内完成时,游戏就会在当前帧卡住,直到循环结束为止. 一.Switch Switch可以在所有 ...
- 知识点:MySQL表名不区分大小写的设置方法
在用centox安装mysql后,把项目的数据库移植了过去,发现一些表的数据查不到,排查了一下问题,最后发现是表名的大小写不一致造成的. mysql在windows系统下安装好后,默认是对表名大小写不 ...
- Jupyter配置步骤
Jupyter是基于浏览器的可交互式开发工具,在数据科学界非常受欢迎,它功能齐全,使用方便,是一款数据分析和建模挖掘的利器. 本文简介Jupyter的配置和使用过程 一.修改添加国内镜像 通常我会先安 ...
- react 数据管理之state思想指南
react的数据管理库有不少,最常听到的可能是mobx redux altjs之类的,当然还有很多其他,可以自己搜索. 为什么需要数据管理库呢,因为react本身只是为了实现view的表现,而不是数据 ...
- Javascript异步编程的4种方法(阮一峰)
转载: http://www.ruanyifeng.com/blog/2012/12/asynchronous%EF%BC%BFjavascript.html 你可能知道,Javascript语言的执 ...
- CS229 1 .线性回归与特征归一化(feature scaling)
线性回归是一种回归分析技术,回归分析本质上就是一个函数估计的问题(函数估计包括参数估计和非参数估计),就是找出因变量和自变量之间的因果关系.回归分析的因变量是应该是连续变量,若因变量为离散变量,则问题 ...
- 配置MySQL GTID(Global Transaction IDs)复制
一.GTID的简介 1.GTID的概述 .全局事物标识:global transaction identifieds. .GTID事物是全局唯一性的,且一个事务对应一个GTID. .一个GTID在一个 ...