2. 样本数据采集与接入:实时数据流(Kafka/Flink)接入、样本字段定义、数据格式规范(JSON/CSV/Parquet)
实时风控系统的核心在于“快”与“准”。样本数据的采集与接入是校验流程的起点,决定了后续规则引擎、模型推理与离线分析的数据质量。本章聚焦于实时数据流的接入方式、样本字段的标准化定义以及三种主流数据格式(JSON、CSV、Parquet)的选型与规范。
2.1 实时数据流接入架构
在风控场景中,样本数据通常以毫秒级延迟从业务前端(如登录、支付、下单)产生,经过消息队列缓冲后,由流计算引擎进行清洗与分发。下图展示了典型的实时样本接入架构:
2.2 样本字段定义规范
统一的字段定义是跨团队协作与自动化校验的基础。实时风控样本至少应包含以下四类字段:
| 字段类别 | 字段名称 | 数据类型 | 示例值 | 说明 |
|---|---|---|---|---|
| 事件标识 | event_id | STRING | evt_20250321_001234 | 全局唯一事件ID,用于去重与追踪 |
| 时间戳 | event_time | BIGINT | 1742544000000 | 事件发生时间(毫秒级Unix时间戳) |
| 业务主体 | user_id | STRING | U10086 | 用户标识,脱敏后传入 |
| 业务主体 | device_id | STRING | D7f3a2b1c | 设备指纹标识 |
| 行为特征 | action_type | STRING | login | 行为类型枚举:login/pay/register等 |
| 行为特征 | amount | DOUBLE | 1999.00 | 交易金额,单位元 |
| 环境信息 | ip_address | STRING | 192.168.1.1 | 客户端IP地址 |
| 环境信息 | ua | STRING | Mozilla/5.0 ... | User-Agent 原始字符串 |
最佳实践:建议所有字段名采用小写蛇形命名法(snake_case),时间戳统一使用毫秒级 BIGINT,避免时区与精度歧义。event_id 必须包含时间戳与随机数,确保全局唯一。
2.3 数据格式规范与选型
实时风控场景下,JSON、CSV、Parquet 三种格式各有优劣。选择依据主要考虑:解析速度、压缩比、Schema 支持度与下游工具兼容性。
2.3.1 JSON 格式规范
JSON 是实时风控中最常用的格式,支持嵌套结构与动态字段。以下为标准化样本示例:
{
"event_id": "evt_20250321_001234",
"event_time": 1742544000000,
"user_id": "U10086",
"device_id": "D7f3a2b1c",
"action_type": "login",
"amount": 1999.00,
"ip_address": "192.168.1.1",
"ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"ext_fields": {
"risk_tag": "high",
"source_channel": "app"
}
}
校验要点:必须校验 JSON 的合法性(是否可解析)、必填字段是否存在、字段类型是否匹配(如 amount 必须为数值类型)。ext_fields 为可选扩展字段,允许业务方自定义传入。
2.3.2 CSV 格式规范
CSV 格式要求字段顺序固定,且必须包含表头行。实时接入时建议使用带引号的 CSV 以避免分隔符冲突:
event_id,event_time,user_id,device_id,action_type,amount,ip_address,ua
evt_20250321_001234,1742544000000,U10086,D7f3a2b1c,login,1999.00,192.168.1.1,"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
避坑提示:CSV 无内建 Schema 校验,字段错位或缺失会导致整行解析失败。建议在 Flink 中预先定义字段索引映射,并启用“严格模式”拒绝不符合列数的行。
2.3.3 Parquet 格式规范
Parquet 是列式存储格式,适用于批量写入与分析。在 Flink 中可通过 FileSink 将清洗后的样本转换为 Parquet:
-- Flink SQL 示例:将 Kafka JSON 流写入 Parquet 文件
CREATE TABLE parquet_sink (
event_id STRING,
event_time BIGINT,
user_id STRING,
amount DOUBLE,
action_type STRING
) WITH (
'connector' = 'filesystem',
'path' = 'hdfs://data/risk_sample_parquet/',
'format' = 'parquet',
'parquet.compression' = 'snappy'
);
INSERT INTO parquet_sink
SELECT event_id, event_time, user_id, amount, action_type
FROM kafka_source;
性能建议:Parquet 配合 Snappy 压缩可在存储空间与读取速度之间取得良好平衡。建议按 event_time 进行分区(如按小时分区),便于后续时间范围裁剪查询。
2.4 数据质量校验前置规则
在样本数据正式进入校验引擎之前,Flink 流处理阶段应执行以下前置校验,确保基础数据质量:
- 完整性校验:必填字段(event_id、event_time、user_id、action_type)不允许为 NULL 或空字符串。
- 唯一性校验:基于 event_id 进行去重,防止重复样本影响统计与模型训练。
- 时间戳合理性校验:event_time 必须在当前时间前后 5 分钟以内,拒绝过期或未来时间戳。
- 枚举值校验:action_type 必须属于预定义枚举列表(如 login、pay、register、withdraw)。
- 数值范围校验:amount 必须大于 0 且小于 1,000,000(根据业务调整上限)。
实践案例:某支付风控项目在接入阶段因未校验 event_id 唯一性,导致同一笔交易被重复计算 3 次,触发误拦截。加入 Flink 去重算子(基于 event_id + 窗口)后,误报率下降 72%。