通过Spark Streaming处理交易数据

Apache Spark 是加州大学伯克利分校的 AMPLabs 开发的开源分布式轻量级通用计算框架。

由于 Spark 基于内存设计,使得它拥有比 Hadoop 更高的性能(极端情况下可以达到 100x),并且对多语言(Scala、Java、Python)提供支持。

其一栈式设计特点使得我们的学习和维护成本大大地减少,而且其提供了很好的容错解决方案

业务场景

我们每天都有来自全国各地的天然气购气数据,并根据用户的充气,退气,核销等实时计算分析的是用户订单数数据,由于数据量比较大,单台机器处理已经达到了瓶颈;综合业务场景分析,我们选用 Spark Streaming + Kafka+Flume+Hbase+kudu 来处理这些日志;又因为业务系统不统一,先通过Spark Streaming对数据进行清洗后再回写kafka集群,因为会有其他业务也需要kafka的数据;通过通过不同的程序对kafka数据进行消费,用户记录以多版本方式记录到hbase;需要经常统计的指标业务数据写入kudu

业务代码:

  创建DStream

val sparkConf = new SparkConf().setAppName("OrderSpark")

val sc = new SparkContext(sparkConf)

val ssc = new StreamingContext(sc, Seconds(10))

val kafkaParams = Map[String, String]("metadata.broker.list" -> brokerAddress,"group.id" -> groupId)

val messages = KafkaUtils.createDirectStream[String, String, StringDecoder,StringDecoder](ssc, kafkaParams, Set(topic))

返回的messages 是一个 DStream,它是对 RDD 的封装,其上的很多操作都类似于 RDD;

createDirectStream 函数是 Spark 1.3.0 开始引入的,其内部实现是调用 Kafka 的低层次 API,Spark 本身维护 Kafka 偏移量等信息,所以可以保证数据零丢失

