MySQL 亿级数据的迁移、清洗、与审计分析
职业生涯中,曾经有两年多时间从事IT内部审计的工作,需要介入公司大部分的业务系统,主要的数据库为 MySQL,特别是三年期审计,需要统计三年的数据素材(亿级以上)。对MySQL的性能有一些自已的理解,
一般对外的高负载的系统为了提升性能,极力规避MySQL直接面对用户,在用户和MySQL之间,有一层又一层的缓存,如果流量大量打到了MySQL上,我们称为缓存穿透,系统很容易就挂掉了,即使在缓存保护下的应用,也会极力限制复杂的 SQL查询,鲜少有 JOIN, GEOUP BY,而在内部系统中,因为用户规模可控。MySQL的各种极致用法都可能出现,我们计论MySQL性能,一般就是内部系统这种场景下。
IT 审计需要跟公司内部大部分的系统打交道,公司有上百个系统,很多是遗留系统,各种各样的架构设计,程序员在这个领域是超级个性化的,同一个系统功能,换一个人,就可能是完全不同的设计,某个系统中可能无差别全是分区表;另一个系统中单表无分区竞有两亿多多条数据,且运行稳定 ......
我对 MySQL数据量极限的理解
很多人认为 MySQL适合千万级以下的数据,或者其它量级,他们的结论大致是正确的,因为是他们的应用场景各不相同。
我将MySQL数据量极限划分为以下情况:
A 不分区
不分区时,性能主要影响因素就是:索引,MySQL表至少有一个主键索引,即使你没建,MySQL也会隐藏的创建一个自增ID
A 01 只有一个主键索引(亿级以上完全没有问题)
写入数据时数据量对写入性能影响比较小。仅当主键这个索引需要做二叉树平衡时,产生额外IO操作,大部分情况下,和空表插入性能无异。
超级大表读取数据时,只能用两种方式,1. 按主键读取,2 不排序或按主键排序 取前多少个。 其它方式不要想了(抓狂:几个小时无返回,show processlist 一直有这个进程,只能 kill 掉),
A 02 多个索引(极限数据量几千万)。
写入数据时,索引越多,索引需要平衡二叉树产生重建操作机率越大。性能下降越厉害,索引个数,类型,长度,行数据大小等影响很大,这个极限没有确定的值。在一个业务系统中,某个核心业务表,100多个字段,近 30 个索引,1000 万+数据,还能硬撑,不过MySQL服务器内存被迫一步步升到了 256G
读取数据时,只有一条路,一定要走索引,尽可能走唯一索引,尽可要走更精准的索引(基数更大的),LIKE 也可以用(但是一定是索引字段, 而且是 LIKE ’***%‘,不能是 %开头的),联合索引只用到了部分字段也可,但必须是按顺序最前的(如 A+B+C三个字段的联合索引,WHERE可以只有A字段,或 A AND B 字段,或三个都有),GROUP BY 也可以用,稍慢点,但一定是 GROUP BY 索引, WHERE条件要走索引,在千万级的 业务系统中,发现有GROUP BY 嵌套 (GROUP BY 的结果作为临时表再次GROUP BY ),效率也可接受。
B 分区表
分区表将数据分成区块存储,可存储到不同磁盘。最多 1024 个分区。和分表性能相当。每个分区可以认为和不分区单表的限制基本一致,如果单表稳定处理1000万复杂的业务数据,那1024个分区理论极限可以稳定处理 100 亿条数据
但分区表最大缺点:操作必须限定在一个分区内,即 WHERE 查询条件中 一定要包含分区字段,这极大地限制了分区表的应用,如果你不小心漏掉了,呵呵,去 KILL 进程吧。
数据迁移:
做IT审计,首先面临的问题是将数据定期从业务系统复制到内审系统中。主要因为:
- 业务系统有分区或分表,历史数据也可能封存到别处。
- 系统隔离,审计操作不影响业务系统,
- 数据需要清洗,加工,拆分或聚合。
早期尝试了 现成 ETL工具 的方案,主要是 kattle,效率还可以(每秒能处理上万条),主要障碍在数据清洗操作。比如订单中有 A+B 这样的组合商品,(我们称 A+B 为商品编码,其中 A, B 为 SKU,商品编码格式没有限制,在基础资料系统中和SKU关联起来即可),表示 两个东西捆绑销售。比如手持风扇加个18650电池。清洗逻辑很多,比如有 将商品编码打散成 SKU, 调用基础资料服务获取商品编码与SKU关系, 调用成本服务获取各SKU成本价,按成本价比例分摊售价。katttle 不擅长做这种复杂操作,实现起来很麻烦,且无法自动化部署,无版本控制。不易测试,最终决定自已开发迁移程序。
清洗后入库时对数据插入及更新的 SQL 处理:
1 SQL预编译后再批量执行
首先 编写占位符的 SQL
INSERT INTO table(a, b, c ... ) VALUE(?, ?, ? , )
预编译后批量注入清洗过数据,不同语言和服务器配置有些差距,但都能很轻松实现 1万条以上/秒的速度,包含清洗逻辑(清洗逻辑经过了极度优化,无处不缓存,耗时影响比较小)。
2 拼接SQL批量执行
INSERT INTO table(a, b, c ... ) VALIES
('1,' '2', '3' , ),
('1,' '2', '3' , ),
('1,' '2', '3' , ),
......
VALUES 后边大量数据,我们一般用 5000 行数据拼成一个 SQL,注意数据需要主动做 escape 处理。这样的SQL一秒钟能执行5~6 条或更多,跟字段量多少有关,相当于一秒处理 3 万条以上的数据,1分钟处理 200 万,5分钟处理 1000 万,
但这并不是极限,我们发现 瓶颈 不在 MySQL身上,而是 网络带宽和磁盘的 IO写入速度首先达到了峰值。一旦我们的程序长时间启动,用不了多久,运维部门的同事就来关照我们了,以至于我们不得不限制下执行时段或速度。
不确定是插入还是更新情况的处理
REPLACE INTO table(a, b, c ... ) VALIES
('1,' '2', '3' , ),
('1,' '2', '3' , ),
('1,' '2', '3' , ),
......
MySQL 提供了独有的 REPLACE INTO, 和 INSERT INTO 语法一致,数据存在时更新,不存在时插入,和 ON DUMPLICATE KEY UPDATE 功能类似,但更方便。REPLACE INTO 操作的表一定要有有唯一键,如果没有,就是单纯的 INSERT INTO 了.
更新也可以几千条批量处理
UPDATE table SET a = CASE WHEN id=1 THEN 'A1' WHEN id=2 THEN 'A2' WHEN id=3 THEN 'A3' .....
END
批量更新相比 批量 INSERT INTO 和 REPLACE INTO 差很多,但也比单条更新快很多倍
至此,各业务系统的数据经过清洗,完整部署在了内审系统中,年度数据5000万行左右,三年 1.5亿, 因为清洗过的数据更有价值,这些数据被多方引用,如 Tableau 报表,财务部门,同时也有同步到 ES 和 ClickHouse 中做不同用途的运算。
数据应用:
外部审计公司进场后,会要求我们提供某些数据,各种维度的, 如:提供一年期前10销量国家的复购次数最多的前 100个用户的订单数据。这些需求都是一次性的,在指定时间段内提供即可,大部分需求直接编写SQL即可实现。编写出来的 SQL 一般都包含两层或三层 GROUP BY 嵌套, 或者几个 GROUP BY 进行 UNION ALL 后再次 GROUP BY。
为了提升效率,我们的数据冗余了两张表,一张不分区,一张按月份分区,数据完全一致,
- 如果需求是月度数据(查询量几百万条),优先使用分区表,基本是秒级的查询。
- 如果需求是几个月的数数(查询量几千万条条),优先使用分区表,几个月的的分段成单月 SQL 再 UNION ALL 后再聚合,基本是两三秒的时间。
- 如果更长维度的话,没办法使用分区表,在总表下查询,要一分钟以上,某些复杂的查询可能出不来,这时候要去 ClickHouse 了( DBeaver 客户端)。又找到了秒级的感觉。
ClickHouse 几乎完全兼容 SQL 语句,只有部分 SQL 函数(如日期)需要特殊处理下,效率相当给力。没有以 ClickHouse 为中心是因为 MySQL 是基础应用,所有系统都是围续 MySQL 构建的,而 ClickHouse 主要适用于数据分析的场景,适合整表写入,数据更新效率很低,因此它的数据更新频率很低,不论数据量有多少,它的更新就是删表,然后整表导入,反而出奇的快。
本文原始网址:MySQL亿级数据的处理及应对方案,转载请保留出处
MySQL 亿级数据的迁移、清洗、与审计分析相关推荐
- MySQL 亿级数据导入导出/数据迁移笔记
最近MySQL的笔记有点多了,主要是公司Oracle比较稳定维护较少,上周被安排做了一个MySQL亿级数据的迁移,趁此记录下学习笔记: 数据迁移,工作原理和技术支持数据导出.BI报表之类的相似,差异较 ...
- MySQL亿级数据数据库优化方案测试-银行交易流水记录的查询
对MySQL的性能和亿级数据的处理方法思考,以及分库分表到底该如何做,在什么场景比较合适? 比如银行交易流水记录的查询 限盐少许,上实际实验过程,以下是在实验的过程中做一些操作,以及踩过的一些坑,我觉 ...
- MySQL 亿级数据需求的优化思路(二),100亿数据,1万字段属性的秒级检索
最近在研究亿级数据的时候,无意中看到了一个关于写58同城的文章 https://blog.csdn.net/admin1973/article/details/55251499?from=timeli ...
- MySQL 亿级数据需求的优化思路(一),交易流水记录的查询
对MySQL的性能和亿级数据的处理方法思考,以及分库分表到底该如何做,在什么场景比较合适? 比如银行交易流水记录的查询 限盐少许,上实际实验过程,以下是在实验的过程中做一些操作,以及踩过的一些坑,我觉 ...
- MySQL亿级数据量实时同步,小米如何完美hold住
点击上方"朱小厮的博客",选择"设为星标" 后台回复"1024"获取公众号专属1024GB资料 作者丨刘心光 来源丨小米云技术(ID:mi- ...
- 一次深夜优化,MySQL亿级数据分页的奇妙经历
下班后,愉快的坐在在回家的地铁上,心里想着周末的生活怎么安排. 突然电话响了起来,一看是我们的一个开发同学,顿时紧张了起来,本周的版本已经发布过了,这时候打电话一般来说是线上出问题了. 果然,沟通的情 ...
- 一次深夜优化MySQL亿级数据分页的奇妙经历
作者:翁智华 cnblogs.com/wzh2010/p/14316920.html 背景 1月22号晚上10点半,下班后愉快的坐在在回家的地铁上,心里想着周末的生活怎么安排. 突然电话响了起来,一看 ...
- MySQL亿级数据分页的奇妙经历
作者:翁智华 cnblogs.com/wzh2010/p/14316920.html 背景 4月28号晚上10点半,下班后愉快的坐在在回家的地铁上,心里想着周末的生活怎么安排. 突然电话响了起来,一看 ...
- mysql如何备份一个表单_Mysql亿级数据大表单表备份
上一篇Mysql已有亿级数据大表按时间分区,介绍了亿级数据大表如何按时间分区,也留下了一个问题:备份亿级数据大表要耗时多久.本篇将就如何备份亿级数据大表展开讨论. 注意:我这里所说的备份指的是数据从一 ...
最新文章
- ubuntu for nvidia-drivers for AI
- 12层打败50层,ParNet 普林斯顿+英特尔:更深不一定更好
- 怎么卸载Apache_pn服务-PHPnow使用问题
- CML 2020 | 显式引入对分类标签的描述,如何提高文本分类的效果?
- 论文阅读——《Robust Superpixel Tracking》
- linux 内核驱动的poll,Linux驱动基石之POLL机制
- 登录表单 参考新浪微博
- python编程第四版_清华编程教授强力推荐《Python编程》,指导你如何学习python
- perl大骆驼和小骆驼_从代码内部:骆驼路由引擎第一部分
- java swt最小化到托盘_SWT 中实现最小化到托盘图标,并只能通过托盘的弹出菜单关闭程序...
- js iframe 出现跨越问题
- Oracle分页小谈
- 释放数据价值:DAYU数据运营新能力解读
- npm + webpack +react
- Pythonz中模块内的__name__用法示例
- Hibernate下载和安装
- 坯子库怎么导入插件_坯子库实用的插件安装器-SketchUp坯子插件库2020下载v2020.1正式版管理器-西西软件下载...
- stm8s单片机2位数码管显示_AT89S52单片机,实现功能两位数码管显示数字,按下
- 竟然可以用Python操作 Word 文档,这么多的骚操作!
- minigui[基础篇][11]—— 图标