0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

十亿级订单系统的数据库查询性能优化之路

京东云 来源:京东零售 崔健 作者:京东零售 崔健 2024-12-11 09:54 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

作者:京东零售 崔健

0.前言

•系统概要:BIP采购系统用于京东采销部门向供应商采购商品,并且提供了多种创建采购单的方式以及采购单审批、回告、下传回传等业务功能

•系统价值:向供应商采购商品增加库存,满足库存周转及客户订单的销售,供应链最重要的第一环节

1.背景

采购系统在经历了多年的迭代后,在数据库查询层面面临巨大的性能挑战。核心根因主要有以下几方面:

复杂查询多,历史上通过MySQL和JED承载了过多的检索过滤条件,时至今日很难推动接口使用方改变调用方式

数据量大,随着业务的持续发展,带来了海量的数据增长(日均150万单左右,订单主表/子表/渠道表/扩展表分别都是:6.5亿行,订单明细表/分配表:9.2亿行,日志表:60亿行)

数据模型复杂,订单完整数据分布在20+张表,经常需要多表join

引入的主要问题有:

•业务层面:

订单列表页查询/导出体验差,性能非常依赖输入条件,尤其是在面对订单数据倾斜的时候,部分用户无法查询/导出超过半个月以上的订单

查询条件不合理,1.归档筛选条件,技术词汇透传到业务,导致相同周期的单子无法一键查询/导出,需要切换“是否归档”查询全部;2.无法区分“需要仓库收货”类的单子,大部分业务同事主要关注这类单子的履约情况

•技术层面:

慢SQL多,各种多表关联复杂条件查询导致,索引、SQL已经优化道了瓶颈,经常出现数据库负载被拉高

大表多,难在数据库上做DDL,可能会引起核心写库负载升高、主从延迟等问题

模型复杂,开发、迭代成本高,查询索引字段散落在多个表中,导致查询性能下降

2.目标

业务层面:提升核心查询/导出体验,加强查询性能,优化不合理的查询条件

技术层面:1.减少慢SQL,降低数据库负载,提高系统稳定性;2.降低单表数据量级;3.简化数据模型

3.挑战

提升海量数据、复杂场景下的查询性能!

•采购订单系统 VS C端销售订单系统复杂度对比:

对比项 采购订单系统 C端订单销售系统
分库逻辑 使用采购单号分库 按用户pin分库分表
查询场景 面向采销、接口人、供应商、仓储运营提供包括采销员、单号、SKU、供应商、部门、配送中心、库房等多场景复杂查询 主要是按用户pin进行订单查询
单据所属人 采购单生成后,采销可以进行单据转移 订单生成后订单所属人不变
数据倾斜 单一采销或供应商存在大量采购单,并且自动补货会自动创建采购单 C端一个用户pin下订单数量有限

4.方案

思路

wKgZPGdXpkWAbcf7AABKgVX1x9k178.jpg

优化前

wKgZO2dXpkaASpVAAAGHV34CD9U786.png

优化后

wKgZPGdXpkeAXa_1AAJ1wV-XQVw870.png

4.1 降低查询数据量

4.1.1 前期调研

基于历史数据、业务调研分析,采购订单只有8%的订单属于“需要实际送货至京东库房”的范围,也就是拥有完整订单履约流程、业务核心关注时效的。其余订单属于通过客户订单驱动,在采购系统的生命周期只有创建记录

wKgZO2dXpkiAdE4uAAD2w4r_XLw662.jpg

基于以上结论,在与产品达成共识后,提出新的业务领域概念:“入库订单”,在查询时单独异构这部分订单数据(前期也曾考虑过,直接从写入层面拆分入库订单,但是因为开发成本、改动范围被pass了)。异构这部分数据实际也参考了操作系统、中间件的核心优化思路,缓存访问频次高的热数据

4.1.2 入库订单异构

执行流程

wKgZPGdXpkmAPj5gAADI9v5shkM141.jpg

