突破数据存储瓶颈!转转业财系统亿级数据存储优化实践

news2024/10/5 18:31:43

1.背景

1.1 现状

目前转转业财系统接收了上游各个业务系统(例如:订单、oms、支付、售后等系统)的数据,并将其转换为财务数据,最终输出财务相关报表和指标数据,帮助公司有效地进行财务管理和决策。

转转业财系统于2021年开始构建,前期为了满足需求短时间内上线,选择了主动接收上游业务系统的数据。然而随着时间的推移,数据量在不断增长,系统已经达到无法承载的边缘,引发了许多问题。因此,我们需要对数据存储进行优化。

1.2 数据量统计

业财系统数据量较大表统计:

表名行数数据长度索引长度
出库明细表10628017629.48GB34GB
出库单头表253441107GB6GB
入库明细表227669108GB5GB
销售订单表2957865910GB9GB
应收单表246862675GB2GB
入库单表207774574GB6GB
应付单表153877244GB2GB

以下是数据量较大的表数据增量趋势图,可以观察到近几个月由于新业务的增加,每月的数据增量已经达到一千万。

1.3 慢查询情况

从慢查询监控平台可以看到,每天慢查询个数已经到达千量级别。慢查询不仅影响用户体验,还会大量消耗所在机器资源,严重可能导致机器宕机。另外,转转MySQL数据库架构属于单机多实例,一台物理机上部署多套集群的实例,所以不仅会影响系统本身集群,还会拖累其他集群,引发雪球效应。

2.设计目标

2.1 解决数据量问题

在未来五年,不用考虑数据库数据量问题,能够轻松应对未来的业务增长和覆盖公司全量业务,且具备良好的扩展性,最终可以稳定向外输出更多数据报表等。

2.2 解决读写性能

通过此次优化,提升报表查询效率,减少定时任务执行时间,避免因为慢查询导致任务失败和接口超时问题,提高服务稳定性。

3.方案选择

3.1 db存储方案选型

