Flink项目总结问题

Flink 问题

https://gitee.com/felix_fxf/gmall2024-realtime.git

待解决问题

为什么要用HBase, 直接到Kafka不行?

关键词:

Flink 测出流 状态编程 日志分流 精准一次性 事务 隔离级别

Flink状态编程

ValueState 是基于键(key)的状态,Flink 会根据键将数据分发到不同的并行实例上,并且每个键的状态是唯一的。这意味着在不同的并行实例中,相同键的状态是共享的,并且可以被正确地更新和访问。例如,对于不同用户的最后访问日期,Flink 会根据用户 ID 这个键来管理每个用户的状态,确保每个用户的状态是一致的。

source端:起码提供可重置偏移量(数据可重放的能力),

tranform:检查点机制

sink端:幂等,事务

API级别

  • SQL
  • DataSet
  • DataStream
  • process

侧出流

1
2
// 定义侧出流标签
OutputTag<String> dirtyTag = new OutputTag<String>("dirtyTag"){};

容错

Kafka生产和消费保证数据的精准一次性

Kafka消费者的
精准一次性:手动维护偏移量
至少一次
消费的精准一次性:开启事务
写入kafka 精准一次性
幂等
事务
预提交
两阶段提交

  • KafkaSource: 从Kafka主题中读取数据

    • 通过手动维护偏移量,保证消费的精准一次性
  • KafkaSink: 向Kafka主题中写入数据,也可以保证写入的精准一次性,需要做如下操作

    Flink-1.17官方说明:Kafka | Apache Flink

    DeliveryGuarantee.EXACTLY_ONCE: 该模式下,Kafka sink 会将所有数据通过在 checkpoint 时提交的事务写入。
    因此,如果 consumer 只读取已提交的数据(参见 Kafka consumer 配置 isolation.level),在 Flink 发生重启时不会发生数据重复。
    然而这会使数据在 checkpoint 完成时才会可见,因此请按需调整 checkpoint 的间隔。
    请确认事务 ID 的前缀(transactionIdPrefix)对不同的应用是唯一的,以保证不同作业的事务 不会互相影响!
    此外,强烈建议将 Kafka 的事务超时时间调整至远大于 checkpoint 最大间隔 + 最大重启时间,否则 Kafka 对未提交事务的过期处理会导致数据丢失。

    • 开启检查点

    • 配置生产者消费一次性

      1
      .setDeliveryGuarantee(DeliveryGuarantee.EXACTLY_ONCE)
    • 设置事务ID前缀保证对不同的应用是唯一的

      1
      .setTransactionalIdPrefix("dwd_base_log_")
    • 设置事务超时时间 (检查点超时时间 < 事务的超时时间 <= 事务的最大超时时间)

      1
      .setProperty(ProducerConfig.TRANSACTION_TIMEOUT_CONFIG, 15*60*1000 + "")
    • 在消费端,需要设置消费的隔离级别为读已提交(默认为读为提交:预提交的数据也能读到)

      1
      .setProperty(ConsumerConfig.ISOLATION_LEVEL_CONFIG, "read_committed")

数据埋点产生的数据问题

  • 判断新老顾客,通过缓存

    Web 端:用户第一次访问埋入神策 SDK 页面的当天(即第一天),JS SDK 会在网页的 cookie 中设置一个首日访问的标记,并设置第一天 24 点之前,该标记为 true,即第一天触发的网页端所有事件中,is_new = 1。第一天之后,该标记则为 false,即第一天之后触发的网页端所有事件中,is_new = 0;

    本项目模拟生成的是 APP 端日志数据。对于此类日志,如果首日之后用户清除了手机本地缓存中的标记,再次启动 APP 会重新设置一个首日为 true 的标记,导致本应为 0 的 is_new 字段被置为 1,可能会给相关指标带来误差。因此,有必要对新老访客状态标记进行修复。

双流Join

Join | Apache Flink

Flink SQL支持对动态表进行复杂而灵活的连接操作。 为了处理不同的场景,需要多种查询语义,因此有几种不同类型的 Join。

