使用spark DStream的foreachRDD时要注意哪些坑?
答案: 两个坑, 性能坑和线程坑
DStream是抽象类,它把连续的数据流拆成很多的小RDD数据块, 这叫做“微批次”, spark的流式处理, 都是“微批次处理”。 DStream内部实现上有批次处理时间间隔,滑动窗口等机制来保证每个微批次的时间间隔里, 数据流以RDD的形式发送给spark做进一步处理。因此, 在一个为批次的处理时间间隔里, DStream只产生一个RDD。
可以利用dstream.foreachRDD把数据发送给外部系统。 但是想要正确地, 有效率的使用它, 必须理解一下背后的机制。通常向外部系统写数据需要一个Connection对象(通过它与外部服务器交互)。程序员可能会想当然地在spark上创建一个connection对象, 然后在spark线程里用这个对象来存RDD。比如下面的程序:
dstream.foreachRDD { rdd =>
val connection = createNewConnection() // executed at the driver
rdd.foreach { record =>
connection.send(record) // executed at the worker
}
}
这个代码会产生执行错误, 因为rdd是分布式存储的,它是一个数据结构,它是一组指向集群数据的指针, rdd.foreach会在集群里的不同机器上创建spark工作线程, 而connection对象则不会在集群里的各个机器之间传递, 所以有些spark工作线程就会产生connection对象没有被初始化的执行错误。 解决的办法可以是在spark worker里为每一个worker创建一个connection对象, 但是如果你这么做, 程序要为每一条record创建一次connection,显然效率和性能都非常差。
另一种改进方法是为每个spark分区创建一个connection对象,同时维护一个全局的静态的连接迟对象, 这样就可以最好的复用connection。 另外需要注意: 虽然有多个connection对象, 但在同一时间只有一个connection.send(record)执行, 因为在同一个时间里, 只有 一个微批次的RDD产生出来。
dstream.foreachRDD { rdd =>
rdd.foreachPartition { partitionOfRecords =>
// ConnectionPool is a static, lazily initialized pool of connections
val connection = ConnectionPool.getConnection()
partitionOfRecords.foreach(record => connection.send(record))
ConnectionPool.returnConnection(connection) // return to the pool for future reuse
}
}
有人问了个问题,为什么foreachRDD里有两层嵌套的foreach? 为什么dstream.foreachRDD里还要再套一层rdd.foreach
可以这么理解, DStream.foreachRDD 是一个输出操作符,它返回的不是RDD里的一行数据, 而是输出DStream后面的RDD,在一个时间间隔里, 只返回一个RDD的“微批次”, 为了访问这个“微批次”RDD里的数据, 我们还需要在RDD数据对象上做进一步操作.。 参考下面的代码实例, 更容易理解。
给顶一个 RDD [Security, Prices]数据结构
dstream.foreachRDD { pricesRDD => // Loop over RDD
val x= pricesRDD.count
if (x > 0) // RDD has data
{
for(line <- pricesRDD.collect.toArray) // Look for each record in the RDD
{
var index = line._2.split(',').view(0).toInt // That is the index
var timestamp = line._2.split(',').view(1).toString // This is the timestamp from source
var security = line._2.split(',').view(12.toString // This is the name of the security
var price = line._2.split(',').view(3).toFloat // This is the price of the security
if (price.toFloat > 90.0)
{
// Do something here
// Sent notification, write to HDFS etc
}
}
}
}
使用spark DStream的foreachRDD时要注意哪些坑?的更多相关文章
- 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(五)——实现注册功能
使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(一)——创建应用 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(二)——使用蓝图功能进行模块化 使用 Flask 框架写用 ...
- 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(四)——对 run.py 的调整
使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(一)——创建应用 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(二)——使用蓝图功能进行模块化 使用 Flask 框架写用 ...
- 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(一)——创建应用
使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(一)——创建应用 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(二)——使用蓝图功能进行模块化 使用 Flask 框架写用 ...
- 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(二)——使用蓝图功能进行模块化
使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(一)——创建应用 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(二)——使用蓝图功能进行模块化 使用 Flask 框架写用 ...
- 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(三)——使用Flask-Login库实现登录功能
使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(一)——创建应用 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(二)——使用蓝图功能进行模块化 使用 Flask 框架写用 ...
- 记一次在node.js中使用crypto的createCipheriv方法进行加密时所遇到的坑
Node.js的crypto模块提供了一组包括对OpenSSL的哈希.HMAC.加密.解密.签名,以及验证等一整套功能的封装.具体的使用方法可以参考这篇文章中的描述:node.js_crypto模块. ...
- 学习Spring5源码时所遇到的坑
学习Spring5源码时所遇到的坑 0)本人下载的源码版本是 spring-framework-5.0.2.RELEASE 配置好gradle环境变量之后,cmd进入到spring项目,执行gradl ...
- 在PyQt5中使用Pandas时的几个坑
最近在看Python GUI编程,在用到PyQt5+Pandas时遇到一些问题.这里把问题和解决方法整理一下.备查. (好像不能上传附件,内容只好写在下面了.) 在PyQt5中使用Pandas时的几个 ...
- 通过Spark Streaming的foreachRDD把处理后的数据写入外部存储系统中
转载自:http://blog.csdn.net/erfucun/article/details/52312682 本博文主要内容包括: 技术实现foreachRDD与foreachPartition ...
随机推荐
- 机器学习技法笔记:01 Linear Support Vector Machine
Roadmap Course Introduction Large-Margin Separating Hyperplane Standard Large-Margin Problem Support ...
- LeetCode--No.015 3Sum
15. 3Sum Total Accepted: 131800 Total Submissions: 675028 Difficulty: Medium Given an array S of n i ...
- Python模块练习题
练习题: 1.logging模块有几个日志级别? #INFO,WARNING,DEBUG,CRITICAL,ERROR 2.请配置logging模块,使其在屏幕和文件里同时打印以下格式的日志 2017 ...
- SQL分别求行、列的平均值
日常工作中,会需要用SQL求平均值,分别是求某一项的平均值或求某一个对象的平均值,放到表格就是求一行中的几个字段的平均值和求一列的平均值. 第一种:[列的平均值]AVG:这个函数相信大家都不陌生的,求 ...
- 1-VScode格式化ESlint-方法(最全最好用方法!)
1-VScode格式化ESlint-方法(最全最好用方法!) ESlint:是用来统一JavaScript代码风格的工具,不包含css.html等. 背景: 近来研究前端,然后一直在百度上找VSc ...
- Docker构建Java web应用服务
1.构建一个Java应用服务,包含两个步骤:a.一个镜像从URL拉取指定的WAR文件并保存到卷里b.一个含有Tomcat服务器的镜像运行这些下载的WAR文件 2.构建下载WAR的镜像 FROM cen ...
- Java 面试基础总结(一)
1.九种基本数据类型的大小以及它们的封装类 java提供的九种基本数据类型:boolean.byte(1).char(2).short(2).int(4).long(8).float(4).doubl ...
- js a标签 + ajax 多参数穿参
<span onclick="return haoping('{$row['jv_id']}','1')"> function haoping(id,type){ $. ...
- Extjs4.2 rest 与webapi数据交互----顺便请教了程序员的路该怎么走
这一章接着上一篇 对于Ext.data.Store 介紹 与总结,以及对以前代码的重构与优化 1.对于更新OnUpdate()函数的修改:先上代码: function OnUpdate(record) ...
- 【Java并发编程】15、ReentrantLock实现原理深入探究
原文已经写得非常详细了,直接把大神的文章转发过来了 https://www.cnblogs.com/xrq730/p/4979021.html 前言 这篇文章被归到Java基础分类中,其实真的一点都 ...