为解决底层表数据量问题,我们对比了以下四个方案:

  • 方案一:分库分表
  • 优点
  1. 将数据分散到多个数据库和表中,从而减轻单一数据库的负载压力。这样可以提高数据库的读写性能和响应速度,降低查询延迟。
  2. 拆分的表结构相同,程序改造较少。
  • 缺点
  1. 需要提前规划好分片规则,一旦定好规则就难以移动,扩展性比较差。
  2. 拆分规则很难抽象出来。
  3. 跨库事务问题。
  • 适用场景
  1. 数据库面临高并发访问的压力,又需要面对海量数据的存储问题,这时需要对数据库既采用分表策略,又采用分库策略,以便同时扩展系统的并发处理能力,以及提升单表的查询性能。
  2. 数据有统一的业务规则主键,使数据可以均匀分布。
  • 业财系统适用分析
  1. 业财系统作为底层系统,接受了各个业务系统的数据,数据比较多样性和复杂性,很难定义出一个业务主键,数据分布均匀困难。
  2. 若某业务数据量迅速增长或接入其他业务数据,那么可能又会面对数据量问题。
  • 方案二:冷热库
  • 优点
  1. 将不常访问的数据从在线存储中移动到归档存储中,减少了在线存储的容量需求,从而降低了存储成本。
  2. 减少了在线存储中数据的数量,因此可以提高数据库读写性能。
  3. 可以将历史数据长期保存,避免了数据的丢失。
  4. 可以将数据备份到不同的存储位置,以便在需要时进行数据恢复。
  • 缺点
  1. 需要保证归档事务性,防止归档数据同时出现在冷热库,出现数据重复。
  2. 需要考虑合适的归档策略,不影响服务访问。
  3. 需要有明确的业务边界,业务复杂的数据不适用。
  • 适用场景
  1. 数据库中存在大量的历史数据,且查询频率比较低。
  2. 数据库的写入操作比读取操作更频繁。
  3. 数据库的存储成本较高,需要降低成本。
  • 业财系统适用分析
  1. 业财系统业务数据复杂,现阶段还会更改和查询历史数据,时间口径不统一,边界比较模糊,无法确认一个准确的边界。
  2. 考虑后续接入更多的业务数据,由于目前无法统一数据格式,那么可能就需要重新考虑边界等问题。
  • 方案三:TiDB
  • 优点
  1. 高度兼容 MySQL:大多数情况下,无需修改代码即可从MySQL轻松迁移至TiDB。
  2. 水平弹性扩展:通过简单地增加新节点即可实现 TiDB 的水平扩展,按需扩展吞吐或存储,轻松应对高并发、海量数据场景。
  • 缺点
  1. 仍有一些MySQL的特性和行为,TiDB目前暂时不支持或表现与MySQL有差异。
  2. 系统复杂,组件太多。
  • 适用场景
  1. 对数据一致性及高可靠、系统高可用、可扩展性、容灾要求较高的金融行业属性的场景。
  2. 对存储容量、可扩展性、并发要求较高的大量数据及高并发的OLTP场景。
  3. 数据汇聚、二次加工处理的场景。
  • 业财系统适用分析
  1. 由于TiDB兼容了MySQL,所以改动点也较少。
  2. 近几年是不用考虑数据量问题,可以接入更多样化数据。
  3. TiDB能够支持大表经常有加列减列的需求,可扩展性高,目前也比较符合业财现状。
  • 方案四:OceanBase
  • 优点
  1. 高性能:采用了读写分离的架构,把数据分为基线数据和增量数据。其中增量数据放在内存里(MemTable),基线数据放在SSD盘(SSTable)。对数据的修改都是增量数据,只写内存。所以DML是完全的内存操作,性能非常高。
  2. 高兼容:兼容常用MySQL/ORACLE功能及MySQL/ORACLE前后台协议,业务零修改或少量修改即可从MySQL/ORACLE迁移至OceanBase。
  3. 高可用:数据采用多副本存储,少数副本故障不影响数据可用性。
  • 缺点
  1. 对环境要求极高,需要采购使用其指定的服务器。
  2. 学习和运维成本比较高。
  3. 尽管OceanBase具有高可用性的特性,但其实现仍然依赖于底层硬件和网络的稳定性。
  • 适用场景
  1. 金融级数据可靠性需求。金融环境下通常对数据可靠性有更高的要求,OceanBase 每一次事务提交,对应日志总是会在多个数据中心实时同步,并持久化。
  2. 数据库面对飞速增长的业务数据量。
  • 业财系统适用分析
  1. 目前运维没有维护,所以就不考虑此方案,大家可以参考此方案是否适用于本身系统。

综合以上各个方案的分析,目前最适用于转转业财系统的方案是TiDB。该方案能够在短时间内解决数据量问题,并且改动成本相对较低。

3.2 慢查询优化方案

在分析了慢查询语句以后,发现大部分慢查询都是由于联表查询导致的,所以此次主要解决联表问题。
联表解决方案对比如下,根据适用分析选择ES方案。

方案业财适用分析
宽表1.宽表可能包含大量重复数据,导致存储空间的浪费。这会增加数据库的存储需求,尤其在大规模数据集上会更为显著
2.由于涉及到大量列和关联数据,后续性能优化可能需要考虑更多的因素,而且可能需要采用复杂的索引策略
3.复杂度增加,改动量比较大
ES1.通过建立索引方式解决联表问题,也一并提高了查询效率
2.后续可扩展性比较高,增加查询条件等,都易实现
3.需要保持数据源与ES数据一致问题
4.可以减低现有的数据库索引数据量

4.方案实践

4.1 方案实践步骤

