突破数据存储瓶颈!转转业财系统亿级数据存储优化实践–图文解析
原文链接:https://juejin.cn/post/7358704806779437097
原文作者:转转技术团队
业财系统:业务和财务一体化系统
与传统财务记账不同,一笔金额不再是写到记账簿上的一成不变的数字,而是在信息系统中随着业务变化不断发生变化的字段。业财系统除了定期生成财务数据,财务报表之外,还会根据不断变化的财务数据生成决策信息。
系统遇到的两大问题:
1.数据量太大了,三年累计了大量数据,原有的数据库快承受不住了。(换数据库,由原来的mysql换成了tidb)
2.慢查询严重影响了系统性能,也拖慢了运行在同一台服务器上的其他系统。(使用es)
一,数据库选型方案
1.分库分表
无法采纳,原因
1:扩展困难,分片规则通常都是一次性定义好的,当前的业财系统承接的上游数据以后有很大的概率会增加新的业务,又要有新的数据出现。
2:业务来自上游不同的系统,不同系统都有自己的业务主键,业务主键无法统一,没有统一的业务主键作为分片键,查询时需要到每一个分片表中寻找数据,严重降低了查询效率。
3:跨库事务(要改代码)
比如说这种代码:
INSERT INTO table_name (column1, column2, column3)
VALUES (value1, value2, value3), (value4, value5, value6), (value7, value8, value9);
如果是单库单表,这种一次添加多条的sql是有利于优化性能的,因为可以减少和数据库反复连接的次数。但如果涉及到分库分表,一次插入多条数据意味着要针对多个数据库,多个表,这样显然是要使用到跨库事务的,需要对源程序进行修改,对原来本不需要添加事务的业务代码添加跨库事务。影响系统的稳定性。
- 分库分表的适用场景
- 数据库面临高并发访问的压力,又需要面对海量数据的存储问题,这时需要对数据库既采用分表策略,又采用分库策略,以便同时扩展系统的并发处理能力,以及提升单表的查询性能。
- 数据有统一的业务规则主键,使数据可以均匀分布。
Java开发分库分表的技术推荐:
单体项目:sharding-jdbc
微服务项目(必须是真的连同开发团队一起拆分的微服务项目):sharding-proxy
可参考视频:基于若依vue plus的分库分表:
https://www.bilibili.com/video/BV1Gh41137rv
https://www.bilibili.com/video/BV1MN411N7ru
https://www.bilibili.com/video/BV1XN411A7Tv
2.冷热库
热库:正在使用的数据库,高访问量,性能强
冷库:历史库,性能一般,存储量大,访问量低
如上图:热库定期将里面的1000万行用户几乎不会请求的数据迁徙到冷库,热库数据量减少,加快了查询速度,同时保存了历史数据。
本文项目中无法采纳的原因:
- 业财系统业务数据复杂,现阶段还会更改和查询历史数据,时间口径不统一,边界比较模糊,无法确认一个准确的边界。
- 考虑后续接入更多的业务数据,由于目前无法统一数据格式,那么可能就需要重新考虑边界等问题。
什么是边界:
举例:商品下单–付款–发货–收货–评价(自动好评),商品评价后,用户几乎不会再关注该商品的订单信息了,可以在评价后将数据库中的该条信息归档到性能稍差但数据存储量极大的“冷库”中。 冷库中的数据也能查,但速读要慢很多,这也是为什么我们过去搜索历史订单总是慢的原因。由于现在都是用了新一代的数据库,所以现在搜索历史订单的速度依然很快。
上面的例子中,商品已评价即为边界。
- 适用场景
- 数据库中存在大量的历史数据,且查询频率比较低。
- 数据库的写入操作比读取操作更频繁。
- 数据库的存储成本较高,需要降低成本,把冷数据放到不值钱的存储介质中。
TiDB
新一代的NewSql数据库
SQL(Structured Query Language):数据库,指关系型数据库。主要代表:SQL Server、Oracle、MySQL、PostgreSQL。
NoSQL(Not Only SQL):泛指非关系型数据库,典型为KV存储。主要代表:MongoDB、Redis、CouchDB。
**NewSQL:**对各种新的可扩展/高性能数据库的简称。主要代表: Google Spanner,PingCAP TiDB, 阿里 oceanBase。
NewSQL可以简单理解为 分布式的关系型数据库
百度百科:
NewSQL 是对各种新的可扩展/高性能数据库的简称,包含OLTP,有些也包含OLAP,这类数据库不仅具有NoSQL对海量数据的存储管理能力,还保持了传统数据库支持ACID和SQL等特性。
名词解析:
OLTP:OnLine Transaction Processing,联机事务处理系统,可以简单理解为对数据的增删改查等操作,数据量相对较少。常见:MySql,Oracle等
OLAP:OnLine Analytical Processing,联机分析处理系统,面向决策分析人员,针对存储的历史数据进行分析统计,常见的比如BI平台,数据可视化系统,风控平台等。常见:ClickHouse,Hive等
ACID:
在数据库系统中,一个事务是指:由一系列数据库操作组成的一个完整的逻辑过程。例如银行转帐,从原账户扣除金额,以及向目标账户添加金额,这两个数据库操作的总和,构成一个完整的逻辑过程,不可拆分。这个过程被称为一个事务,具有ACID特性。
- Atomicity(原子性):一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被恢复(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
- Consistency(一致性):在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。
- Isolation(隔离性):数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。
- Durability(持久性):事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
TiDB
- 纯分布式架构,拥有良好的扩展性,支持弹性的扩缩容,尤其支持高写入场景
- 支持 SQL,对外暴露 MySQL 的网络协议,并兼容大多数 MySQL 的语法,在大多数场景下可以直接替换 MySQL
- 默认支持高可用,在少数副本失效的情况下,数据库本身能够自动进行数据修复和故障转移,对业务透明
- 支持 ACID 事务,对于一些有强一致需求的场景友好,例如:银行转账
- 具有丰富的工具链生态,覆盖数据迁移、同步、备份等多种场景
- 不支持MySql存储过程,具体其他不支持的地方请查询官网
为什么TiDB支持高写入场景呢?因为其使用了不同于mysql的B+树的LSM树。
MySQL的B+树:
优点,查询速度快:保证了顺序查询,即便使用SSD硬盘,传统查询速度也要比顺序查询速度差的多。
缺点:插入数据慢,尤其是高写入插入的大量随机值,因为mysql需要维护B+树的平衡,所以每次插入值都需要规划B+树的结构。
原文链接:https://blog.csdn.net/weixin_43883685/article/details/109693823
下图高清地址:https://www.processon.com/view/link/5f48818e1e0853452d3fa33c
LSM-TREE
LSM树对写入过程做了优化,将大量数据先存放在内存中排序后再写入硬盘,每隔一段时间合并一次数据,有序的批量插入,大大提高了插入效率
数据写入时,并不会马上落入硬盘中,而是先存放在内存中,并对不断写入的数据进行排序,通常将其实现为平衡二叉树
当内存中的数据行程一定规模后,将内存中的Memtable写入硬盘,作为一颗独立的小树存在,不可修改
定期对硬盘中的SSTable进行合并
PD:
整个集群的管理中心,负责储存元数据,负责负载均衡以及分配全局唯一事务ID.(默认三个节点,高可用)
TiDB:
对外暴露MySql协议,接收并优化SQL请求,通过PD中存储的元数据找到对应TiKV中实际存放数据的TiKV节点并取得数据返回给用户
TiKV:
真正存储数据的地方,数据以NoSql数据库的KV形式存储。(TiKV Server默认三个节点,高可用)
Spark:
提供OLAP服务,接收Spark SQL,通过PD中存储的元数据找到对应TiKV中实际存放数据的TiKV节点并取得数据进行分析
TiDB部署方式:
https://cloud.tencent.com/developer/article/2363104
OceanBase
同样属于NewSql数据库
兼容常用MySQL/ORACLE功能及MySQL/ORACLE前后台协议,业务零修改或少量修改即可从MySQL/ORACLE迁移至OceanBase。
根据官方文档介绍支持MySql存储过程。
未采纳原因:要花钱,要花好多钱!
虽然有免费的社区版,但安装环境收费,文档不完整,开源社区活跃度不如TiDB
二 慢SQL的解决方案
使用ES
建立索引模型之后,我们需要考虑数据库(DB)与Elasticsearch(ES)之间增量数据的同步方式。
数据同步到ES中的几种方式
同步双写
数据写入到MySQL的时候,同时将数据写入到ES,需要改代码
异步双写
数据写入到MySQL的时候,通过MQ异步将数据写入到ES,需要改代码
定期同步
通过定时器,每隔一段时间同步一次数据,无法实现到秒级,MySQL中的数据无法和ES实时同步。
数据订阅
读取mysql的binlog日志信息转为MQ,通过MQ消费程序不断消费MQ,每消费完一条消息,将消息写入到ES中;
不用改代码,没有感知;性能高;业务解耦,不需要关注原来系统的业务逻辑。
QL的时候,同时将数据写入到ES,需要改代码
异步双写
数据写入到MySQL的时候,通过MQ异步将数据写入到ES,需要改代码
定期同步
通过定时器,每隔一段时间同步一次数据,无法实现到秒级,MySQL中的数据无法和ES实时同步。
数据订阅
读取mysql的binlog日志信息转为MQ,通过MQ消费程序不断消费MQ,每消费完一条消息,将消息写入到ES中;
不用改代码,没有感知;性能高;业务解耦,不需要关注原来系统的业务逻辑。