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 配置变更流程
- 运维人员通过管理平台修改因子定义,写入 MySQL 并记录版本号。
- 变更事件发送至 Kafka 配置变更主题(config_change_topic)。
- Flink 作业通过 BroadcastProcessFunction 接收变更流,更新 Broadcast State。
- 作业根据新配置重新构建计算逻辑,无需重启作业。
最佳实践: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 作业如何通过统一的数据模型层完成实时计算。
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 作业,保证配置与计算状态一致。