根据方案选择分析,最适合业财系统当前状况的方案是首先切换底层数据存储,然后再接入ES。在实施这两个方案之前,我们需要考虑它们的先后顺序,并分析业财系统的现状。
由于数据量的突增,考虑到现有业务和后续新增业务,同时在不影响现有使用的前提下,首要需要解决的问题是数据量。因此,我们建议首先切换底层数据存储。这样做的好处是,即使在后续的实施中遇到问题,我们仍然可以回滚到原有的数据存储。这样既可以保证数据的完整性,也减少了实施过程中的风险。另一方面,如果我们选择先接入ES,就需要考虑如何保证数据切换过程中的数据完整性,并且同步方式也需要考虑两种不同数据存储方案之间的兼容性,这将增加许多额外的工作量和风险。

综上所述,我们选择的优化步骤是首先切换底层数据存储,待其稳定后再接入ES。这样能够有效解决当前的数据量问题,同时保证系统的稳定性和数据完整性。随后,我们可以继续进行ES的接入,以进一步优化业财系统的性能。

4.2 切换底层数据存储步骤

在选择数据迁移方式时,考虑到业财系统对实时性要求并不是很高,且评估了下目前大部分数据接入写入方式,是可以接受停写几分钟,这样便大大降低了整个数据迁移成本。

迁移过程要求:

  1. 检查TiDB是否都能兼容目前服务中的SQL语句,保证迁移之后系统不会报错。
  2. 数据需要保证完整性,迁移之后需要保证MySQL库和TiDB库的数据是严格一致。
  3. 迁移过程中需要做到可以回滚,一旦迁移过程中出现问题,可以立即回滚到MySQL库,不会对系统可用性造成影响。

4.3 接入ES

  1. 根据报表查询页面的功能和联表SQL分析,我们进行了索引模型设计,核心是优化查询性能和提高系统的响应速度。
  2. 在建立索引模型之后,我们需要考虑数据库(DB)与Elasticsearch(ES)之间增量数据的同步方式。

以下表格是对比了四种不同的同步方式,我们根据已设计的索引分析,考虑到每个索引涉及的表较多、相关业务代码尚未收口以及对实时性较高的需求,我们决定采用数据订阅的方式进行同步。在当前公司提供的实现方式中,我们选择了Kafka。

同步方式优点缺点
同步双写这种方式简单粗暴,实时性高1.业务耦合:这种方式代码侵入性强,耦合大量数据同步代码,要在写DB的地方写ES的代码
2. 影响性能:写入两个存储,响应时间变长,系统的性能必然会下降
3.不便扩展:搜索可能有一些个性化需求,需要对数据进行聚合,这种方式不便实现
4.高风险:存在双写失败丢数据风险
异步双写1.性能高
2.不易出现数据丢失问题
3.多源写入之间相互隔离,便于扩展更多的数据源写入
1.硬编码问题,接入新的数据源需要实现新的消费者代码
2.系统复杂度增加,引入了消息中间件
3.MQ是异步消费模型,用户写入的数据不一定可以马上看到,造成延时
定期同步实现比较简单1.实时性难以保证
2.对存储压力较大
数据订阅1.业务入侵较少
2.实时性比较高
需要选型数据订阅框架,系统复杂度增加
  1. 在增量数据同步以后,最后一步就是需要完成历史数据的同步,此次我们选择的同步方式是公司内部提供的ECP,可以参考文章:
    不可思议!亿级数据竟然如此轻松同步至ES!

5.总结与成果

目前,业财系统已成功完成底层数据存储的切换,可以看到近几年来不再担心数据量存储的问题,并且成功接入了更多的业务数据。随着引入了Elasticsearch(ES),业务人员也不再反馈报表页面超时等问题。这次针对数据存储的优化实质上是对系统的重构,选择方案时考虑了对系统影响范围较小且不影响业务人员使用的因素,这也是优化的核心所在。

由于历史原因,业财系统仍存在许多需要优化的方面,如慢SQL的持续治理、定时任务优化等。因此,我们需要保持此优化的核心理念,并在后续的重构中继续完善,以使业财系统更加稳定。


