3、特征数据模型设计:定义特征事件Schema、特征ID、时间戳、特征值、缺失标记字段

在实时特征缺失检测系统中,数据模型是上下游所有组件(Producer、Kafka Topic、Consumer、检测引擎)的通信契约。一个设计良好的特征事件 Schema 必须同时满足三个目标:唯一标识特征、精确记录时间、显式表达缺失状态。本节将定义核心字段、数据类型与序列化方案。

3.1 核心字段定义

特征事件(Feature Event)采用 Avro 作为序列化格式,包含以下五个必选字段:

字段名 类型 含义 示例值
feature_id string 全局唯一的特征标识符,通常由业务域+特征名组成 "user:click_rate_7d"
event_timestamp long (epoch millis) 特征值产生或采集的 UTC 毫秒时间戳 1719878400000
feature_value double / null 特征数值;当缺失时为 null 0.873 或 null
is_missing boolean 显式缺失标记:true 表示缺失,false 表示正常 false
source string 特征来源标识(可选但推荐),用于溯源 "flink_job_v2"
设计要点:同时保留 feature_value = null 和 is_missing = true 是一种冗余设计。前者用于数值计算时的空值传播,后者用于快速过滤缺失事件,避免对 null 的二次判断。两者必须保持逻辑一致。

3.2 特征ID 命名规范

特征ID 采用三级命名法,以冒号分隔,确保全局可搜索与自动解析:

<业务域>:<特征名称>[:<聚合窗口>]

示例:

  • user:login_freq_1d — 用户域,登录频率,1天窗口
  • order:amount_avg_7d — 订单域,平均金额,7天窗口
  • device:cpu_util_raw — 设备域,CPU 利用率,原始值(无窗口)
避坑:特征ID 中禁止使用空格、中文、特殊符号(除冒号与下划线外)。Kafka 消息键(Key)通常直接使用 feature_id,特殊符号会导致分区路由异常。

3.3 时间戳语义与精度

时间戳字段 event_timestamp 必须遵守以下规则:

  • 单位:毫秒级 Unix 时间戳(UTC),避免使用字符串格式。
  • 语义:记录特征值在源系统实际产生的时间,而非 Kafka 生产时间或 Broker 接收时间。
  • 时区:统一使用 UTC,消费端按需转换为本地时间。
  • 缺失处理:如果源系统无法提供时间戳,使用 -1 表示未知,但应尽量避免。

3.4 缺失标记字段的三种状态

is_missing 与 feature_value 的组合可以表达三种语义状态:

is_missing feature_value 语义 典型场景
false 非 null 特征正常产生,值有效 正常采集
true null 特征缺失,无值 数据未生成、采集失败
true 非 null 特征缺失,但有默认/填充值 降级策略、默认值填充
检测规则:实时缺失检测引擎只关注 is_missing = true 的事件。当 is_missing = true 且 feature_value 非 null 时,检测引擎应发出“填充值告警”,而非普通缺失告警。

3.5 特征事件 Schema 结构图

下图展示了特征事件从产生到序列化的完整数据模型结构:

特征事件 Schema 结构 FeatureEvent (Avro Record) feature_id string event_timestamp long (epoch millis) feature_value double / null is_missing boolean source string (可选) Kafka 消息 Key = feature_id,Value = Avro 序列化的 FeatureEvent 缺失检测引擎消费时优先检查 is_missing 字段,再读取 feature_value

3.6 Avro Schema 定义示例

以下为完整的 Avro Schema 定义,可直接用于 Kafka Producer 与 Schema Registry:

{
  "namespace": "com.feature.monitoring.avro",
  "type": "record",
  "name": "FeatureEvent",
  "fields": [
    {"name": "feature_id",      "type": "string"},
    {"name": "event_timestamp", "type": "long"},
    {"name": "feature_value",   "type": ["null", "double"], "default": null},
    {"name": "is_missing",      "type": "boolean",         "default": false},
    {"name": "source",          "type": ["null", "string"], "default": null}
  ]
}
Schema Registry 集成:建议将上述 Schema 注册到 Confluent Schema Registry,使用 Avro 序列化器自动管理兼容性。特征ID 作为 Kafka 消息 Key,FeatureEvent 作为 Value,确保相同特征的事件路由到同一分区,保证有序性。

3.7 数据模型与检测流程的映射

下图展示了特征事件从生产到缺失检测的完整数据流,突出 Schema 字段在各个环节的作用:

特征事件数据流与字段映射 特征生产者 填充 feature_id 填充 event_timestamp Kafka Topic Key = feature_id Value = Avro 序列化 缺失检测引擎 检查 is_missing 读取 feature_value 告警 输出 字段在数据流中的关键作用 feature_id → 分区路由与特征聚合 is_missing → 快速过滤缺失事件,避免反序列化整个 feature_value

3.8 设计检查清单

在实施特征数据模型前,请逐项确认以下要点:

  • 字段完备性:是否包含 feature_id、event_timestamp、feature_value、is_missing 四个核心字段?
  • 类型正确性:feature_value 是否允许 null?is_missing 是否为 boolean 而非 int?
  • 命名规范:feature_id 是否遵循三级命名法?是否包含非法字符?
  • 时间戳统一:所有生产者是否使用 UTC 毫秒时间戳?是否避免使用本地时间?
  • Schema 注册:是否已将 Avro Schema 注册到 Schema Registry?兼容性策略是否设置为 BACKWARD?
  • 缺失语义一致性:是否明确 is_missing = true 且 feature_value 非 null 时的处理逻辑?
最佳实践:在开发环境中使用 kafka-avro-console-producer 快速验证 Schema 兼容性。生产环境建议启用 Schema Registry 的 FULL_TRANSITIVE 兼容性检查,防止字段变更导致消费端反序列化失败。