从HDFS将Avro文件加载到pyspark数据帧中

时间:2018-09-03 19:12:03

标签: python apache-spark pyspark apache-spark-sql avro

我建立了一个小的数据管道,该管道将一些虚构的测试数据从本地目录(json格式)移动到hdfs(avro格式)。这似乎已经正常工作(水槽未显示任何错误),但这种情况可能已经存在于此处。下一步是使用databricks加载程序将avro文件转换为pyspark数据帧(我只能为此找到python库)。现在,让我解释一下我是如何做到的,这样您就可以看到我可能失败的地方:

1)通过使用flume从json文件中创建avro文件

我的目标是将json数据从本地目录推送到HDFS,因此我可以使用pySpark对其进行分析。为此,我正在使用水槽。由于json在HDFS上的压缩质量很差,因此我还将使用以下flume.conf将每个文件转换为avro:

agent.sources.tail.type = exec
agent.sources.tail.shell = /bin/bash -c
agent.sources.tail.command = cat /home/user/Data/json/*
agent.sources.tail.batchsize = 10
agent.sources.tail.channels = MemChannel

agent.channels.MemChannel.type = memory
agent.channels.MemChannel.capacity = 100
agent.channels.MemChannel.transactionCapacity = 100


agent.sinks.HDFS.channel = MemChannel
agent.sinks.HDFS.type = hdfs
agent.sinks.HDFS.hdfs.fileType = DataStream
agent.sinks.HDFS.hdfs.fileSuffix=.avro
agent.sinks.HDFS.hdfs.path = hdfs://localhost:9000/home/user/Data/hdfs/test_data
agent.sinks.HDFS.hdfs.batchSize = 100
agent.sinks.HDFS.hdfs.rollSize = 0
agent.sinks.HDFS.hdfs.rollCount = 100
agent.sinks.HDFS.serializer=avro_event
agent.sinks.HDFS.serializer.compressionCodec=snappy

这确实没有任何错误,所以我假设flume将每个文件作为正确的avro文件移动到HDFS。

2)通过加载avro文件创建数据框

现在是我试图读取一个avro文件作为pyspark中的数据帧的部分:

from pyspark.sql.types import *
from pyspark.sql import SQLContext
from pyspark import SparkContext
sc = SparkContext()
sqlContext = SQLContext(sc)
sqlContext.setConf("spark.sql.avro.compression.codec","snappy") 

# creates a dataframe by reading a single avro file 
df = sqlContext.read.format("com.databricks.spark.avro").load("hdfs://localhost:9000/home/user/Data/hdfs/test_data/FlumeData.1535723039267.avro")

这向我显示以下(错误)输出:

df.show()
+-------+--------------------+
|headers|                body|
+-------+--------------------+
|     []|[7B 22 63 61 74 6...|
|     []|[7B 22 63 61 74 6...|
|     []|[7B 22 63 61 74 6...|
|     []|[7B 22 63 61 74 6...|
|     []|[7B 22 63 61 74 6...|
+-------+--------------------+
only showing top 5 rows

这显然不是我想要的,因为上面的整个代码似乎像读取纯文本文件一样读取avro文件,因此没有解析结构。以前,我只是创建一个使用相同数据但存储在原始json文件中的数据框。

# creates a dataframe by reading a single json file
df = sqlContext.read.json('hdfs://localhost:9000/home/user/Data/hdfs/test_data/FlumeData.1535702513118.json')

所以这是所需(正确)输出的样子:

df.show()
+---------------+--------------------+---+-------------------+-----------------+
|       category|             content| id|          timestamp|             user|
+---------------+--------------------+---+-------------------+-----------------+
|              A|Million near orde...|801|2018-08-30_16:49:53|      Molly Davis|
|              D|Determine company...|802|2018-08-30_16:49:53|       Ronnie Liu|
|              B|Among themselves ...|803|2018-08-30_16:49:53|       Lori Brown|
|              C|Through various d...|804|2018-08-30_16:49:53|   Judith Herrera|
|              C|Week toward so co...|805|2018-08-30_16:49:53|Teresa Cunningham|
+---------------+--------------------+---+-------------------+-----------------+
only showing top 5 rows

如何为转换后的avro文件获得相同的结果?

0 个答案:

没有答案