使用 使用使用 使用 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的记录。具体的程序如下面的代码所示:

  1. public class Demo {
  2. public static final String FIELD_CONTENTS = "contents";
  3. public static final String FIELD_FILENAME = "filename";
  4. public static final String SCHEMA_JSON = "{\"type\": \"record\",\"name\": \"SmallFilesTest\", "
  5. + "\"fields\": ["
  6. + "{\"name\":\""
  7. + FIELD_FILENAME
  8. + "\",\"type\":\"string\"},"
  9. + "{\"name\":\""
  10. + FIELD_CONTENTS
  11. + "\", \"type\":\"bytes\"}]}";
  12. public static final Schema SCHEMA = new Schema.Parser().parse(SCHEMA_JSON);
  13. public static void writeToAvro(File srcPath, OutputStream outputStream) throws IOException {
  14. DataFileWriter<Object> writer = new  DataFileWriter<Object>(new GenericDatumWriter<Object>()).setSyncInterval(100);
  15. writer.setCodec(CodecFactory.snappyCodec());
  16. writer.create(SCHEMA, outputStream);
  17. for (Object obj : FileUtils.listFiles(srcPath, null, false)){
  18. File file = (File) obj;
  19. String filename = file.getAbsolutePath();
  20. byte content[] = FileUtils.readFileToByteArray(file);
  21. GenericRecord record = new GenericData.Record(SCHEMA);
  22. record.put(FIELD_FILENAME, filename);
  23. record.put(FIELD_CONTENTS, ByteBuffer.wrap(content));
  24. writer.append(record);
  25. System.out.println(file.getAbsolutePath() + ":"+ DigestUtils.md5Hex(content));
  26. }
  27. IOUtils.cleanup(null, writer);
  28. IOUtils.cleanup(null, outputStream);
  29. }
  30. public static void main(String args[]) throws Exception {
  31. Configuration config = new Configuration();
  32. FileSystem hdfs = FileSystem.get(config);
  33. File sourceDir = new File(args[0]);
  34. Path destFile = new Path(args[1]);
  35. OutputStream os = hdfs.create(destFile);
  36. writeToAvro(sourceDir, os);
  37. }
  38. }
    1. public class Demo {
    2. private static final String FIELD_FILENAME = "filename";
    3. private static final String FIELD_CONTENTS = "contents";
    4. public static void readFromAvro(InputStream is) throws  IOException {
    5. DataFileStream<Object> reader = new DataFileStream<Object>(is,new GenericDatumReader<Object>());
    6. for (Object o : reader) {
    7. GenericRecord r = (GenericRecord) o;
    8. System.out.println(r.get(FIELD_FILENAME)+ ":"+DigestUtils.md5Hex(((ByteBuffer)r.get(FIELD_CONTENTS)).array()));
    9. }
    10. IOUtils.cleanup(null, is);
    11. IOUtils.cleanup(null, reader);
    12. }
    13. public static void main(String... args) throws Exception {
    14. Configuration config = new Configuration();
    15. FileSystem hdfs = FileSystem.get(config);
    16. Path destFile = new Path(args[0]);
    17. InputStream is = hdfs.open(destFile);
    18. readFromAvro(is);
    19. }
    20. }

