用户画像系统系统的复杂性,通常来自两个方面:
指标计算的复杂度;
大数据下指标计算的实时性;
证券行业的产品买卖并不像普通商品买卖那么简单,例如同一个基金,客户可以分次买入,也可以分批卖出,每次买卖的价格又都可能不一样,这样会导致收益计算的复杂性,这也会导致证券行业上实施用户画像系统会更加复杂一些。
当然,指标计算复杂度的增加还是小的,但是如果交易的数据很多的话,要想能够快速地计算出指标,那就有点难了。
用户画像指标统计的特点
用户画像的相关指标,大致上可以分为三类:
一类是静态指标:通常是不会变化的指标,例如性别,出生年月,爱好等。
第二类是动态指标:通常是随时间变化和交易发生而变化的,例如交易金额等,这类指标通常会有不同的统计维度,例如每日统计,每周统计,每月统计等。
还有一类是实时指标:这类指标则更加特别,主要跟RFM模型相关的指标,例如最近交易到当下的天数,最近30天交易金额,最近半年的收益率等,这些都是跟时间直接相关的,就算什么交易都没有发生,只要时间变化,指标就会跟着变化。
静态指标的计算和存储都是比较简单的,直接设计一个客户表存储即可,对于不同维度上的统计,都是不变的。所以,这类指标也没什么好说的。
传统的数据库设计
以前我们在做这种指标的统计表时,往往是直接设计各种维度的统计表,以数据冗余来实现查询的高效,如下图(本来想自己画一个图,不过既然别人已经画过了,就没必要了):

图一:来自《Apache Doris在美团点评中的实践》
而为了完成这几个统计表,那就需要一堆异步流程任务来完成,例如每次交易,就需要同时写入7天宽表,15天宽表和30天宽表,要保证不重复不遗漏,其代价也是巨大的。在每天凌晨的时候,在更新日宽表,周宽表,月宽表等,
这些异步任务能否及时完整的执行,这又是一个大问题。
如果要设计任意时间段的查询。。。。那就直接悲剧了,而客户往往就是这么想。客户会觉得,能够按时间查询,就能按任意时间段查询,岂不知这实现的难度并不是一个等级的。主要是因为,当数据量巨大的时候,为了可以加速查询,我们通常会做分表的处理,但是一旦分表,任意时间段的查询就很复杂,得考虑是否需要跨表查询。
总之,开发很罗嗦,架构很复杂,维护又很大坑。对于传统数据库,如果数据量足够大,就算简单的RFM模型,要想快速查询也是不容易实现的。
使用ES统计的设计
后来用上了ES,这在设计和实现上倒是简单了,什么都做成一个大宽表就好了。但是这也有问题:
ES不能联表查询,所有查询必须都整成一个大宽表,开始时也不觉得有什么问题。但是我们在做舆情系统的时候,很多数据确实是放到了大宽表上,但是还是有很多关系数据数据需要放在关系数据库中,需要联合查询的时候就麻烦了,要么是先查MySQL再查ES,要么反过来,但是排序和过滤都很麻烦,维护也很复杂。
还有一个维护复杂的原因是,ES的查询语法独树一帜,如果有人一致在钻研使用ES,那可能还没多大问题,一旦不是这样,维护的问题就来了,特别是部署到了客户那里,而现场维护的人往往又不专业,出个小问题也得搞半天,效率很低。
ES和Mysql的联合查询问题,还深深困扰着我们,改又不是,不改也不是。
使用Apache Doris
显然自己还没有实际使用过这个数据库,不过作为性能出众的分析型数据库,基于此设计进行表结构设计,则要简单多了:

图二:来自《Apache Doris在美团点评中的实践》
这就简单了,只要写入一个大宽表即可,借助Doris出众的实时分析的性能,业务端无论是按天查询,还是按月查询,还是任意时间段的查询,都是一个SQL语句就能解决了,完全没有压力。使用ClickHouse应该也是类似的,只是ClickHouse维护比Doris复杂太多,个人不是很喜欢。
这可以很好的解决任意时间维度上的查询,不过还有一个不容易解决的问题,那就是在我们场景下指标计算复杂,可能并不是在SQL语句中就能解决的,还是需要在业务系统中来进行实现。不过这在任何数据库中,可能都是无法避免的。
使用Doris还有一个好处,因为它是列式数据库,所以存储成本会低很多,因为它更容易做数据压缩。
而且,据说Doris还能和ES整合使用,那可真是能比较完整的解决我们的混合使用ES和Mysql的大坑了。因为,有些数据还是必须依赖es的,例如全文检索。es的倒排索引暂时看,还没有好的替换者。
2021-03-27晚
醒来的时候,想到之前同事在决定混用两种数据库来查询时,应该还有几个原因:
其一,就是不少的关系数据是可变的,而这些可变的数据放在es上,经常修改会变得很复杂,例如文章分类,原来分类名是a,你现在想修改为b,这就复杂了,因为库中有几十亿的数据。当然,这个问题的解决还是不难的,只要在MySQL数据库中建相应的映射表即可。
其二,有些数据是后来设置时加上去的,例如事件,业务员可以根据需要设置事件,而系统自动关联所有相关的文章和评论标,显然这是非常适合存在MySQL中的,因为MySQL可以很方便的进行联表查询,而es不行。
其三,es的存储成本比较高,客户接受不了,所以在es只是保留了最近三个月的数据,这也是最常使用的部分,历史的数据都转存到MySQL上。这又造成一大坑,得实现它们之间的数据同步,还得实现和维护两套查询,而且客户的查询条件又很多……造成了现在维护的悲剧。
es存储成本高,除了本身数据量巨大,而其本身的存储空间效率也不高,还有就是因为不能联表查询,所以大宽表必须保存大量的冗余数据。
20210328上午




