4、因子计算数据模型设计

实时因子计算服务的核心在于将业务逻辑抽象为可配置、可复用的计算单元。本章围绕因子定义、元数据管理、数据源抽象三大模块,构建一套完整的数据模型体系,确保因子计算在 Flink 作业中能够高效、一致地执行。

4.1 因子定义模型

因子定义是计算逻辑的元数据载体,包含因子标识、计算逻辑、时间窗口等核心属性。每个因子在系统中拥有全局唯一的 ID,并通过 JSON 格式描述其计算规则。

字段 类型 说明 示例
factor_id String 全局唯一因子标识 FACTOR_001
factor_name String 因子中文名称 近5分钟平均响应时间
compute_logic JSON 计算逻辑定义(算子链 + 参数) {"operator":"AVG","field":"response_time","filter":"status=200"}
window_config JSON 时间窗口配置(类型、大小、滑动步长) {"type":"SLIDING","size":300,"slide":60}
data_source_id String 关联的数据源标识 DS_KAFKA_001
output_topic String 计算结果输出目标 factor_result
status Integer 启用状态(0-禁用,1-启用) 1
设计要点:compute_logic 字段采用嵌套 JSON 结构,支持 AND/OR 条件组合、多字段聚合、自定义 UDF 引用。window_config 中的 type 支持 TUMBLE(滚动窗口)、SLIDING(滑动窗口)、SESSION(会话窗口)三种模式。

4.2 因子元数据管理

元数据管理负责因子定义的存储、版本控制、缓存与动态更新。系统采用 MySQL 作为持久化存储,Redis 作为运行时缓存,Flink 通过广播状态(Broadcast State)实现因子配置的热加载。

4.2.1 元数据存储结构

存储层 用途 数据结构 更新频率
MySQL 因子定义持久化、历史版本追溯 factor_def 表(含 version 字段) 低频(人工配置变更)
Redis 因子配置缓存、实时查询加速 Hash(key=factor:config, field=factor_id) 中频(配置变更后刷新)
Flink Broadcast State 作业运行时因子配置热更新 MapStateDescriptor<String, FactorConfig> 高频(Kafka 配置变更流驱动)

4.2.2 配置变更流程

  1. 运维人员通过管理平台修改因子定义,写入 MySQL 并记录版本号。
  2. 变更事件发送至 Kafka 配置变更主题(config_change_topic)。
  3. Flink 作业通过 BroadcastProcessFunction 接收变更流,更新 Broadcast State。
  4. 作业根据新配置重新构建计算逻辑,无需重启作业。
最佳实践:Redis 缓存设置 TTL(建议 300 秒),避免因配置变更未及时刷新导致数据不一致。Flink 广播状态建议使用 RocksDB 状态后端,防止大配置集撑爆堆内存。

4.3 数据源抽象

实时因子计算需要对接多种数据源:Kafka 提供高吞吐事件流,MySQL 存储维度数据,Redis 提供低延迟键值查询。数据源抽象层统一管理连接信息、序列化方式与访问策略。

4.3.1 数据源定义模型

字段 类型 说明 示例
ds_id String 数据源唯一标识 DS_KAFKA_001
ds_type String 数据源类型(KAFKA / MYSQL / REDIS) KAFKA
connection_config JSON 连接参数(bootstrap.servers / host / port 等) {"bootstrap.servers":"kafka:9092","group.id":"factor-group"}
schema JSON 数据字段定义(字段名、类型、是否必填) [{"name":"user_id","type":"STRING","required":true}]
access_mode String 访问模式(STREAM / LOOKUP / BATCH) STREAM

4.3.2 数据源适配策略

  • Kafka 流式源:使用 FlinkKafkaConsumer,配置反序列化器(DeserializationSchema),支持 Avro / JSON / Protobuf 格式。消费位点通过 Kafka 内置 offset 管理,作业重启时自动恢复。
  • MySQL 维度源:使用 JDBC Connector 或 Flink CDC,定期拉取或监听 binlog 变更。维度数据通过 AsyncIO 或 Lookup Join 与流数据关联。
  • Redis 缓存源:使用 Redis Connector(如 flink-redis-connector),通过 Jedis / Lettuce 客户端实现键值查询。适用于高频低延迟的配置查询或计数器读取。
注意事项:MySQL 维度源应避免全表扫描,必须为关联字段建立索引。Redis 查询建议使用 Pipeline 批量操作,减少网络往返。Kafka 消费端需设置合理的 auto.offset.reset 策略(建议 earliest 或 latest 根据业务容忍度选择)。

4.4 整体数据模型架构

下图展示了因子定义、元数据管理、数据源抽象三者之间的协作关系,以及 Flink 作业如何通过统一的数据模型层完成实时计算。

因子计算数据模型架构图 因子定义层 factor_id compute_logic (JSON) window_config data_source_id output_topic status 元数据管理层 MySQL 持久化存储 Redis 缓存加速 Flink Broadcast State 版本控制与热更新 配置变更事件流 数据源抽象层 Kafka 流式源 MySQL 维度源 Redis 缓存源 统一连接配置 Schema 管理 Flink 实时计算引擎 DataStream API + BroadcastProcessFunction + AsyncIO 因子计算结果输出(Kafka / Redis) 说明:因子定义层通过元数据管理层下发配置,数据源抽象层提供统一接入,Flink 引擎根据配置动态组装计算拓扑

4.5 因子计算逻辑示例

以下是一个完整的因子定义 JSON 示例,展示如何配置一个“近5分钟用户登录失败次数”的实时计算因子。

{
  "factor_id": "FACTOR_LOGIN_FAIL_5M",
  "factor_name": "近5分钟登录失败次数",
  "compute_logic": {
    "operator": "COUNT",
    "filter": {
      "field": "event_type",
      "value": "LOGIN_FAIL"
    },
    "group_by": ["user_id"],
    "udf_ref": null
  },
  "window_config": {
    "type": "SLIDING",
    "size_seconds": 300,
    "slide_seconds": 60,
    "allowed_lateness": 30
  },
  "data_source_id": "DS_KAFKA_LOGIN",
  "output_topic": "factor_result_login",
  "status": 1
}
解析:该因子从 Kafka 数据源 DS_KAFKA_LOGIN 消费登录事件流,过滤出 event_type 为 LOGIN_FAIL 的记录,按 user_id 分组,在 5 分钟滑动窗口(每 60 秒滑动一次)内统计失败次数,允许 30 秒迟到数据,结果输出到 factor_result_login 主题。

4.6 数据模型设计原则总结

  • 解耦性:因子定义、元数据管理、数据源抽象三层独立演进,通过标准接口交互。
  • 可配置性:所有计算参数通过 JSON 描述,支持运行时动态调整,无需修改代码。
  • 可扩展性:新增数据源类型只需实现统一接口,不影响现有因子逻辑。
  • 一致性:元数据变更通过事件驱动同步至 Flink 作业,保证配置与计算状态一致。