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