flink的那些事

flink开发流程
一 自定义source
1 定义实体bean
2 获取kafka里的数据
3 生成流,并对gson转换
问题:对类的定义 以及类转换
获取kafka的步骤,在测试阶段如何去自定义消费断点时间
代码:
//1.1

case class SpeedBean(rts: Long, parserData: Long, carModelId: String, receiveDate: Long, tripId: String, sn: String, sp: Int, ts: Long,
                       et: Int, beanType1: Int = 1) extends OutingTripStatusInfo(sn, beanType1, rts)

//1.2 获取kafka

  val zkCluster = "bigdata06:2181,bigdata09:2181,bigdata10:2181"
    val kafkaCluster = "bigdata07:9092,bigdata08:9092,bigdata09:9092"
    val topic = "vin_selfdrivingtravel_status"
    val timestamp = 1519804800000L

    val env = StreamExecutionEnvironment.getExecutionEnvironment
    val props = new Properties()
    props.setProperty("bootstrap.servers",kafkaCluster)
    props.setProperty("zookeeper.connect",zkCluster)
props.put("key.deserializer","org.apache.kakfa.common.serialization.StringDeserializer")
props.put("value.deserializer","org.apache.kafka.common.serialization.StringDeserializer")
    props.setProperty("group.id","selfDrivingTest")

//1.3解析kafka 里的 内容

  val speedStreamBean = speadStreaming.map(new MapFunction[String, SpeedBean] {
      override def map(t: String): SpeedBean = {
        gson.fromJson(t, classOf[SpeedBean]).copy(beanType1 = 1)
      }
    })

二 source 的流建立连接
1 source 是否需要转化广播流
2 对连接流进行 connection

2.2 
streamOutingTripBean.connect(speedStreamBean).map(new CoMapFunction[OutingTripBean, SpeedBean, OutingTripStatusInfo]() {
  override def map1(in1: OutingTripBean): OutingTripStatusInfo = in1

  override def map2(in2: SpeedBean): OutingTripStatusInfo = in2
}).connect(gpsBeanStreamBean).map(new CoMapFunction[OutingTripStatusInfo, GpsBean, OutingTripStatusInfo]() {
  override def map1(in1: OutingTripStatusInfo): OutingTripStatusInfo = in1

  override def map2(in2: GpsBean): OutingTripStatusInfo = in2
})

问题: 1 keyby如何去选择字段去分组
2 多流connection 如何去做,用什么函数,是否可以做flink sql

三 开始计算 process
1 对keyby连接流里的字段
2 对keyby后的数据,进行process数据处理
3 对状态的选取和维护
3.1 声明状态类
3.2 选取合适的状态
3.3 获取父类状态数据
3.4 对空状态的里的数据进行特殊处理
4 计算数据逻辑
1 初始化processElement
2 不同的状态去process
3 更新状态
4 从状态里获取汇总数据
5 返回数据collection

