最近接手了公司的一个实时特征系统,属于陈年屎山项目,问题挺多的。老板让我看看怎么重构,但一直考虑不清楚,想来请教下大家。
1. 系统现状
这个系统主要是给各种模型提供实时的特征查询,比如:近 x 分钟的成交量,某 x 分钟的成交量.
下面讲讲这样搞有啥问题,这草台系统居然也跑那么多年了。。。😓👍
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 的存储压力。
另外,我们的特征有一些特点:
- 特征都是简单的数值,不会是结构体
- 特征的查询维度不多,一般就 5 个左右。但是,部分维度的枚举值非常多(可能在十万级别),也意味着如果使用缓存,可能命中率不高
- 特征生命周期短,只保存 1 小时左右即可
- 查询实时性比较高,要能在秒级别同步
于是,我调研了各种数据库:starrocks, clickhouse 这类 olap 数据库; influxdb 这类时序数据库。
从网上收集到的资料看,功能上大概都能满足。但感觉他们都不太能扛得住我们这么高的查询量,并且提供一个与 redis 相近的查询延迟。
这一块我纯小白,刚毕业没多久,是真不知道咋搞了。有没有f友能救救,跪谢😣😣😣
|