关于作者

戴美琪,转转交易中台研发工程师

转转研发中心及业界小伙伴们的技术学习交流平台,定期分享一线的实战经验及业界前沿的技术话题。

关注公众号「转转技术」(综合性)、「大转转FE」(专注于FE)、「转转QA」(专注于QA),更多干货实践,欢迎交流分享~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1602662.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Matlab|基于改进遗传算法的配电网故障定位

目录 1 主要内容 2 部分代码 3 部分程序结果 4 下载链接 1 主要内容 该程序复现文章《基于改进遗传算法的配电网故障定位》,将改进的遗传算法应用于配电网故障定位中, 并引入分级处理思想, 利用配电网呈辐射状的特点, 首先把整个配电网划分为主干支路和若干独立…

Pr2024安装包(亲测可用)

目录 一、软件简介 二、软件下载 一、软件简介 Premiere简称“Pr”,是一款超强大的视频编辑软件,它可以提升您的创作能力和创作自由度,它是易学、高效、精确的视频剪辑软件,提供了采集、剪辑、调色、美化音频、字幕添加、输出、D…

minio如何配置防盗链

MinIO 是一个开源的对象存储服务器,用于存储大量的数据,同时提供了丰富的功能和 API。配置防盗链可以帮助你控制谁可以访问存储在 MinIO 上的对象。以下是在 MinIO 中配置防盗链的一般步骤: 编辑 config.json 文件: 找到 MinIO 服…

【Godot4自学手册】第三十七节钥匙控制开门

有些日子没有更新了,实在是琐事缠身啊,今天继续开始自学Godot4,继续完善地宫相关功能,在地宫中安装第二道门,只有主人公拿到钥匙才能开启这扇门,所以我们在合适位置放置一个宝箱,主人公开启宝箱…

vue+element作用域插槽

作用域插槽的样式由父组件决定&#xff0c;内容却由子组件控制。 在el-table使用作用域插槽 <el-table><el-table-column slot-scope" { row, column, $index }"></el-table-column> </el-table>在el-tree使用作用域插槽 <el-tree>…

【Java开发指南 | 第十一篇】Java运算符

读者可订阅专栏&#xff1a;Java开发指南 |【CSDN秋说】 文章目录 算术运算符关系运算符位运算符逻辑运算符赋值运算符条件运算符&#xff08;?:&#xff09;instanceof 运算符Java运算符优先级 Java运算符包括&#xff1a;算术运算符、关系运算符、位运算符、逻辑运算符、赋值…

C语言入门案例-学生管理系统

要求&#xff1a;学员管理系统可以实现对学员的添加、全部显示、查询、修改、删除功能 完整代码示例&#xff1a; #include <stdio.h> // 定义容量 #define NUM 100//自定义结构体 typedef struct st {char name[30];int age;char sex[10]; }STU;//传入四个初始数据 STU…

PyTorch深度学习入门-2

PyTorch深度学习快速入门教程&#xff08;绝对通俗易懂&#xff01;&#xff09;【小土堆】_哔哩哔哩_bilibili 一、神经网络的基本骨架 --nn.Module Neutral network torch.nn — PyTorch 2.2 documentation * import torch from torch import nnclass xiaofan(nn.Module):…

1997-2022年各省技术市场发展水平数据(原始数据+计算过程+计算结果)

1997-2022年各省技术市场发展水平数据&#xff08;原始数据计算过程计算结果&#xff09; 1、时间&#xff1a;2000-2022年 2、来源&#xff1a;国家统计局、统计年鉴 3、范围&#xff1a;30省 4、指标&#xff1a;技术市场成交额、国内生产总值、技术市场发展水平 5、计算…

Git回滚版本并push到远端master

1、查看日志 git log 2、还原最近的版本 () --git reset --hard commit-id 如&#xff1a;git reset --hard d84da14bf2743683eca7a015f56114faaa344f42 3、覆盖分支版本 git push -f origin dev 回滚本地master完成后&#xff0c;将回滚后的代码push到远端master&#xf…