但是机器一旦宕机或者重启时,可能会存在重复消费;因此我们可以通过自己对offset进行checkpoint

  获取kafkaoffset

   val kafkaStream = KafkaUtils.createDirectStream[String, String, StringDecoder, StringDecoder](ssc, kafkaParams, topics)
    var offsetRanges = Array[OffsetRange]()
    kafkaStream.transform{ rdd =>
      offsetRanges = rdd.asInstanceOf[HasOffsetRanges].offsetRanges
      rdd
    }.foreachRDD(rdd=>{
      for(o <- offsetRanges) {
        println(s"@@@@@@ topic  ${o.topic}  partition ${o.partition}  fromoffset ${o.fromOffset}  untiloffset ${o.untilOffset} #######")
      }    }

为了能够在 Spark Streaming 程序挂掉后又能从断点处恢复,我们每个批次进行向zookeeper进行 Checkpoint;

这里我们没有采用spark自带的checkpoint,是因为一旦程序修改,之前序列化的checkpoint数据会冲突报错,

当然checkpoint到文件也会随之越大。(读者可以自己搜索spark 文件checkpoint的弊端)

  启动实时程序

    ssc.start()
    ssc.awaitTermination()

  因业务所需需要向kafka回写数据

  

rdd.foreachPartition(partition=>{
        val props = new Properties()
        props.put("bootstrap.servers",Constans.brokers)
        props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer")
        props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer")
        val producer = new KafkaProducer[String,String](props)
        partition.foreach(r=>{
          val record = new ProducerRecord[String, String](Constans.topic_kc, new Random().nextInt(3), "", msg)
      producer.send(record,new Callback() {        override def onCompletion(recordMetadata: RecordMetadata, e: Exception): Unit = {          if (null != e) {            println("发送消息失败=>"+msg)          }        }      })
  }) producer.close() })

监控

系统部署上线之后,我们无法保证系统 7x24 小时都正常运行,即使是在运行着,我们也无法保证 Job 不堆积、是否及时处理 Kafka 中的数据;而且 Spark Streaming 系统本身就不很稳定。所以我们需要实时地监控系统,包括监控Kafka 集群、Spark Streaming 程序。我们所有的监控都是CDH自带监控管理和Ganglia以及nagios,一旦检测到异常,系统会自己先重试是否可以自己恢复,如果不行,就会给我们发送报警邮件和打电话。

 

原文地址:https://www.cnblogs.com/weishao-lsv/p/8159496.html

时间: 2024-10-13 01:16:10

通过Spark Streaming处理交易数据的相关文章

160728、Spark Streaming kafka 实现数据零丢失的几种方式

定义 问题开始之前先解释下流处理中的一些概念: At most once - 每条数据最多被处理一次(0次或1次) At least once - 每条数据最少被处理一次 (1次或更多) Exactly once - 每条数据只会被处理一次(没有数据会丢失,并且没有数据会被多次处理) High Level API   如果不做容错,将会带来数据丢失因为receiver一直在接收数据,在其没有处理的时候(已通知zk数据接收到),executor突然挂掉(或是driver挂掉通知executor关闭

spark streaming 接收 kafka 数据java代码WordCount示例

1. 首先启动zookeeper 2. 启动kafka 3. 核心代码 生产者生产消息的java代码,生成要统计的单词 package streaming; import java.util.Properties; import kafka.javaapi.producer.Producer; import kafka.producer.KeyedMessage; import kafka.producer.ProducerConfig; public class MyProducer { pu

Kafka:ZK+Kafka+Spark Streaming集群环境搭建(二十二)Spark Streaming接收流数据及使用窗口函数

官网文档:<http://spark.apache.org/docs/latest/streaming-programming-guide.html#a-quick-example> Spark Streaming官网的例子reduceByKeyAndWindow 简单的介绍了spark streaming接收socket流的数据,并把接收到的数据进行windows窗口函数对数据进行批量处理. import java.util.Arrays; import org.apache.spark.S

spark streaming读取kakfka数据手动维护offset

在spark streaming读取kafka的数据中,spark streaming提供了两个接口读取kafka中的数据,分别是KafkaUtils.createDstream,KafkaUtils.createDirectStream,前者会自动把offset更新到zk中,默认会丢数据,效率低,后者不会经过zk,效率更高,需要自己手动维护offse,通过维护护offset写到zk中,保障数据零丢失,只处理一次,下面来看看KafkaUtils.createDirectStream的使用,我把z

Spark Streaming 读取 Kafka 数据的两种方式

在Spark1.3之前,默认的Spark接收Kafka数据的方式是基于Receiver的,在这之后的版本里,推出了Direct Approach,现在整理一下两种方式的异同. 1. Receiver-based Approach val kafkaStream = KafkaUtils.createDstream(ssc, [zk], [consumer group id], [per-topic,partitions] ) 2. Direct Approach (No Receivers) v

Spark Streaming编程指南

本文基于Spark Streaming Programming Guide原文翻译, 加上一些自己的理解和小实验的结果. 一.概述 Spark Streaming是基于Core Spark API的可扩展,高吞吐量,并具有容错能力的用于处理实时数据流的一个组件.Spark Streaming可以接收各种数据源传递来的数据,比如Kafka, Flume, Kinesis或者TCP等,对接收到的数据还可以使用一些用高阶函数(比如map, reduce, join及window)进行封装的复杂算法做进

使用Spark Streaming + Kudu + Impala构建一个预测引擎

随着用户使用天数的增加,不管你的业务是扩大还是缩减了,为什么你的大数据中心架构保持线性增长的趋势?很明显需要一个稳定的基本架构来保障你的业务线.当你的客户处在休眠期,或者你的业务处在淡季,你增加的计算资源就处在浪费阶段:相对应地,当你的业务在旺季期,或者每周一每个人对上周的数据进行查询分析,有多少次你忒想拥有额外的计算资源. 根据需求水平动态分配资源 VS 固定的资源分配方式,似乎不太好实现.幸运的是,借助于现今强大的开源技术,可以很轻松的实现你所愿.在这篇文章中,我将给出一个解决例子,基于流式

3.spark streaming Job 架构和容错解析

一.Spark streaming Job 架构 SparkStreaming框架会自动启动Job并每隔BatchDuration时间会自动触发Job的调用. Spark Streaming的Job 分为两大类: 每隔BatchInterval时间片就会产生的一个个Job,这里的Job并不是Spark Core中的Job,它只是基于DStreamGraph而生成的RDD的DAG而已:从Java角度讲相当于Runnable接口的实现类,要想运行Job需要将Job提交给JobScheduler,在J

Spark Streaming和Flume集成指南V1.4.1

Apache Flume是一个用来有效地收集,聚集和移动大量日志数据的分布式的,有效的服务.这里我们解释一下怎样配置Flume和Spark Streaming来从Flume获取数据.这里有两个方法. Python API:Flume现在还不支持PythonAPI 方法1:Flume风格的推方法 Flume被设计用来在Flume代理之间推送数据.在这种方法中,Spark Streaming本质上设置了一个接收器作为Flume的一个Avro代理,Flume把数据推送到接收器上.下面是配置的步骤. 一