Spark--06 SparkStreaming kafka消息堆积

本文探讨了在Kafka与Spark Streaming联合使用时,如何通过调整关键参数来优化性能,包括提升Job并发数、控制数据处理速率及重试策略,确保在消息积压或写入量激增情况下,系统仍能稳定运行。

问题:

当应用由于各种其它因素需要暂停消费时,下一次再次启动后就会有大量积压消息需要进行处理,此时为了保证应用能够正常处理积压数据,需要进行相关调优。

另外对于某个时刻,某个topic写入量突增时,会导致整个kafka集群进行topic分区的leader切换,而此时Streaming程序也会受到影响。

所以针对以上问题我们进行了如下调优:

  1. spark.streaming.concurrentJobs=10:提高Job并发数,读过源码的话会发现,这个参数其实是指定了一个线程池的核心线程数而已,没有指定时,默认为1。

  2. spark.streaming.kafka.maxRatePerPartition=2000:设置每秒每个分区最大获取日志数,控制处理数据量,保证数据均匀处理。(spark.streaming.kafka.maxRatePerPartition设定对目标topic每个partition每秒钟拉取的数据条数。假设此项设为1,批次间隔为10s,目标topic只有一个partition,则一次拉取的数据量为1*10*1=10。 计算Kafka吞吐量:

    spark.streaming.kafka.maxRatePerPartition这个参数是控制吞吐量的,一般和spark.streaming.backpressure.enabled=true一起使用。那么应该怎么算这个值呢。

    如例要10分钟的吞吐量控制在5000,0000,kafka分区是10个。

    spark.streaming.kafka.maxRatePerPartition=8400这个值是怎么算的呢。如下是公式

    spark.streaming.kafka.maxRatePerPartition的值 * kafka分区数 * (10 *60)(每秒时间) 

  3. spark.streaming.kafka.maxRetries=50:获取topic分区leaders及其最新offsets时,调大重试次数。

  4. 在应用级别配置重试
    spark.yarn.maxAppAttempts=5
    spark.yarn.am.attemptFailuresValidityInterval=1h

此处需要【注意】:
spark.yarn.maxAppAttempts值不能超过hadoop集群中yarn.resourcemanager.am.max-attempts的值,原因可参照下面的源码或者官网配置。

### 实时传输 Spark Streaming 处理结果到前端 将 Spark Streaming 处理的数据实时展示在前端,需要完成从数据处理、存储/传输到前端渲染的完整链路。以下是实现这一目标的关键步骤和技术方案: #### 1. 数据输出:Spark Streaming 输出处理结果 Spark Streaming 支持多种输出方式,可以将处理后的数据发送到数据库、消息队列或直接写入网络流。常用的输出操作包括: - **`foreachRDD`**:对每个批次的 RDD 执行自定义操作。 - **`print()`**:用于调试,将数据打印到控制台。 - **`saveAsTextFiles`**:将数据保存为文本文件。 ```python dstream.foreachRDD { rdd => rdd.foreachPartition { partition => // 连接数据库或发送消息到后端 partition.foreach { record => // 发送记录到后端服务 } } } ``` #### 2. 数据中间层:使用消息队列或数据库进行数据传递 为了保证高并发和解耦,建议使用以下中间层技术: - **Kafka**:适用于高吞吐量场景,Spark Streaming 可以直接发送数据到 Kafka,前端后端通过 Kafka 消费数据。 - **Redis**:适合缓存和低延迟读取,可作为临时存储,供后端 API 快速访问。 - **MySQL / PostgreSQL / MongoDB**:持久化存储处理结果,供前端查询展示。 #### 3. 后端接口:构建 RESTful API 或 WebSocket 接口 前端无法直接与 Spark Streaming 通信,因此需要一个后端服务来接收数据并提供接口: - **RESTful API**:前端通过定时轮询获取最新数据(适合较低频更新)。 - **WebSocket**:实现双向通信,适用于高频实时更新需求。 ```java // 示例:Java WebSocket 端点 @ServerEndpoint("/websocket") public class WebSocketEndpoint { @OnOpen public void onOpen(Session session) { // 存储 session 以便后续推送数据 } public static void sendDataToClient(String message) { // 推送数据到前端 } } ``` #### 4. 前端展示:使用前端框架进行实时可视化 前端可通过以下方式获取实时数据并展示: - **Axios + setInterval**:轮询后端接口获取最新数据。 - **Socket.IO / WebSocket**:建立长连接,接收实时推送。 - **ECharts / D3.js / Vue Chart**:用于数据可视化展示。 ```javascript const socket = new WebSocket("ws://yourserver/websocket"); socket.onmessage = function(event) { const data = JSON.parse(event.data); updateChart(data); // 更新图表 }; ``` #### 5. 性能优化与注意事项 - **批次间隔设置**:合理设置 Spark Streaming 的批次间隔(batch interval),避免数据堆积或延迟过高 [^4]。 - **反压机制(Backpressure)**:启用反压机制防止系统过载。 - **异步写入**:在 `foreachRDD` 中使用异步方式写入外部系统,提升性能。 - **前端性能监控**:限制数据更新频率,避免浏览器卡顿。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值