VIT论文阅读

论文地址&#xff1a;https://arxiv.org/pdf/2010.11929.pdf VIT论文阅读 摘要INTRODUCTION结论RELATEDWORKMETHOD1.VISIONTRANSFORMER(VIT)整体流程消融实验HEAD TYPE AND CLASSTOKENpoisitional embedding 整体过程公式Inductive biasHybrid Architecture 2.FINE-TUNINGANDH…

Nginx第1篇-安装和简单配置

Nginx可以做什么 可以做静态HTTP服务器做负载均衡做正向代理做反向代理 正向代理和反向代理 正向代理&#xff1a; 是一个位于客户端和目标服务器之间的服务器(代理服务器)&#xff0c;为了从目标服务器取得内容&#xff0c;客户端向代理服务器发送一个请求并指定目标&…

Scala 02——Scala OOP

文章目录 Scala 02——Scala OOP前序类1. 类的基本结构2. 普通类和数据类的区别 继承1. extends2. override 抽象类抽象类的特点 单例对象1. 定义2. 场景3. 方法3.1 方法定义3.2 方法调用 特质1. 抽象类和特质的区别2. 强制混入语法3. 静态混入和动态混入 内部类Java和Scala内部…

单链表的应用

文章目录 目录1. 单链表经典算法OJ题目1.1 [移除链表元素](https://leetcode.cn/problems/remove-linked-list-elements/description/)1.2 [链表的中间节点](https://leetcode.cn/problems/middle-of-the-linked-list/description/)1.3 [反转链表](https://leetcode.cn/problem…

【八股】Redisson分布式锁

Redisson分布式锁 主要了解了Redisson分布式锁实现的三个功能&#xff1a; 1.可重入 -> 防止死锁 2.可重试&#xff08;i.e. 非阻塞获取锁&#xff09; 3.自动续约 1. 可重入 原理&#xff1a; 利用Redis的Hash结构&#xff0c;记录了使用当前锁的线程id和重用次数&#…

C++初级----list(STL)

1、 list介绍 1.1、 list介绍 1.list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。 1. list的底层是双向链表结构&#xff0c;双向链表中每个元素存储在互不相关的独立节点中&#xff0c;在节点中通过指针指向 其前一…

git 分支-变基

在git中&#xff0c;将一个分支的更改集成到另一个分支有两种主要方式&#xff1a;合并&#xff08;merge&#xff09;和变基&#xff08;rebase&#xff09;。在本节中&#xff0c;将学习什么是变基&#xff0c;如何执行变基操作&#xff0c;为什么它是一个非常强大的工具&…

Web 题记

[极客大挑战 2019]LoveSQL 看到这种就肯定先想到万能密码&#xff0c;试试&#xff0c;得到了用户名和密码 总结了一些万能密码&#xff1a; or 11 oror admin admin-- admin or 44-- admin or 11-- admin888 "or "a""a admin or 22# a having 11# a havin…

vue2知识点1 ———— (vue指令,vue的响应式基础)

vue2的知识点&#xff0c;更多前端知识在主页&#xff0c;还有其他知识会持续更新 Vue 指令 Vue指令是Vue.js中的一个重要概念&#xff0c;用于向DOM元素添加特定行为或功能。Vue指令以v-开头&#xff0c;例如v-bind、v-if、v-for等。 v-bind 动态绑定属性 用法&#xff1a…

Linux sort/uniq/wc

文章目录 1. sort 排序将线程ID从大到小排序 2.uniq 临近去重3.wc word cnt 统计 1. sort 排序 将线程ID从大到小排序 grep -v是反向筛选&#xff0c;利用USER&#xff0c;排除掉首行 awk是打印第1 2列 sort -n是代码以数值大小做排序&#xff0c;不加的话会以字符排序。 -k是…