这是一篇翻译,原文来自:How to load some Avro data into Spark

首先,为什么使用 Avro ?

最基本的格式是 CSV ,其廉价并且不需要顶一个一个 schema 和数据关联。

随后流行起来的一个通用的格式是 XML,其有一个 schema 和 数据关联,XML 广泛的使用于 Web Services 和 SOA 架构中。不幸的是,其非常冗长,并且解析 XML 需要消耗内存。

另外一种格式是 JSON,其非常流行易于使用因为它非常方便易于理解。

这些格式在 Big Data 环境中都是不可拆分的,这使得他们难于使用。在他们之上使用一个压缩机制(Snappy,Gzip)并不能解决这个问题。

因此不同的数据格式出现了。Avro 作为一种序列化平台被广泛使用,因为它能跨语言,提供了一个小巧紧凑的快速的二进制格式,支持动态 schema 发现(通过它的泛型)和 schema 演变,并且是可压缩和拆分的。它还提供了复杂的数据结构,例如嵌套类型。

例子

让我们来看一个例子,创建一个 Avro schema 并生成一些数据。在一个真实案例的例子中,组织机构通常有一些更加普通的格式,例如 XML,的数据,并且他们需要通过一些工具例如 JAXB 将他们的数据转换成 Avro。我们来使用这个例子,其中 twitter.avsc 如下:

{
"type" : "record",
"name" : "twitter_schema",
"namespace" : "com.miguno.avro",
"fields" : [
{ "name" : "username",
"type" : "string",
"doc" : "Name of the user account on Twitter.com" },
{
"name" : "tweet",
"type" : "string",
"doc" : "The content of the user's Twitter message" },
{
"name" : "timestamp",
"type" : "long",
"doc" : "Unix epoch time in seconds" }
],
"doc:" : "A basic schema for storing Twitter messages"
}

twitter.json 中有一些数据:

{"username":"miguno","tweet":"Rock: Nerf paper, scissors is fine.","timestamp": 1366150681 }
{"username":"BlizzardCS","tweet":"Works as intended. Terran is IMBA.","timestamp": 1366154481 }

我们将这些数据转换成二进制的 Avro 格式:

$ java -jar ~/avro-tools-1.7.7.jar fromjson --schema-file twitter.avsc twitter.json > twitter.avro

然后,我们将 Avro 数据转换为 Java:

$ java -jar /app/avro/avro-tools-1.7.7.jar compile schema /app/avro/data/twitter.avsc /app/avro/data/

现在,我们编译这些类并将其打包:

