Structured Streaming教程(3) —— 与Kafka的集成
Structured Streaming最主要的生产环境应用场景就是配合kafka做实时处理,不过在Strucured Streaming中kafka的版本要求相对搞一些,只支持0.10及以上的版本。就在前一个月,我们才从0.9升级到0.10,终于可以尝试structured streaming的很多用法,很开心~
引入
如果是maven工程,直接添加对应的kafka的jar包即可:
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-sql-kafka-0-10_2.11</artifactId>
<version>2.2.0</version>
</dependency>
读取kafka的数据
以流的形式查询
读取的时候,可以读取某个topic,也可以读取多个topic,还可以指定topic的通配符形式:
读取一个topic
val df = spark
.readStream
.format("kafka")
.option("kafka.bootstrap.servers", "host1:port1,host2:port2")
.option("subscribe", "topic1")
.load()
df.selectExpr("CAST(key AS STRING)", "CAST(value AS STRING)")
.as[(String, String)]
读取多个topic
val df = spark
.readStream
.format("kafka")
.option("kafka.bootstrap.servers", "host1:port1,host2:port2")
.option("subscribe", "topic1,topic2")
.load()
df.selectExpr("CAST(key AS STRING)", "CAST(value AS STRING)")
.as[(String, String)]
读取通配符形式的topic组
val df = spark
.readStream
.format("kafka")
.option("kafka.bootstrap.servers", "host1:port1,host2:port2")
.option("subscribePattern", "topic.*")
.load()
df.selectExpr("CAST(key AS STRING)", "CAST(value AS STRING)")
.as[(String, String)]
以批的形式查询
关于Kafka的offset,structured streaming默认提供了几种方式:
设置每个分区的起始和结束值
val df = spark
.read
.format("kafka")
.option("kafka.bootstrap.servers", "host1:port1,host2:port2")
.option("subscribe", "topic1,topic2")
.option("startingOffsets", """{"topic1":{"0":23,"1":-2},"topic2":{"0":-2}}""")
.option("endingOffsets", """{"topic1":{"0":50,"1":-1},"topic2":{"0":-1}}""")
.load()
df.selectExpr("CAST(key AS STRING)", "CAST(value AS STRING)")
.as[(String, String)]
配置起始和结束的offset值(默认)
val df = spark
.read
.format("kafka")
.option("kafka.bootstrap.servers", "host1:port1,host2:port2")
.option("subscribePattern", "topic.*")
.option("startingOffsets", "earliest")
.option("endingOffsets", "latest")
.load()
df.selectExpr("CAST(key AS STRING)", "CAST(value AS STRING)")
.as[(String, String)]
Schema信息
读取后的数据的Schema是固定的,包含的列如下:
Column | Type | 说明 |
---|---|---|
key | binary | 信息的key |
value | binary | 信息的value(我们自己的数据) |
topic | string | 主题 |
partition | int | 分区 |
offset | long | 偏移值 |
timestamp | long | 时间戳 |
timestampType | int | 类型 |
source相关的配置
无论是流的形式,还是批的形式,都需要一些必要的参数:
- kafka.bootstrap.servers kafka的服务器配置,host:post形式,用逗号进行分割,如host1:9000,host2:9000
- assign,以json的形式指定topic信息
- subscribe,通过逗号分隔,指定topic信息
- subscribePattern,通过java的正则指定多个topic
assign、subscribe、subscribePattern同时之中能使用一个。
其他比较重要的参数有:
- startingOffsets, offset开始的值,如果是earliest,则从最早的数据开始读;如果是latest,则从最新的数据开始读。默认流是latest,批是earliest
- endingOffsets,最大的offset,只在批处理的时候设置,如果是latest则为最新的数据
- failOnDataLoss,在流处理时,当数据丢失时(比如topic被删除了,offset在指定的范围之外),查询是否报错,默认为true。这个功能可以当做是一种告警机制,如果对丢失数据不感兴趣,可以设置为false。在批处理时,这个值总是为true。
- kafkaConsumer.pollTimeoutMs,excutor连接kafka的超时时间,默认是512ms
- fetchOffset.numRetries,获取kafka的offset信息时,尝试的次数;默认是3次
- fetchOffset.retryIntervalMs,尝试重新读取kafka offset信息时等待的时间,默认是10ms
- maxOffsetsPerTrigger,trigger暂时不会用,不太明白什么意思。Rate limit on maximum number of offsets processed per trigger interval. The specified total number of offsets will be proportionally split across topicPartitions of different volume.
写入数据到Kafka
Apache kafka仅支持“至少一次”的语义,因此,无论是流处理还是批处理,数据都有可能重复。比如,当出现失败的时候,structured streaming会尝试重试,但是不会确定broker那端是否已经处理以及持久化该数据。但是如果query成功,那么可以断定的是,数据至少写入了一次。比较常见的做法是,在后续处理kafka数据时,再进行额外的去重,关于这点,其实structured streaming有专门的解决方案。
保存数据时的schema:
- key,可选。如果没有填,那么key会当做null,kafka针对null会有专门的处理(待查)。
- value,必须有
- topic,可选。(如果配置option里面有topic会覆盖这个字段)
下面是sink输出必须要有的参数:
- kafka.bootstrap.servers,kafka的集群地址,host:port格式用逗号分隔。
流处理的数据写入
// 基于配置指定topic
val ds = df
.selectExpr("CAST(key AS STRING)", "CAST(value AS STRING)")
.writeStream
.format("kafka")
.option("kafka.bootstrap.servers", "host1:port1,host2:port2")
.option("topic", "topic1")
.start()
// 在字段中包含topic
val ds = df
.selectExpr("topic", "CAST(key AS STRING)", "CAST(value AS STRING)")
.writeStream
.format("kafka")
.option("kafka.bootstrap.servers", "host1:port1,host2:port2")
.start()
批处理的数据写入
跟流处理其实一样
df.selectExpr("CAST(key AS STRING)", "CAST(value AS STRING)")
.write
.format("kafka")
.option("kafka.bootstrap.servers", "host1:port1,host2:port2")
.option("topic", "topic1")
.save()
df.selectExpr("topic", "CAST(key AS STRING)", "CAST(value AS STRING)")
.write
.format("kafka")
.option("kafka.bootstrap.servers", "host1:port1,host2:port2")
.save()
kafka的特殊配置
针对Kafka的特殊处理,可以通过DataStreamReader.option进行设置。
关于(详细的kafka配置可以参考consumer的官方文档](http://kafka.apache.org/documentation.html#newconsumerconfigs)
注意下面的参数是不能被设置的,否则kafka会抛出异常:
- group.id kafka的source会在每次query的时候自定创建唯一的group id
- auto.offset.reset 为了避免每次手动设置startingoffsets的值,structured streaming在内部消费时会自动管理offset。这样就能保证订阅动态的topic时不会丢失数据。startingOffsets在流处理时,只会作用于第一次启动时,之后的处理都会自定的读取保存的offset。
- key.deserializer,value.deserializer,key.serializer,value.serializer 序列化与反序列化,都是ByteArraySerializer
- enable.auto.commit kafka的source不会提交任何的offset
- interceptor.classes 由于kafka source读取数据都是二进制的数组,因此不能使用任何拦截器进行处理。
参考
Structured Streaming教程(3) —— 与Kafka的集成的更多相关文章
- Structured Streaming教程(2) —— 常用输入与输出
上篇了解了一些基本的Structured Streaming的概念,知道了Structured Streaming其实是一个无下界的无限递增的DataFrame.基于这个DataFrame,我们可以做 ...
- Structured Streaming教程(1) —— 基本概念与使用
近年来,大数据的计算引擎越来越受到关注,spark作为最受欢迎的大数据计算框架,也在不断的学习和完善中.在Spark2.x中,新开放了一个基于DataFrame的无下限的流式处理组件--Structu ...
- Spark Structured Streaming框架(2)之数据输入源详解
Spark Structured Streaming目前的2.1.0版本只支持输入源:File.kafka和socket. 1. Socket Socket方式是最简单的数据输入源,如Quick ex ...
- Spark Structured Streaming框架(5)之进程管理
Structured Streaming提供一些API来管理Streaming对象.用户可以通过这些API来手动管理已经启动的Streaming,保证在系统中的Streaming有序执行. 1. St ...
- Spark Structured Streaming框架(4)之窗口管理详解
1. 结构 1.1 概述 Structured Streaming组件滑动窗口功能由三个参数决定其功能:窗口时间.滑动步长和触发时间. 窗口时间:是指确定数据操作的长度: 滑动步长:是指窗口每次向前移 ...
- Spark Structured Streaming框架(3)之数据输出源详解
Spark Structured streaming API支持的输出源有:Console.Memory.File和Foreach.其中Console在前两篇博文中已有详述,而Memory使用非常简单 ...
- Spark Structured Streaming框架(2)之数据输入源详解
Spark Structured Streaming目前的2.1.0版本只支持输入源:File.kafka和socket. 1. Socket Socket方式是最简单的数据输入源,如Quick ex ...
- Structured Streaming从Kafka 0.8中读取数据的问题
众所周知,Structured Streaming默认支持Kafka 0.10,没有提供针对Kafka 0.8的Connector,但这对高手来说不是事儿,于是有个Hortonworks的邵大牛(前段 ...
- 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 ...
随机推荐
- 单个 LINQ to Entities 查询中的两个结构上不兼容的初始化过程中出现类型“XXXX”
最近在做一个报表的时候,用EF使用了Contact方法,但是程式运行一直出错.最近终于找到原因了,写下来提醒下自己.好了,进入正题: 现在我举个栗子,目前数据库中有ParentStudent表和Sub ...
- centos7.2环境下安装smokeping对网络状态进行监控
centos7.2环境下安装smokeping对网络状态进行监控 安装smokeping建议用centos7,用centos6.5一直卡在smokeping那里,下载不了perl的扩展插件,可能是因为 ...
- sqlserver2008r2通过发布和订阅的方式进行数据库同步
发布服务器:192.168.8.16 订阅服务器:192.168.8.92 发布服务器配置: 选择需要发布的数据库,这里是Attendace_new 订阅服务器配置: 在订阅服务器上新建一个数据库:d ...
- Ex 5_33 实现一个关于公式长度(其中所有文字总的出现次数)为线性时间的Horn公式可满足性问题_第十次作业
对于所有的蕴含式,生成一张有向图,对于每一个蕴含式,将左边的每一个文字连接到一个中间结点,并用中间结点记录蕴含式左边文字的数量,然后将中间结点连接到蕴含式的右侧结点.例如,对于蕴含式集合 生成的有向图 ...
- ajax post 传递数组参数
1.前言 此文章仅作为记录,方便查阅. 2.代码 javascript: var idArr = ['one','two','Three']; $.ajax({ type: 'POST', data ...
- OCM_第一天课程:OCM课程环境搭建
注:本文为原著(其内容来自 腾科教育培训课堂).阅读本文注意事项如下: 1:所有文章的转载请标注本文出处. 2:本文非本人不得用于商业用途.违者将承当相应法律责任. 3:该系列文章目录列表: 一:&l ...
- java.net.ServerSocket 解析
注:本文来自:简书:jianshu 作者:jijs链接:http://www.jianshu.com/p/7c0722a8b66f來源:简书著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注 ...
- String:(字符串)中常用的方法
package stringyiwen; //字符串中常用的方法public class StringTest03 { public static void main(String[] args) { ...
- [转] Java接口_interface_implements
相对抽象类来讲,接口就是比抽象类还要抽象的抽象类,丝毫不带半点实现的内容.接口可以更加规范的对子类进行约束.接口全面地专业地实现了:规范和具体实现的分离.接口就是规范,定义的是一组规则,提现了现实世界 ...
- 让我们了解 Ceph 分布式存储
前言 最近在学习 kubernetes 过程中,想实现 pod 数据的持久化.在调研的过程中,发现 ceph 在最近几年发展火热,也有很多案例落地企业.在选型方面,个人更加倾向于社区火热的项目,Glu ...