用Hadoop AVRO进行大量小文件的处理(转)的更多相关文章

  1. Hadoop记录-hive merge小文件

    1. Map输入合并小文件对应参数:set mapred.max.split.size=256000000;  #每个Map最大输入大小set mapred.min.split.size.per.no ...

  2. hadoop 使用map合并小文件到SequenceFile

    上一例是直接用SequenceFile的createWriter来实现,本例采用mapreduce的方式. 1.把小文件整体读入需要自定义InputFormat格式,自定义InputFormat格式需 ...

  3. Hadoop实战项目:小文件合并

    项目背景 在实际项目中,输入数据往往是由许多小文件组成,这里的小文件是指小于HDFS系统Block大小的文件(默认128M),早期的版本所定义的小文件是64M,这里的hadoop-2.2.0所定义的小 ...

  4. hadoop文件系统上的小文件合并-Hadoop Archives

    1. 什么是Hadoop archives Hadoop archives是特殊的档案格式.一个Hadoop archive对应一个文件系统目录. Hadoop archive的扩展名是.har.Ha ...

  5. [大牛翻译系列]Hadoop(17)MapReduce 文件处理:小文件

    5.1 小文件 大数据这个概念似乎意味着处理GB级乃至更大的文件.实际上大数据可以是大量的小文件.比如说,日志文件通常增长到MB级时就会存档.这一节中将介绍在HDFS中有效地处理小文件的技术. 技术2 ...

  6. Hadoop MapReduce编程 API入门系列之小文件合并(二十九)

    不多说,直接上代码. Hadoop 自身提供了几种机制来解决相关的问题,包括HAR,SequeueFile和CombineFileInputFormat. Hadoop 自身提供的几种小文件合并机制 ...

  7. 将众多小文件输入Hadoop的解决方案 可挂载的HDFS

    配置HDFS为可挂载后: 1-可挂载后才支持非完整POSIX语义: 2-仍然不支持随机写入,仍然为“一次写入,多次读取”: 3-可能误用,导致众多小文件: : 1-使用Solr存储和检索小文件: 2- ...

  8. Hadoop合并小文件的几种方法

    1.Hadoop HAR 将众多小文件打包成一个大文件进行存储,并且打包后原来的文件仍然可以通过Map-Reduce进行操作,打包后的文件由索引和存储两大部分组成: 缺点: 一旦创建就不能修改,也不支 ...

  9. Hive如何处理小文件问题?

    一.小文件是如何产生的 1.动态分区插入数据,产生大量的小文件,从而导致map数量剧增. 2.reduce数量越多,小文件也越多(reduce的个数和输出文件是对应的). 3.数据源本身就包含大量的小 ...

随机推荐

  1. MySQL数据库InnoDB存储引擎中的锁机制(转载)

    http://www.uml.org.cn/sjjm/201205302.asp 00 – 基本概念 当并发事务同时访问一个资源的时候,有可能导致数据不一致.因此需要一种致机制来将访问顺序化. 锁就是 ...

  2. hadoop本地运行模式调试

    一:简介 最近学习hadoop本地运行模式,在运行期间遇到一些问题,记录下来备用:以运行hadoop下wordcount为例子. hadoop程序是在集群运行还是在本地运行取决于下面两个参数的设置,第 ...

  3. NFS应用场景及环境搭建

    两台虚拟机,一台做服务端(server)用来存储,一台做客户端(client)用来访问. 注意,两台虚拟机都已经挂载完光盘,并配置好yum源.客户端client已经安装好lamp环境,服务端不做任何处 ...

  4. [UE4]控制流

    虽然官方文档说复杂的蓝图循环是会跨域多帧运行,但实际上测试下来,如果在循环体进行大量复杂的运算,不足以在一帧内完成时,游戏就会在当前帧卡住,直到循环结束为止. 一.Switch Switch可以在所有 ...

  5. 知识点:MySQL表名不区分大小写的设置方法

    在用centox安装mysql后,把项目的数据库移植了过去,发现一些表的数据查不到,排查了一下问题,最后发现是表名的大小写不一致造成的. mysql在windows系统下安装好后,默认是对表名大小写不 ...

  6. Jupyter配置步骤

    Jupyter是基于浏览器的可交互式开发工具,在数据科学界非常受欢迎,它功能齐全,使用方便,是一款数据分析和建模挖掘的利器. 本文简介Jupyter的配置和使用过程 一.修改添加国内镜像 通常我会先安 ...

  7. react 数据管理之state思想指南

    react的数据管理库有不少,最常听到的可能是mobx redux altjs之类的,当然还有很多其他,可以自己搜索. 为什么需要数据管理库呢,因为react本身只是为了实现view的表现,而不是数据 ...

  8. Javascript异步编程的4种方法(阮一峰)

    转载: http://www.ruanyifeng.com/blog/2012/12/asynchronous%EF%BC%BFjavascript.html 你可能知道,Javascript语言的执 ...

  9. CS229 1 .线性回归与特征归一化(feature scaling)

    线性回归是一种回归分析技术,回归分析本质上就是一个函数估计的问题(函数估计包括参数估计和非参数估计),就是找出因变量和自变量之间的因果关系.回归分析的因变量是应该是连续变量,若因变量为离散变量,则问题 ...

  10. 配置MySQL GTID(Global Transaction IDs)复制

    一.GTID的简介 1.GTID的概述 .全局事物标识:global transaction identifieds. .GTID事物是全局唯一性的,且一个事务对应一个GTID. .一个GTID在一个 ...