•“入库”订单数据打标

◦增量订单在创建订单完成时写入;存量订单通过离线表推数

◦需要订单创建模块先完成改造上线,再同步历史,保证数据不丢

◦如果在【数据解析模块】处理binlog时无法及时从JimKV获取到订单标识,会补偿反查数据库并回写JimKV,提升其他表的binlog处理效率

•binlog监听

◦基于公司的【数据订阅】任务,通过消费JMQ实现。其中订阅任务基于订单号进行MQ数据分区,并且在消费端配置不允许消息重试,防止消息时序错乱

◦其中,根据订单号进行各个表的MQ数据分区,第一版设计可能会引起热分区,导致消费速率变慢,基于这个问题识别到热分区主要是由于频繁更新订单明细数据导致(订单(1)->明细(N)),于是将明细相关表基于自身id进行分区,其他订单纬度表还是基于订单号。这样既不影响订单数据更新的先后顺序,也不会造成热分区、还可以保证明细数据的准确性

•数据同步

◦增量数据同步可以采用源库的增量binlog进行解析即可,存量数据通过申请新库/表,进行DTS的存量+增量同步写入,完成binlog生产

◦以上是在上线前的临时链路,上线后需要切换到源库同步binlog的增量订阅任务,此时依赖“位点回拨”+“数据可重入”。位点回拨基于订阅任务的binlog时间戳,数据可重入依赖上文提到的MQ消费有序以及SQL覆盖写

•数据校对

◦以表为纬度,优先统计总数,再随机抽样明细进行比对

◦目前入库订单量为稳定在5000万,全部实时订单量级6.5亿,降低92%

4.2 提升复杂查询能力

4.2.1 数据准备

•考虑到异构“入库”订单到JED,虽然数据查询时效性可以有一定保障,但是在复杂查询能力以及识别“非入库”订单还没有支持

•其中,“非入库”订单业务对于订单数据时效性要求并不高(1.订单创建源于客户订单;2.没有履约流程;3.无需手动操作订单关键节点)

•所以,考虑将这部分查询能力转移到ES上

ES数据异构过程

wKgZO2dXpkqAGjxcAACoceq29DY089.jpg

•首先,同步到ES的数据的由“实时+归档”订单组成,其中合计20亿订单,顺带优化了先前归档ES大索引(所有订单放在同一个索引)的问题,改成基于“月份”存储订单,之所以改成月份是因为根据条件查询分两种:1.一定会有查询时间范围(最多3个月);2.指定单号查询,这种会优先检索单号对应的订单创建时间,再路由到指定索引

•其次,简化了归档程序流程,历史方案是程序中直接写入【归档JED+归档ES】,现在优化成只写入JED,ES数据通过【数据解析模块】完成,简化归档程序的同时,提高了归档能力的时效性

•再次,因为ES是存储全量订单,需要支持复杂条件的查询,所以在订单没有物理删除的前提下,【数据解析模块】会过滤所有delete语句,保证全量订单数据的完整性

•接着,为了提升同步到ES数据的吞吐,在MQ消费端,主要做了两方面优化:1.会根据表和具体操作进行binlog的请求合并;2.降低对于ES内部refresh机制的依赖,将2分钟内更新到ES的数据缓存到JimKV,更新前从缓存中获取

•最后,上文提到,同步到入库JED,有的表是根据订单号,有的表是根据自身id。那么ES这里,因为NoSQL的设计,和线程并发的问题,为了防止数据错误,只能将所有表数据根据单号路由到相同的MQ分区

4.2.2 查询调度策略设计

优化前,所有的查询请求都会直接落到数据库进行查询,可以高效查询完全取决于用户的筛选条件是否可以精准缩小数据查询范围

优化后,新增动态路由层

离线计算T-1的采销/供应商的订单数据倾斜,将数据倾斜情况推送到JimDB集群