1  .keyBy(_._vin1).process(keyedProcessFunction = new KeyedProcessFunction[String, OutingTripStatusInfo, outResult]() {

3.1 声明状态类

case class BaseStateInfo(vin: String, SDTTripId: Long, state: Int, StartTime: Long, EndTime: Long)
case class GpsStateInfo(totalDistinceGps: Double, lo: Double, ld: Double, rts: Long, distanceCurrenceDay: Double, maxDistanceDay: Long, maxDistince: Double)
case class DrivingTimeInfo(totalDrivingTime: Long, maxDrivingTime: Long, maxDrivingTimeStart: Long, maxDrivingTimeEnd: Long,
                                 maxDrivingTimeOnce: Long, maxDrivingTimeOneDay: Long, trip_id: String, currencyDrivingTime: Long)
case class SpeedStateInfo(maxSpeed: Long, maxSpeedTime: Long, sumSpeed: Long, speedCount: Long)

3.2 选取合适的状态

var vin_state: ValueState[BaseStateInfo] = _
      var speed_state: ValueState[SpeedStateInfo] = _
      var gps_state: ValueState[GpsStateInfo] = _
      var drivingTime_state: ValueState[DrivingTimeInfo] = _

3.3 获取父类状态数据

 override def open(parameters: Configuration): Unit = {
    vin_state = getRuntimeContext.getState(new ValueStateDescriptor[BaseStateInfo]("0", TypeInformation.of(new TypeHint[BaseStateInfo]() {})))
    speed_state = getRuntimeContext.getState(new ValueStateDescriptor("4", TypeInformation.of(new TypeHint[SpeedStateInfo]() {})))
    gps_state = getRuntimeContext.getState(new ValueStateDescriptor[GpsStateInfo]("2", TypeInformation.of(new TypeHint[GpsStateInfo]() {})))
    drivingTime_state = getRuntimeContext.getState(new ValueStateDescriptor[DrivingTimeInfo]("3", TypeInformation.of(new TypeHint[DrivingTimeInfo]() {})))
  }

3.4 状态数据初始化

private def initStatus(statusInfo: OutingTripStatusInfo): Unit = {
        if (vin_state.value() == null) vin_state.update(BaseStateInfo(statusInfo._vin1, 0, 0, 0, 0))
        if (speed_state.value() == null) speed_state.update(SpeedStateInfo(0, 0, 0, 0))
        if (gps_state.value() == null) gps_state.update(GpsStateInfo(0d, 0d, 0d, 0, 0d, 0, 0d))
        if (drivingTime_state.value() == null) drivingTime_state.update(DrivingTimeInfo(0, 0, 0, 0, 0, 0, "", 0))
      }
4 计算数据逻辑
	1 初始化processElement
	2 不同的状态去process
	3  更新状态
	4 从状态里获取汇总数据
	5 返回数据collection

4.1 初始化 processElement
4.2 不同的状态去process

  override def processElement(statusInfo: OutingTripStatusInfo, context: KeyedProcessFunction[String, OutingTripStatusInfo, outResult]#Context, collector: Collector[outResult]): Unit = {
    initStatus(statusInfo)
    statusInfo._beanType match {
      case 0 => processOutingTripBean(statusInfo.asInstanceOf[OutingTripBean])
      case 1 => processSpeedBean(statusInfo.asInstanceOf[SpeedBean])
      case 2 => processGpsBean(statusInfo.asInstanceOf[GpsBean])
    }

4.3更新状态

  gps_state.update(GpsStateInfo(tmpDistince, bean.lo, bean.ld, bean.rts, tmpDistince, tempMaxTime, tempMaxDistance))

4.4从状态里获取汇总数据

// 总驾驶时长
        val totalDrivingTime = drivingTime_state.value().totalDrivingTime

4.5 返回数据collection

 if (trip_id > 0 && vin != null && !"".equals(vin)) {
          collector.collect(outResult(trip_id, vin, state, totalDrivingTime, maxDrivingTime,
            maxDrivingTimeStart, maxDrivingTimeEnd, maxDrivingTimeOnce, maxDrivingTimeOneDay, avgSpead, maxSpeed,
            maxSpeedRts, totalDistance, maxDistance, maxDistanceTime, ct))
        }
      }

四 水印
1 30秒snapshot

window(TumblingEventTimeWindows.of(Time.seconds(30)))

五 sink数据

### Apache Flink 使用指南及官方文档资源 Apache Flink 是一个分布式流处理框架,支持高吞吐、低延迟的实时数据处理。以下是关于 Flink使用指南和官方文档资源的详细介绍: #### 1. 官方文档 Flink 官方文档是学习和使用 Flink 的最佳起点,涵盖了从入门到高级的所有主题。文档地址为 [https://nightlies.apache.org/flink/flink-docs-release-1.17/](https://nightlies.apache.org/flink/flink-docs-release-1.17/)。以下是文档的主要内容分类: - **快速开始**:提供了安装和运行 Flink 的基本步骤,包括本地环境配置和简单示例代码[^3]。 - **核心概念**:详细介绍了 Flink 的核心组件,如 DataStream API、Table API、SQL 等[^3]。 - **部署与运维**:涵盖了如何在不同环境中部署 Flink 集群,例如 Kubernetes、YARN 和独立集群模式[^3]。 - **性能调优**:提供了优化 Flink 应用程序性能的最佳实践,包括并行度设置、内存管理等[^3]。 #### 2. 社区支持与学习资源 除了官方文档,Flink 社区也提供了丰富的学习资源和支持渠道: - **邮件列表**:通过加入用户邮件列表或开发者邮件列表,可以获取来自社区的帮助和建议[^3]。 - **Stack Overflow**:许多常见问题已经在 Stack Overflow 上得到了解答,搜索标签 `apache-flink` 可以找到相关讨论。 - **Flink Meetup 和 Conference**:定期举办的线上或线下活动,分享最新的技术进展和最佳实践。 #### 3. 示例代码与项目参考 为了更好地理解 Flink 的实际应用,可以通过以下项目进行学习: - **Flink Shaded Artifacts**:该项目提供了一些用于隔离依赖的工具库,帮助开发者避免版本冲突问题[^1]。 - **Flink Benchmarks**:包含了一系列基准测试程序,展示了如何评估 Flink 的性能表现[^2]。 #### 4. 示例代码 以下是一个简单的 Flink 流处理程序示例,演示了如何读取 Kafka 数据源并进行基本转换操作: ```java import org.apache.flink.api.common.eventtime.WatermarkStrategy; import org.apache.flink.api.common.serialization.SimpleStringSchema; import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment; import org.apache.flink.connector.kafka.source.KafkaSource; public class SimpleFlinkKafkaExample { public static void main(String[] args) throws Exception { // 创建执行环境 StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); // 配置 Kafka 数据源 KafkaSource<String> kafkaSource = KafkaSource.<String>builder() .setBootstrapServers("localhost:9092") .setTopics("input-topic") .setStartingOffsets(OffsetsInitializer.earliest()) .setValueOnlyDeserializer(new SimpleStringSchema()) .build(); // 从 Kafka 中读取数据并打印 env.fromSource(kafkaSource, WatermarkStrategy.noWatermarks(), "Kafka Source") .map(value -> value.toUpperCase()) // 转换为大写 .print(); // 启动任务 env.execute("Simple Flink Kafka Example"); } } ``` 此代码片段展示了如何连接到 Kafka 数据源,并对消息进行简单转换后输出。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值