默认情况下,joins 的顺序是没有优化的。表的 join 顺序是在 FROM 从句指定的。可以通过把更新频率最低的表放在第一个、频率最高的放在最后这种方式来微调 join 查询的性能。需要确保表的顺序不会产生笛卡尔积,因为不支持这样的操作并且会导致查询失败。

Regular Joins #

Regular join 是最通用的 join 类型。在这种 join 下,join 两侧表的任何新记录或变更都是可见的,并会影响整个 join 的结果。 例如:如果左边有一条新纪录,在 Product.id 相等的情况下,它将和右边表的之前和之后的所有记录进行 join。

Interval Joins #

返回一个符合 join 条件和时间限制的简单笛卡尔积。Interval join 需要至少一个 equi-join 条件和一个 join 两边都包含的时间限定 join 条件。范围判断可以定义成就像一个条件(<, <=, >=, >),也可以是一个 BETWEEN 条件,或者两边表的一个相同类型(即:处理时间 或 事件时间)的时间属性 的等式判断。

Temporal Joins #

时态表(Temporal table)是一个随时间变化的表:在 Flink 中被称为动态表。时态表中的行与一个或多个时间段相关联,所有 Flink 中的表都是时态的(Temporal)。 时态表包含一个或多个版本的表快照,它可以是一个变化的历史表,跟踪变化(例如,数据库变化日志,包含所有快照)或一个变化的维度表,也可以是一个将变更物化的维表(例如,存放最终快照的数据表)。

Lookup Join #

水位线

1
getUpsertKafkaDDL

旁路缓存

异步IO

维度层和数据明细层

Doris

报表分析

即席查询

统一数仓构建

搜索关键词聚合统计

Flink 有 spark stream没有:事件时间语义

wartermark 水位线 事件时间衡量,逻辑时钟

默认指定wartermark两种方式

  • 单调递增:有界乱序的一种特殊情况(乱序程度0)
  • 有界乱序

旁路缓存

异步IO

异步 I/O | Apache Flink

Flink 的异步 I/O API 允许用户在流处理中使用异步请求客户端。API 处理与数据流的集成,同时还能处理好顺序、事件时间和容错等。

在具备异步数据库客户端的基础上

ODS数据采集

日志数据采集

flume组件:source sink cancel

2024-10-10日停止维护

业务数据采集

maxwell: binlog拿取数据

不具备将json格式封装为字符串

DIM维度层处理

业务数据库维度表变化实时同步到数仓

配置表中配置信息判断是不是维度,flinkCDC

广播流

主流数据处理:根据表名到

DWD事实表准备

流量域

日志分流

交易域

FlinkSQL实现:普通内外连接为参与连接的表默认维护一个状态,默认情况下这个状态永远不会失效

状态保留时间:传输延迟,业务滞后关系

左外连接,如果左表数据先到,右表数据后到,会产生3条数据(回撤流)

发送到kafka主题会记录三条数据:需要空数据处理,去重

普通内外连接关联维度,时间无法控制,Lookup Join左表驱动

工具域

互动域

用户域

实现:DataStreamAPI,SQL

DWS汇总表的抽取以及轻度聚合

给ADS提供服务

列出指标,

统计周期、粒度、业务过程相同,这样的指标放在一张汇总表进行处理(汇总表的抽取)

写数据,轻度聚合,FlinkSQL FlinkAPI 读取数据创建动态表、指定waterMark、提取事件事件字段

处理、分组、开窗、聚合计算、写到Doris

往数据库写保证数据一致性

hbase 幂等

kafka 事务

doris union表可以幂等

去重

  • 状态+定时器:失效性差,不会出现数据膨胀
  • 状态+抵消

维度关联:基本维度关联:旁路缓存Redis,异步IO 支持异步操作数据库

异步编排对象

ADS分析和可视化操作

sugar


Flink项目总结问题
https://leaf-domain.gitee.io/2024/10/05/bigdata/flink/Flink 问题/
作者
叶域
发布于
2024年10月5日
许可协议