根据登陆用户、数据延迟要求、查询数据范围,自动调度查询的数据集群,实现高性能的查询请求

查询调度

wKgZPGdXpkuAMvM6AACiOgSxhxo555.jpg

5.ES主备机制&数据监控

1.主/备ES可以通过DUCC开关,实现动态切换,提升数据可靠性

2.结合公司的业务监控,完成订单数据延迟监控(数据同步模块写入时间-订单创建时间)

3.开启消息队列积压告警

5.1 ES集群主/备机制

1:1ES集群进行互备,应急预案快速切换,保证高可用

wKgZO2dXpkyAY3AfAAJzs0G-Log316.png

5.2 数据监控

wKgZPGdXpk2ACAFoAAFYtOhWBnM103.png

6.灰度上线

•第一步,优先上线数据模块,耗费较多时间的原因:1.整体数据量级以及历史数据复杂度的问题;2.数据同步链路比较长,中间环节多

•第二步,预发环境验证,流量回放并没有做到长周期的完全自动化,根因:1.项目周期相对紧张;2.新老集群的数据还是有一些区别,回放脚本不够完善

•第三步,用户功能灰度,主要是借助JDOS的负载均衡策略结合用户erp完成

•第四部,对外接口灰度,通过控制新代码灰度容器个数,逐步放量

wKgZO2dXpk6ANtV6AALJPiBnIt0217.jpg

7.成果

平稳切换,无线上问题

指标 具体提升
采购列表查询(ms) 1、TP999:4817 优化到 2872,提升40.37% 2、超管、部门管理员由无法查询超过一周范围的订单,优化为可以在2秒内查询3个月的订单 3、页面删除“是否归档”查询条件,简化业务操作 4、页面新增“是否入库”查询条件,聚焦核心业务数据
仓储运营列表(ms) TP999:9009 优化到 6545,提升27.34%
采购统计查询(ms) TP999:13219 优化到 1546,提升88.3%
慢SQL指标(天纬度) 1、1s-2s慢SQL数:820->72,降低91% 2、2s-5s慢SQL数:276->26,降低90% 3、5s以上慢SQL数:343->6,降低98%

8.待办

•主动监控层面,新增按照天纬度进行数据比对、异常告警的能力,提高问题发现率

•优化数据模型,对历史无用订单表进行精简,降低开发、运维成本,提升需求迭代效率

•精简存储集群

◦逐步下线其他非核心业务存储集群,减少外部依赖,提高系统容错度

◦目前全量订单ES集群已经可以支持多场景的外部查询,未来考虑是否可以逐步下线入库订单JED

•识别数据库隐患,基于慢日志监控,重新梳理引入模块,逐步优化,持续降低数据库负载

•MySQL减负,探索其他优化方案,减少数据量存储,提升数据灵活性。优先从业务层面出发,识别库里进行中的僵尸订单的根因,进行分类,强制结束

•降级方案,当数据同步或者数据库存在异常时,可以做到秒级无感切换,提升业务可用率

9.写在最后

•为什么没考虑Doris?因为ES是团队应用相对成熟的中间件,处于学习、开发成本考虑

•未来入库的JED相关表是否可以下掉,用ES完全替代?目前看可以,当初设计冗余入库JED也是出于对于ES不确定性以及数据延迟的角度考虑,而且历史的一部分查询就落在了异构的全量实时订单JED上。现在,JED官方也不是很推荐非route key的查询。最后,现阶段因为降低了数据量和拆分了业务场景,入库JED的查询性能还是非常不错的

