最近接手了公司的一个实时特征系统,属于陈年屎山项目,问题挺多的。老板让我看看怎么重构,但一直考虑不清楚,想来请教下大家。

1. 系统现状

这个系统主要是给各种模型提供实时的特征查询,比如:近 x 分钟的成交量,某 x 分钟的成交量.

  • 我们通过流式任务消费上游的 mq ,直接产生具体的特征值,写入到 redis 集群里。再通过一个接口,支持对特征的查询。

  • 按峰值来算,写入任务每秒要对 redis 执行 1000w+次写入相关命令;服务接口查询 qps 在 40w+,对 redis 的查询 qps 有 120w+。

下面讲讲这样搞有啥问题,这草台系统居然也跑那么多年了。。。😓👍

1.1 写入聚合的问题

举个例子,假设当前时是第 x 分钟,对于特征 近 5 分钟的成交量 ,需要一个滑动窗口来实现。我们会在消费到一条订单消息时,分别给这 5 个 key 执行 +1: 成交量#x, 成交量#x+1,...,成交量#x+4.

这样,在第 x 分钟时查询 成交量#x ;在第 x+1 分钟时查询 成交量#x+1…… 我们都可以得到一个当前时间节点对应的准确的特征值。

这种方式使得一个特征的写入次数和 key 数量都产生激增

1.2 查询聚合的问题

对于另一类特征,比如 第 0~4 分钟的成交量 。我们需要 MGET 出第 0,1,...,4 分钟 5 个特征 key 的值,然后求和。当然,也可以提前生产按 5 分钟聚合的特征值,这就又引入了 1.1 的问题。

这种方式使得一个特征的查询,对 redis 有很高的扇出

1.3 难以维护的配置,摇摇欲坠的 redis 集群

按上面的做法,每当业务需要一个新特征。我都得人工分析并进行配置,是写入时聚合好?还是查询时聚合好?并且配置复杂容易出错。😱

另外,从实际表现看,不管哪种方式,对 redis 的 cpu 压力都很大……😭

2. 一些想法

目前我的思路主要是在系统底层补充一个 具有简单聚合能力的数据库 存储较为原始的特征信息,由数据库负责做统计、聚合。redis 仅作为缓存使用。

这样我就不需要人工考虑一个特征到底该怎么生产,怎么查询了,大幅降低维护成本。也可以减少 redis 的存储压力。

另外,我们的特征有一些特点:

  1. 特征都是简单的数值,不会是结构体
  2. 特征的查询维度不多,一般就 5 个左右。但是,部分维度的枚举值非常多(可能在十万级别),也意味着如果使用缓存,可能命中率不高
  3. 特征生命周期短,只保存 1 小时左右即可
  4. 查询实时性比较高,要能在秒级别同步

于是,我调研了各种数据库:starrocks, clickhouse 这类 olap 数据库; influxdb 这类时序数据库。

从网上收集到的资料看,功能上大概都能满足。但感觉他们都不太能扛得住我们这么高的查询量,并且提供一个与 redis 相近的查询延迟。

这一块我纯小白,刚毕业没多久,是真不知道咋搞了。有没有f友能救救,跪谢😣😣😣

举报· 208 次点击
登录 注册 站外分享
1 条回复  
liprais 小成 3 天前
flink 开个时间窗口聚合完事
返回顶部