Spark Streaming自定义Receiver
一 背景
Spark社区为Spark Streaming提供了很多数据源接口,但是有些比较偏的数据源没有覆盖,由于公司技术栈选择,用了阿里云的MQ服务ONS,要做实时需求,要自己编写Receiver
二 技术实现
1.官网的例子已经比较详细,但是进入实践还需要慢慢调试,官方文档。
2.实现代码,由三部分组成,receiver,inputstream,util
3.receiver代码
import java.io.Serializable
import java.util.Properties import com.aliyun.openservices.ons.api._
import com.aliyun.openservices.ons.api.impl.ONSFactoryImpl
import org.apache.spark.internal.Logging
import org.apache.spark.storage.StorageLevel
import org.apache.spark.streaming.receiver.Receiver class OnsReceiver(
cid: String,
accessKey: String,
secretKey: String,
addr: String,
topic: String,
tag: String,
func: Message => Array[Byte])
extends Receiver[Array[Byte]](StorageLevel.MEMORY_AND_DISK_2) with Serializable with Logging {
receiver => private var consumer: Consumer = null
private var workerThread: Thread = null override def onStart(): Unit = {
workerThread = new Thread(new Runnable {
override def run(): Unit = {
val properties = new Properties
properties.put(PropertyKeyConst.ConsumerId, cid)
properties.put(PropertyKeyConst.AccessKey, accessKey)
properties.put(PropertyKeyConst.SecretKey, secretKey)
properties.put(PropertyKeyConst.ONSAddr, addr)
properties.put(PropertyKeyConst.MessageModel, "CLUSTERING")
properties.put(PropertyKeyConst.ConsumeThreadNums, "50")
val onsFactoryImpl = new ONSFactoryImpl
consumer = onsFactoryImpl.createConsumer(properties)
consumer.subscribe(topic, tag, new MessageListener() {
override def consume(message: Message, context: ConsumeContext): Action = {
try {
receiver.store(func(message))
Action.CommitMessage
} catch {
case e: Throwable => e.printStackTrace()
Action.ReconsumeLater
}
}
})
consumer.start()
}
})
workerThread.setName(s"Aliyun ONS Receiver $streamId")
workerThread.setDaemon(true)
workerThread.start()
} override def onStop(): Unit = {
if (workerThread != null) {
if (consumer != null) {
consumer.shutdown()
} workerThread.join()
workerThread = null
logInfo(s"Stopped receiver for streamId $streamId")
}
}
}
input代码
import com.aliyun.openservices.ons.api.Message
import org.apache.spark.streaming.StreamingContext
import org.apache.spark.streaming.dstream.ReceiverInputDStream
import org.apache.spark.streaming.receiver.Receiver class OnsInputDStream(
@transient _ssc: StreamingContext,
cid: String,
topic: String,
tag: String,
accessKey: String,
secretKey: String,
addr:String,
func: Message => Array[Byte]
) extends ReceiverInputDStream[Array[Byte]](_ssc) { override def getReceiver(): Receiver[Array[Byte]] = {
new OnsReceiver(cid,accessKey,secretKey,addr,topic,tag,func)
} }
util代码
import com.aliyun.openservices.ons.api.Message
import org.apache.spark.annotation.Experimental
import org.apache.spark.streaming.StreamingContext
import org.apache.spark.streaming.dstream.{DStream, ReceiverInputDStream} object OnsUtils {
@Experimental
def createStream(
ssc: StreamingContext,
cid: String,
topic: String,
tag: String,
accessKey: String,
secretKey: String,
addr: String,
func: Message => Array[Byte]): ReceiverInputDStream[Array[Byte]] = {
new OnsInputDStream(ssc, cid, topic, tag, accessKey, secretKey, addr, func)
} @Experimental
def createStreams(
ssc: StreamingContext,
consumerIdTopicTags: Array[(String, String, String)],
accessKey: String,
secretKey: String,
addr: String,
func: Message => Array[Byte]): DStream[Array[Byte]] = {
val invalidTuples1 = consumerIdTopicTags.groupBy(e => (e._1, e._2)).filter(e => e._2.length > 1)
val invalidTuples2 = consumerIdTopicTags.map(e => (e._1, e._2)).groupBy(e => e._1).filter(e => e._2.length > 1)
if (invalidTuples1.size > 1 || invalidTuples2.size > 1) {
throw new RuntimeException("Inconsistent consumer subscription.")
} else {
ssc.union(consumerIdTopicTags.map({
case (consumerId, topic, tags) =>
createStream(ssc, consumerId, topic, tags, accessKey, secretKey, addr, func)
}))
}
} }
三 调用
val stream = (0 until 3).map(i => {
OnsUtils.createStream(ssc,
"CID",
"BI_CALL",
"call_log_ons",
config.getString("ons.access_key"),
config.getString("ons.sercet_key"),
config.getString("ons.ons_addr"),
func)
})
val unionStream = ssc.union(stream).foreachRDD(...)
stream可以决定设置多少个receiver,这个数量必须小于等于spark on yarn的num-executors,内存默认占用executors的内存的一半。
Spark Streaming自定义Receiver的更多相关文章
- spark Streaming的Receiver和Direct的优化对比
Direct 1.简化并行读取:如果要读取多个partition,不需要创建多个输入DStream然后对它们进行union操作.Spark会创建跟Kafka partition一样多的RDD part ...
- spark streaming 3: Receiver 到 submitJobSet
对于spark streaming来说,receiver是数据的源头.spark streaming的框架上,将receiver替换spark-core的以磁盘为数据源的做法,但是数据源(如监听某个 ...
- Spark Streaming自定义Receivers
自定义一个Receiver class SocketTextStreamReceiver(host: String, port: Int( extends NetworkReceiver[String ...
- 9. Spark Streaming技术内幕 : Receiver在Driver的精妙实现全生命周期彻底研究和思考
原创文章,转载请注明:转载自 听风居士博客(http://www.cnblogs.com/zhouyf/) Spark streaming 程序需要不断接收新数据,然后进行业务逻辑 ...
- 4. Spark Streaming解析
4.1 初始化StreamingContext import org.apache.spark._ import org.apache.spark.streaming._ val conf = new ...
- Spark Streaming Backpressure分析
1.为什么引入Backpressure 默认情况下,Spark Streaming通过Receiver以生产者生产数据的速率接收数据,计算过程中会出现batch processing time > ...
- Spark Streaming性能优化: 如何在生产环境下应对流数据峰值巨变
1.为什么引入Backpressure 默认情况下,Spark Streaming通过Receiver以生产者生产数据的速率接收数据,计算过程中会出现batch processing time > ...
- 【Streaming】30分钟概览Spark Streaming 实时计算
本文主要介绍四个问题: 什么是Spark Streaming实时计算? Spark实时计算原理流程是什么? Spark 2.X下一代实时计算框架Structured Streaming Spark S ...
- 第12课:Spark Streaming源码解读之Executor容错安全性
一.Spark Streaming 数据安全性的考虑: Spark Streaming不断的接收数据,并且不断的产生Job,不断的提交Job给集群运行.所以这就涉及到一个非常重要的问题数据安全性. S ...
随机推荐
- vue项目实现表格导出excel表格
第一:安装依赖 npm install -S file-saver xlsx npm install -D script-loader 第二:在目录里新建excel文件夹 在excel文件夹里新建两个 ...
- spring 5.x 系列第8篇 —— 整合Redis客户端 Jedis和Redisson (代码配置方式)
文章目录 一.说明 1.1 Redis 客户端说明 1.2 Redis可视化软件 1.3 项目结构说明 1.3 依赖说明 二.spring 整合 jedis 2.1 新建基本配置文件和其映射类 2.2 ...
- IO侦探:多进程写ceph-fuse单文件性能瓶颈侦查
近期接到ceph用户报案,说是多进程direct写ceph-fuse的单个文件,性能很低,几乎与单进程direct写文件的性能一样.关乎民生,刻不容缓,笔者立即展开侦查工作~ 一.复现案情,寻踪追记 ...
- 并发编程-concurrent指南-阻塞队列-链表阻塞队列LinkedBlockingQueue
LinkedBlockingQueue是一个基于链表的阻塞队列. 由于LinkedBlockingQueue实现是线程安全的,实现了先进先出等特性,是作为生产者消费者的首选. LinkedBlocki ...
- scrapy实战2分布式爬取lagou招聘(加入了免费的User-Agent随机动态获取库 fake-useragent 使用方法查看:https://github.com/hellysmile/fake-useragent)
items.py # -*- coding: utf-8 -*- # Define here the models for your scraped items # # See documentati ...
- 图解AQS原理之ReentrantLock详解-非公平锁
概述 并发编程中,ReentrantLock的使用是比较多的,包括之前讲的LinkedBlockingQueue和ArrayBlockQueue的内部都是使用的ReentrantLock,谈到它又不能 ...
- ecshop面包屑修改
找到includes 找到lib_main.php 大约163样左右 /* 处理有分类的 */这段代码下面的一行修改成的对应的自己网站的分类,类似这样: 注释掉180行到194行左右,然后添加自己的分 ...
- webpack-dev-server 小记 原理介绍 概念解读
使用 DevServer 提供 HTTP 服务而不是使用本地文件预览 监听文件的变化并自动刷新网页,做到实时预览 支持 Source Map,以方便调试 对于这些,Webpack 都为我们考虑好了.W ...
- Unity《ATD》塔防RPG类3D游戏架构设计(二)
目录 <ATD> 游戏模型 <ATD> 游戏逻辑 <ATD> UI/HUD/特效/音乐 结语 前篇:Unity<ATD>塔防RPG类3D游戏架构设计(一 ...
- ~~番外:说说Python 面向对象编程~~
进击のpython Python 是支持面向对象的 很多情况下使用面向对象编程会使得代码更加容易扩展,并且可维护性更高 但是如果你写的多了或者某一对象非常复杂了,其中的一些写法会相当相当繁琐 而且我们 ...