千万级联表查询-读写分离改造

需求背景

在企业后台管理系统中,充斥着各种对象关联关系,联表查询必不可少。很多CRM项目在发展初期,背后的列表查询SQL都是各种join,主打一个敏捷开发,快速上线。在项目的访问量、数据量比较小的时候,即便join四五张表,确实也不会有什么查询压力。但随着业务的发展,C端用户量逐渐增加,各种数据库表也在不断膨胀,原先200ms内就能响应的列表查询接口,要loading个几秒甚至几十秒才能返回数据。即便拆分查询SQL语句,也只能优化部分查询条件的检索速度,很难彻底地解决慢查询问题,这时就需要进行读写分离改造了。

方案选型

个人计划的读写分离方案有两种

  • 将所有需要联表查询的表数据实时同步至OLAP数据库,例如Clickhouse和Kudu,在OLAP数据库上进行联表查询。
sql 复制代码
优点:改造成本最小,只需要在OLAP数据库中建个一模一样的表,Binlog增量同步就完事,查询SQL几乎不用变,替换数据库连接配置即可。
缺点:没用过,暂时不知道,但我估计存储成本会比下面这个Elasticsearch异构方案高点。
  • 将多个具备关联关系的数据源,异构成一个聚合对象,同步至Elasticsearch,使用nested嵌套查询。

    优点:可以存储数组、嵌套对象,检索方式比较多样,全文检索功能强大。
    缺点:后期维护成本较高,如果有新加字段,源表加完字段还得改ES同步逻辑。

最终选用方案:异构同步至Elasticsearch

  • 为什么:没为什么,我真的很想用OLAP解决这需求,但是公司的公共数据库部门在OLAP这方面没啥投入,大部分精力都投入在MySQL分片库、OLTP、Hive、Elasticsearch等地方,只有MySQL分片库、Elasticsearch和一个半自研的NewSQL具备核心保障级别。我甚至都没见到一个像样的Clickhouse建库工单 T-T。

技术实现

数据源梳理

首先,我们的对象关系,类似于下图所示(只是举个例子,实际业务肯定不长这样哈)

会有一个主表,对应多个关联表。关联表小的有几百条数据,多的有几千万条数据,尤其是标签表,一个用户头上挂着几十个标签都很正常,有一百万的用户就有几千万的标签关系。且存储的数据源各不相同,有些是自己部门的,有些是其他部门的,各个数据源情况类似于下图所示

反正就是各式各样,五花八门

对象异构

数据聚合,以用户对象为根,六合一,组成嵌套对象

同步方案

  • 用户主表增量同步:咱们公司有开箱即用的Binlog同步平台,我只管从RocketMQ里消费Binlog事件就ok。

  • 用户主表全量同步:半夜开个定时任务,扫表,定时更新一些很久没有人操作过的历史数据(有些用户可能很久都没有信息、订单、好友关系变更,但是他的标签变了,得同步这批冷数据的关联标签)。

  • 用户关联数据同步:接收到一条用户表Binlog事件时,按用户id查出所有关联数据,聚合在一起塞进Elasticsearch。

  • 分布式锁:因为Elasticsearch数据保存后不能立马查到,如果在数据插入Elasticsearch后,马上又来一条更新事件,这时是没法从Elasticsearch中查出刚插入的数据的,然后该更新事件就会被判定为是新增事件,导致重复新增两条一样的记录,因此需要一个利用ETCD或者Redis的分布式锁功能,在新增时加把锁,避免重复新增同一条记录。

完整流程

简单来说,同步流程以用户主表更新为关键触发点。当用户加好友、下单、编辑个人信息时,都会触发用户表记录更新(可以理解为,想要触发用户数据同步逻辑,就得更新用户表,统一收口,方便后续迭代维护),此时会将本次用户更新操作的binlog数据抛入消息队列,当数据同步服务接收到binlog数据后,查出所有关联数据,聚合写入ES。

End

相关推荐
兆子龙1 小时前
从 float 到 Flex/Grid:CSS 左右布局简史与「刁钻」布局怎么搞
前端·架构
初次攀爬者2 小时前
RabbitMQ的消息模式和高级特性
后端·消息队列·rabbitmq
爱勇宝5 小时前
2026一人公司生存指南:用AI大模型,90天跑出你的第一条现金流
前端·后端·架构
偷油师傅6 小时前
拆解 OpenClaw - 05:13 个省 Token 的设计
架构
兆子龙6 小时前
当「多应用共享组件」成了刚需:我们从需求到模块联邦的落地小史
前端·架构
sunny_19 小时前
⚡️ vite-plugin-oxc:从 Babel 到 Oxc,我为 Vite 写了一个高性能编译插件
前端·webpack·架构
兆子龙1 天前
模块联邦(Module Federation)详解:从概念到手把手 Demo
前端·架构
Bigger1 天前
告别版本焦虑:如何为 Hugo 项目定制专属构建环境
前端·架构·go
狗哥哥1 天前
微前端架构下的平台级公共组件资源体系设计
前端·架构
两万五千个小时1 天前
落地实现 Anthropic Multi-Agent Research System
人工智能·python·架构