从0到1:海量数据下查询优化之旅

88 阅读4分钟

一、业务背景

最近官官同学加入了一家新的公司,来到这个公司后,发现自己负责所在的系统经常被业务吐槽,”为什么系统打不开了“,”为什么我的页面动不了“,”为什么查询不了数据",同事到处救火,天天处理线上问题,然后就白天答疑,晚上写代码,天天加班,心想,如果来了之后天天加班,那还得了,后来跟领导反馈了此问题,从此开始了系统优化之旅。经过整理排查,主要核心的问题是查询,系统存在大量的慢sql,大量的使用联表查询,一个查询关联十几张表是到处可见,因为大量的慢查询,导致数据库负载过高,影响了整个系统性能。

image.png

二、问题特点

分析后,查询有以下特征,查询条件、join数量、返回的数据字段也非常多,有些查询条件没有走索引,我们都知道如果大量的使用join关联会导致表之间产生笛卡尔积,会大量占用系统资源。那怎么解决一下问题呢

三、技术选型

  • 增加索引:虽然能解决部分场景问题,如果建立大量的索引,会大大降低插入和更新等一些变更场景的性能。
  • 同步更新:数据更新后,同步写入es中,实时性高,异常情况下,很容易造成数据不一致,并且跟业务代码耦合在一起,不符合程序开发规范。
  • 异步更新:数据更新后,监听binlog日志,利用中间件将消息发送到kafka 中,消费队列中的消息, 再更新es数据,这种方案既然不影响现有业务,同步还能解决同步更新带来的问题,何乐而不为呢

四、数据异构

基本原理

debuzium 中间件监听mysql binlog日志,然后将结构化的数据发送到kafka中,由etl-service (数据同步服务) 监听消息,将mysql的变更更新到es中

mysql 同步 es流程图.drawio.png

中间件介绍

  • debuzium (官网地址:debezium.io/

    • Debezium是一个用于变更数据捕获的开源分布式平台,类似于canal。

    注:为什么不选用canal,最大的原因是公司有各种数据库,例如:mysql,sqlservice, oracle,canal只支持mysql,但是debuzium支持的数据很广,不局限mysql

  • Kafka 消息队列

    • 具有高吞吐,数据持久化,在大数据量的情况依然性能良好,支持批量消费
    • 基于上述特点,非常适合数据异构的场景
    • 同时支持批量消费,批量提交ack
  • etl-service 数据同步服务

    • 使用java语言开发的一个通用服务,维护多个es索引的初始化,变更
    • 消费kafka中每个表的变更消息,同时将变更消息组装成es宽表数据,保存到es中
  • es 搜索引擎

    • 分布式架构,可以存储海量数据,数据分布在多个节点上,具有可扩展性和容错性特点
    • 支持实时搜索分析,通过倒排索引的方式,使得支持复杂的查询
    • 多种数据类型支持,可以灵活处理不同的数据
    • 数据分析和聚合,提供了丰富的功能,可以对数据进行统计,分组,排序等操作,方便数据分析和可视化
    • 自定义词库,可以自定义分词器,将公司的一些特有品牌,型号,分类等同步到词库当中,可以很大程度上提升搜索体验

    基于上述特点,非常符合公司现有业务需求,在大量条件的情况下,es可以给特定字段进行倒排索引,使得搜索性能非常高,所以选择es

三、总结

以上对 “大数量下的查询已优化” 的优化方案做了一个简单的梳理,包括技术选型,技术方案确定,技术方案相关中间件的简单介绍,后续会补充相关中间件的整体用法,以及etl-service 如果进行搭建

如果文章对你帮助,动动大家发财的小手帮忙点点赞