•因为项目排期、个人能力的因素,在方案设计上会有考虑不周的场景,本期只是优化了最核心的业务、技术痛点,未来还有很大持续优化的空间。中间件的使用并不是可以优化数据库性能的银弹,最核心的还是要结合业务以及系统历史背景,在不断纠结当中寻找balance

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 数据库
    +关注

    关注

    7

    文章

    3993

    浏览量

    67736
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    基于数据库查询过程优化设计

    在大型关系数据库管理与开发中,优化设计极大地提高数据库性能。通过对一大型数据库查询语句执行过程
    发表于 02-27 16:05 18次下载

    分布式异构数据库查询优化方法的研究

    对于分布式异构数据库查询优化既是非常复杂的问题,又是影响系统性能的关键因素。本文结合遗传算法和位爬山算法的优点,提出了基于遗传爬山算法的分布式异构
    发表于 12-25 14:35 9次下载

    查询数据库的最完美技巧

    查询数据库的最完美技巧.rar
    发表于 03-15 14:15 24次下载

    分布式数据库分片关系变换查询优化

    基于分布式查询的概念和优化要求,结合实际的信息管理系统分片查询的实践,描述分布式数据库分片查询
    发表于 05-03 17:04 0次下载
    分布式<b class='flag-5'>数据库</b>分片关系变换<b class='flag-5'>查询</b><b class='flag-5'>优化</b>

    数据库查询优化方法的研究与探索

    SQL是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统。不同的实现方法之间可能存在的
    发表于 08-08 14:43 0次下载

    基于语义指向性分析的数据库访问查询优化设计

    基于语义指向性分析的数据库访问查询优化设计_马晓珺
    发表于 01-03 17:41 0次下载

    如何优化数据库负载

    摘要:一个前端开发者介绍了他和他的数据库朋友们是如何降低基于Ruby网站数据库负载的故事。以下为译文: 数据库负载可能是个沉默的性能杀手。我一直都在
    发表于 09-28 16:32 0次下载

    提高Oracle的数据库性能

    问题。通过优化SQL语句效率、扩充高级缓冲区和配置重做日志缓冲区等几个方面介绍了Oracle数据库优化方法,探讨了OraCle如何提高性能优化
    发表于 11-11 18:16 4次下载

    基于Greenplum数据库查询优化

    针对分布式数据库查询效率随着数据规模的增大而降低的问题,以Greenplum分布式数据库为研究对象,从优化
    发表于 03-29 17:46 0次下载

    数据库系统概论之如何进行关系查询处理和查询优化

    本文档的主要内容详细介绍的是数据库系统概论之如何进行关系查询处理和查询优化主要内容包括了:1、关系数据库系统
    发表于 11-15 15:12 11次下载
    <b class='flag-5'>数据库系统</b>概论之如何进行关系<b class='flag-5'>查询</b>处理和<b class='flag-5'>查询</b><b class='flag-5'>优化</b>

    数据库索引使用策略及优化

    的内容完全基于上文的理论基础,实际上一旦理解了索引背后的机制,那么选择高性能的策略就变成了纯粹的推理,并且可以理解这些策略背后的逻辑。 示例数据库 为了讨论索引策略,需要一个数据量不算小的数据
    的头像 发表于 11-02 15:13 2226次阅读
    <b class='flag-5'>数据库</b>索引使用策略及<b class='flag-5'>优化</b>

    数据库插入查询删除操作教程

    数据库插入查询删除操作教程
    发表于 12-07 09:57 2次下载

    数据库优化最有效的方式是什么?

    随着业务数据量和网站QPS日益增高,对数据库压力也越来越大,单机版数据库很快会到达存储和并发瓶颈,就需要做数据库性能方面的
    的头像 发表于 02-28 09:46 1141次阅读

    python读取数据库数据 python查询数据库 python数据库连接

    python读取数据库数据 python查询数据库 python数据库连接 Python是一门高级编程语言,广泛应用于各种领域。其中,Pyt
    的头像 发表于 08-28 17:09 2586次阅读

    数据库查询分析与SQL优化实战技巧

    今天,我将分享我在处理数千次数据库性能问题中积累的实战经验,帮助你系统掌握慢查询分析与SQL优化的核心技巧。无论你是刚入门的运维新手,还是有
    的头像 发表于 09-08 09:34 619次阅读