有一个设想
当有持续不断的结构化或非结构化大数据集以流(streaming)的方式进入分布式计算平台, 能够保存在大规模分布式存储上,并且能够提供准实时SQL查询,这个系统多少人求之不得。
今天,咱们就来介绍一下这个计算框架和过程。
问题分解一下
数据哪里来?
假设,你已经有一个数据收集的引擎或工具(不在本博客讨论范围内,请出门左转Google右转百度),怎么都行, 反正数据能以流的方式给出来,塞进Kafka类似的消息系统。
结构化?非结构化?如何识别业务信息?
关于结构化或非结构化,也不在今天的主要讨论范围,但是,必须要说明的是, 你的数据能够以某种规则进行正则化,比如:空格分隔,CSV,JSON等。咱们今天以Apache网站日志数据作为参照。
类似如下:
124.67.32.161 - - [10/Apr/2016:05:37:36 +0800] "GET /blog/app_backend.html HTTP/1.1" 200 26450
如何处理?写到哪里去?
拿到数据,我们需要一些处理,将业务逻辑分离开来,做成二维表,行列分明,就像是关系型数据库的表。这个事情有Spark DataFrame来完成。
就像写入关系型数据库一样,我们需要将DataFrame写入某处,这里,就是Parquet文件,天然支持schema,太棒了。
怎么取出来?还能是SQL?
我们的数据已经被当做“二维表,Table”写入了Parquet,取出来当然也得是“表”或其他什么的,当然最好是能暴露出JDBC SQL,相关人员使用起来就方便了。
这个事情交给Spark的 SparkThriftServer 来完成。
设计蓝图
以上分解似乎完美,一起来看看“设计框架”或“蓝图”。
[图片上传失败...(image-fe3774-1542717299721)]
算了,不解释了,图,自己看。
Coding Style
从Kafka Stream获取数据
// 从Kafka Stream获取数据 JavaPairInputDStream<String, String> messages = KafkaUtils.createDirectStream(jssc, String.class, String.class, StringDecoder.class, StringDecoder.class, kafkaParams, topicsSet);
写入Parquet
accessLogsDStream.foreachRDD(rdd -> { // 如果DF不为空,写入(增加模式)到Parquet文件 DataFrame df = sqlContext.createDataFrame(rdd, ApacheAccessLog.class); if (df.count() > 0) { df.write().mode(SaveMode.Append).parquet(Flags.getInstance().getParquetFile()); } return null; });
创建Hive表
使用spark-shell,获取Parquet文件, 写入一个临时表;
scala代码如下:
import sqlContext.implicits._ val parquetFile = sqlContext.read.parquet("/user/spark/apachelog.parquet") parquetFile.registerTempTable("logs")
复制schema到新表链接到Parquet文件。
在Hive中复制表,这里你会发现,文件LOCATION位置还是原来的路径,目的就是这个,使得新写入的文件还在Hive模型中。
我总觉得这个方法有问题,是不是哪位Hive高人指点一下,有没有更好的办法来完成这个工作?
CREATE EXTERNAL TABLE apachelog LIKE logs STORED AS PARQUET LOCATION '/user/spark/apachelog.parquet';
启动你的SparkThriftServer
当然,在集群中启用ThriftServer是必须的工作,SparkThriftServer其实暴露的是Hive2服务器,用JDBC驱动就可以访问了。
我们都想要的结果
本博客中使用的SQL查询工具是SQuirreL SQL,具体JDBC配置方法请参照前面说的向左向右转。
作者:BillowX
链接:https://www.jianshu.com/p/363c9bfb345d
共同学习,写下你的评论
评论加载中...
作者其他优质文章