2. 贷后预警数据模型设计
贷后预警系统的核心是数据。在 Flink 中构建实时预警任务,首先需要将业务数据抽象为逻辑模型,并定义 Flink Table 的 Schema,同时引入事件时间与水位线机制来保证计算的准确性。本章将围绕贷后业务实体关系、Flink 表定义以及时间语义展开。
2.1 贷后数据实体关系
贷后预警涉及四个核心业务实体:客户、贷款、还款计划和逾期记录。它们之间的逻辑关系如下:
- 客户:唯一标识借款人,是预警触达的对象。
- 贷款:客户名下的每一笔借款,包含金额、利率、起止日期等。
- 还款计划:每笔贷款对应的分期还款明细,包含每期应还日期、应还金额。
- 逾期记录:当实际还款行为晚于计划应还日期时,系统生成的逾期事件。
关键关系: 一个客户可以有多笔贷款;一笔贷款对应多条还款计划;一条还款计划可能触发零条或多条逾期记录。
下表列出了各实体的核心字段:
| 实体 | 核心字段 | 说明 |
|---|---|---|
| 客户 | customer_id, name, phone, credit_level | 客户唯一标识与信用等级 |
| 贷款 | loan_id, customer_id, amount, term, start_date, end_date | 贷款金额、期限、起止日期 |
| 还款计划 | plan_id, loan_id, due_date, due_amount, status | 每期应还日期与金额,状态标识是否已还 |
| 逾期记录 | overdue_id, plan_id, overdue_days, overdue_amount, create_time | 逾期天数、逾期金额、记录生成时间 |
2.2 Flink Table Schema 定义
在 Flink SQL 中,我们需要将上述实体映射为 Table 的 Schema。以下以“还款计划”和“逾期记录”为例,展示 DDL 定义:
-- 还款计划表(来自 Kafka)
CREATE TABLE repayment_plan (
plan_id BIGINT,
loan_id BIGINT,
due_date DATE,
due_amount DECIMAL(10, 2),
status STRING,
-- 事件时间字段:计划应还日期
event_time AS TO_TIMESTAMP(CONCAT(due_date, ' 23:59:59')),
WATERMARK FOR event_time AS event_time - INTERVAL '1' DAY
) WITH (
'connector' = 'kafka',
'topic' = 'repayment_plan',
'format' = 'json',
'properties.bootstrap.servers' = 'localhost:9092'
);
-- 逾期记录表(来自 Kafka)
CREATE TABLE overdue_record (
overdue_id BIGINT,
plan_id BIGINT,
overdue_days INT,
overdue_amount DECIMAL(10, 2),
create_time TIMESTAMP(3),
-- 事件时间字段:记录生成时间
event_time AS create_time,
WATERMARK FOR event_time AS event_time - INTERVAL '5' SECOND
) WITH (
'connector' = 'kafka',
'topic' = 'overdue_record',
'format' = 'json',
'properties.bootstrap.servers' = 'localhost:9092'
);
Schema 设计要点:
- 使用
AS定义计算列,将业务时间转换为 TIMESTAMP 类型。 - 每个表必须显式声明
WATERMARK,否则无法使用事件时间语义。 - 水位线延迟时间根据数据乱序程度设置,还款计划延迟较大(1天),逾期记录延迟较小(5秒)。
2.3 事件时间与水位线概念
在贷后预警场景中,数据到达 Flink 的时间(处理时间)与业务实际发生的时间(事件时间)往往不一致。例如,一笔逾期记录可能因为系统延迟在 10 秒后才到达。为了准确判断“是否逾期”,我们必须使用事件时间。
| 时间语义 | 定义 | 贷后场景适用性 |
|---|---|---|
| 事件时间 | 业务实际发生的时间戳 | ✅ 必须使用,保证逾期判断准确 |
| 处理时间 | 数据到达 Flink 算子的机器时间 | ❌ 不适用,受延迟影响 |
| 摄入时间 | 数据进入 Flink 源算子的时间 | ⚠️ 仅作参考,不推荐 |
水位线(Watermark) 是 Flink 中衡量事件时间进度的机制。它表示“当前时间之前的数据已经全部到达”,触发窗口计算或关联操作。
- 水位线 = 当前最大事件时间 - 允许的最大乱序时间
- 当水位线超过窗口结束时间时,触发窗口计算。
- 在贷后预警中,水位线帮助我们在“逾期记录”和“还款计划”进行 temporal join 时,避免因数据乱序导致漏关联。
常见陷阱: 如果水位线设置过小(乱序容忍时间过短),会导致部分迟到数据被丢弃,造成预警漏报;如果设置过大,则会增加计算延迟。建议根据业务数据实际乱序统计(如 95 分位延迟)来设定。