$ CLASSPATH=/app/avro/avro-1.7.7-javadoc.jar:/app/avro/avro-mapred-1.7.7-hadoop1.jar:/app/avro/avro-tools-1.7.7.jar
$ javac -classpath $CLASSPATH /app/avro/data/com/miguno/avro/twitter_schema.java
$ jar cvf Twitter.jar com/miguno/avro/*.class

我们启动 Spark,并将上面创建的 Jar 和一些需要的库(Hadoop 和 Avro)传递给 Spark 程序:

$ ./bin/spark-shell --jars /app/avro/avro-mapred-1.7.7-hadoop1.jar,/avro/avro-1.7.7.jar,/app/avro/data/Twitter.jar

在 REPL 中,我们获取数据并创建一个 RDD:

scala>
import com.miguno.avro.twitter_schema
import org.apache.avro.file.DataFileReader;
import org.apache.avro.file.DataFileWriter;
import org.apache.avro.io.DatumReader;
import org.apache.avro.io.DatumWriter;
import org.apache.avro.specific.SpecificDatumReader;
import org.apache.avro.mapreduce.AvroKeyInputFormat
import org.apache.avro.mapred.AvroKey
import org.apache.hadoop.io.NullWritable
import org.apache.avro.mapred.AvroInputFormat
import org.apache.avro.mapred.AvroWrapper
import org.apache.avro.generic.GenericRecord
import org.apache.avro.mapred.{AvroInputFormat, AvroWrapper}
import org.apache.hadoop.io.NullWritable val path = "/app/avro/data/twitter.avro"
val avroRDD = sc.hadoopFile[AvroWrapper[GenericRecord], NullWritable, AvroInputFormat[GenericRecord]](path)
avroRDD.map(l => new String(l._1.datum.get("username").toString() ) ).first

返回结果:

res2: String = miguno

一些注意事项:

翻译结束。


接下来,我将上述过程在 CDH 5.3 集群中测试一遍。

验证

首先,在集群一个节点创建 twitter.avsc 和 twitter.json 两个文件。

然后,使用 avro-tools 将这些数据转换成二进制的 Avro 格式:

$ java -jar /usr/lib/avro/avro-tools.jar fromjson --schema-file twitter.avsc twitter.json > twitter.avro

这时候会生成 avro 文件:

$ ll
总用量 12
-rw-r--r-- 1 root root 543 3月 25 15:13 twitter.avro
-rw-r--r-- 1 root root 590 3月 25 15:12 twitter.avsc
-rw-r--r-- 1 root root 191 3月 25 15:12 twitter.json

将 Avro 数据转换为 Java:

$ java -jar /usr/lib/avro/avro-tools.jar compile schema twitter.avsc .

这时候会生成 twitter_schema.java 文件:

$ tree
.
├── com
│   └── miguno
│   └── avro
│   └── twitter_schema.java
├── twitter.avro
├── twitter.avsc
└── twitter.json

这时候会生成一个 Twitter.jar 的 jar 包。

编译这些类并将其打包:

$ CLASSPATH=/usr/lib/avro/avro-mapred-hadoop2.jar:/usr/lib/avro/avro-tools.jar
$ javac -classpath $CLASSPATH com/miguno/avro/twitter_schema.java
$ jar cvf Twitter.jar com/miguno/avro/*.class

在当前目录,运行 spark-shell:

spark-shell --jars /usr/lib/avro/avro-mapred-hadoop2.jar,/usr/lib/avro/avro.jar,Twitter.jar

将 twitter.avro 上传到 hdfs:

hadoop fs -put twitter.avro

在 REPL 中,我们创建一个 RDD 并查看结果是否和上面一致:

scala>
import com.miguno.avro.twitter_schema;
import org.apache.avro.file.DataFileReader;
import org.apache.avro.file.DataFileWriter;
import org.apache.avro.io.DatumReader;
import org.apache.avro.io.DatumWriter;
import org.apache.avro.specific.SpecificDatumReader;
import org.apache.avro.mapreduce.AvroKeyInputFormat
import org.apache.avro.mapred.AvroKey
import org.apache.hadoop.io.NullWritable
import org.apache.avro.mapred.AvroInputFormat
import org.apache.avro.mapred.AvroWrapper
import org.apache.avro.generic.GenericRecord
import org.apache.avro.mapred.{AvroInputFormat, AvroWrapper}
import org.apache.hadoop.io.NullWritable val path = "twitter.avro"
val avroRDD = sc.hadoopFile[AvroWrapper[GenericRecord], NullWritable, AvroInputFormat[GenericRecord]](path)
avroRDD.map(l => new String(l._1.datum.get("username").toString() ) ).first

更多的 Avro Tools 用法,可以参考 Avro 介绍

spark使用scala读取Avro数据(转)的更多相关文章

  1. Spark使用Java读取mysql数据和保存数据到mysql

    原文引自:http://blog.csdn.net/fengzhimohan/article/details/78471952 项目应用需要利用Spark读取mysql数据进行数据分析,然后将分析结果 ...

  2. Spark使用Java、Scala 读取mysql、json、csv数据以及写入操作

    Spark使用Java读取mysql数据和保存数据到mysql 一.pom.xml 二.spark代码 2.1 Java方式 2.2 Scala方式 三.写入数据到mysql中 四.DataFrame ...

  3. Spark学习笔记4:数据读取与保存

    Spark对很多种文件格式的读取和保存方式都很简单.Spark会根据文件扩展名选择对应的处理方式. Spark支持的一些常见文件格式如下: 文本文件 使用文件路径作为参数调用SparkContext中 ...

  4. Spark读取elasticsearch数据指南

    最近要在 Spark job 中通过 Spark SQL 的方式读取 Elasticsearch 数据,踩了一些坑,总结于此. 环境说明 Spark job 的编写语言为 Scala,scala-li ...

  5. Kafka:ZK+Kafka+Spark Streaming集群环境搭建(二十九):推送avro格式数据到topic,并使用spark structured streaming接收topic解析avro数据

    推送avro格式数据到topic 源代码:https://github.com/Neuw84/structured-streaming-avro-demo/blob/master/src/main/j ...

  6. spark通过JDBC读取外部数据库,过滤数据

    官网链接: http://spark.apache.org/docs/latest/sql-programming-guide.html#jdbc-to-other-databases http:// ...

  7. spark读取kafka数据 createStream和createDirectStream的区别

    1.KafkaUtils.createDstream 构造函数为KafkaUtils.createDstream(ssc, [zk], [consumer group id], [per-topic, ...

  8. scala实现读取Oracle数据

    用scala实现读取oracle数据 增加oralce的jar包后 package cn.bigdata.scala.oracle import java.sql.{DriverManager, Co ...

  9. 毕设三: spark与phoenix集成插入数据/解析json数组

    需求:将前些日子采集的评论存储到hbase中 思路: 先用fastjson解析评论,然后构造rdd,最后使用spark与phoenix交互,把数据存储到hbase中 部分数据: [ { "r ...

随机推荐

  1. Spring AOP 之编译期织入、装载期织入、运行时织入(转)

    https://blog.csdn.net/wenbingoon/article/details/22888619 一   前言 AOP 实现的关键就在于 AOP 框架自动创建的 AOP 代理,AOP ...

  2. 头皮溢脂性皮炎推荐联合治疗:采乐50ml+希尔生100g(请看详情页)维生素B2维生素B6

    治疗头皮脂溢性皮炎采乐50ml+希尔生100g联合用药用法:用药先用一般香皂清洗头发及头皮,头皮处于湿润状态,取适量希尔生洗剂涂于头皮表面,充分揉搓出泡沫样5 min后用清水冲净抹干,再将适量采乐洗剂 ...

  3. [UE4]宏

    宏和函数的区别 “展开”就是直接将宏代码直接复制粘贴替换到所有使用当前宏的地方.这个跟C++中的宏是一样的. 1.宏可以有多个入口,多个出口,函数只有一个入口,一个出口 2.宏的参数可以使用“Exec ...

  4. tensorFlow 三种启动图的用法

    tf.Session(),tf.InteractivesSession(),tf.train.Supervisor().managed_session()  用法的区别: tf.Session() 构 ...

  5. 将.ipynb文件导入到另外的文件中

    在定义函数或者类的.ipyter文件的末尾加上 try: !jupyter nbconvert --to python ppp.ipynb #ppp是文件的名称 except: pass 在需要导入到 ...

  6. 三种方式控制GPIO

    BBB为REV C,emmc4G版本,系统为Debian 7.9 wheezy (2015.11.12),内核为Linux 3.8.13.使用命令cat /etc/dogtag查看 查看系统信息的四种 ...

  7. django前篇

    http协议 HTTP简介 HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本 ...

  8. python各种推导式

    字典推导式 例一:将一个字典的key和value对调 mcase = {, } mcase_frequency = {mcase[k]: k for k in mcase} print(mcase_f ...

  9. 升级Android Studio到1.0.2的问题解决

    当前从光网下载到的Android Studio的版本是1.0.1,升级到1.0.2大概是3M的升级包.升级很简单,点击Help--Check For Update... 可是我碰到的情况是提示:Con ...

  10. 07 grep命令与正则表达式

    grep命令 首先我们知道grep命令是用来做文件内容过滤的!如果你要在文件中查找一些对应的内容,我们如何来过滤找到其中我们需要符合条件的内容呢?grep命令结合正则表达式就可以实现: grep.eg ...