一文带你看懂:亿级大表垂直拆分的工程实践

news2025/7/10 3:09:20

伴随着不断扩张的业务量,在数据库层面一般会经历数据拆分。解决问题的第一步,就是重新评估DB表结构设计的合理性。我们开发者会对表结构和业务代码进行重构,在之前的文章《业务系统重构》我有提到过。

大表问题

我实际遇到的是怎么样的情况呢?下面我简单介绍下(做了脱敏处理):

过去对表结构设计时,研发由于忽略了业务原子性,使用了一个大字段(TEXT/LONGTEXT/JSON等)存储了耦合业务的大数据字段,如今表行数已经超过1亿了,总使用空间超过100G;虽然碎片率不高,但仍有1.97GB的碎片空间。

b8e5e5417af791f8db4b6a9700f08baa.png

DB大表的存在导致了诸多问题:

1、读查询:每次带大字段的SQL被执行了,都会引起从 DB-Server 到 应用服务 之间的一次大数据量传输;如果SQL执行并发量大,吃机器内存的情况,将发生在Mysql-Server和应用容器中,甚至OOM;

2、业务拓展:业务是不断往前迭代的,意味着针对这个表,将不断有DDL和DML的SQL被执行;这也注定了,如果不对大表进行瘦身,第1点提到的问题,将是一颗定时炸弹,埋在不断被堆积的业务里;

3、DB运维:在追求平滑升级的背景下,我们对表结构变更时,一般选择是在业务低峰期,对临时表进行拷贝,然后执行DDL变更(增删字段和索引),最后通过rename完成业务切换;大表的临时表将具有跟原表同样大小体积,这对运维来说,每次备份大表都是一个巨大的资源和时间开销。

4、业务隐患:为了完成DB高可用部署,我们的业务上云之后,采取了一主多从的部署架构。因此DDL变更期间,由于强同步配置,难免造成从库的数据延迟问题。

大表的垂直拆分

数据库拆分原则:就是指通过某种特定的条件,按照某个维度,将我们存放在同一个数据库中的数据分散存放到多个数据库(主机)上面以达到分散单库(主机)负载的效果。

数据库拆分,分为水平和垂直拆分两种;

- 水平拆分的典型场景就是大家熟知的分库分表;

- 垂直拆分则倾向于表重构,按照业务维度进行数据切割。

winter

上文讲了大表背景下导致的种种问题,基于上述原因,我们团队决定趁着重构的机会,进行一次大表垂直拆分:大字段迁移。

经过和DBA的一起分析,发现该表存在一个LONGTEXT的字段,它占用了几乎整个表体积空间的60%以上。

在处理这个大表的问题上,我们有考虑过水平拆分的手段。

9ea4f1209e60eff326bdb27e73078f6e.png

按照某种策略(基于项目id,基于用户id,基于冷热项目等),但始终不能较好的将数据均匀平摊到每个分表,甚至会因为热点项目再次带来大表问题,因此并不采纳这个方案。

我们最终选择垂直拆分的方案。

ca5df05ae60295aab0ceef6b9f179962.png

原因是这个大字段,本身就是一个结构化的对象数据,结构化对象最终可以抽象成一张表。通过将这个大字段拆分到一个新表,随后完成旧表的数据迁移和清理。

2002ea2efa767fa7ac367754d640991a.png

解决方案

制定了DB变更方案之后,我们要按照真实环境部署来完善方案细节。

6af6522530c61b15ca950121fe0bd69d.png

1、新表创建:这类SQL操作,我们都会提单给DBA评估执行。

2、数据迁移(存量数据):这里我们用定时任务来完成。

如果简单使用UPDATE务,会带来表锁的开销,这会直接影响线上业务;我们是不停服变更,因此绝对不能影响正常业务。

定时任务逻辑很简单:查出一条老数据,插入一条新数据。这里建议直接设定一个区间,按照主键ID来遍历;否则通过任何索引+分页的手段,最后都会面临深度分页带来的性能问题,属于是本末倒置了。

3、开启双写(增量数据):正常业务是会源源不断产生增量数据的,此时要确保数据在新旧表都有一份,这样才能完全兼容业务。

4、兼容API:数据迁移是需要切换时间的,这个缓冲期需要保持对API的兼容,包括对新表or旧表的读操作,其他依赖业务的读操作等。

5、关闭双写:数据迁移完成后,老表的字段不需要再写入数据,因此可以修改Insert的SQL,停止该字段写入。

6、清理旧表:确认线上业务不依赖旧表之后,DBA可以进行磁盘碎片回收。

往期推荐

《源码系列》

《JDK之Object 类》

《JDK之BigDecimal 类》

《JDK之String 类》

《JDK之Lambda表达式》

《Spring源码:Event事件发布与监听》

《互联网技术峰会》

《ArchSummit:从珍爱微服务框架看架构演进》

《ArchSummit_2022_全球架构峰会》

《2021年深圳ArchSummit全球架构师峰会》

《降本30%,酷家乐海量数据冷热分离设计与实践》

《经典书籍》

《Java并发编程实战:第1章 多线程安全性与风险》

《Java并发编程实战:第2章 影响线程安全性的原子性和加锁机制》

《Java并发编程实战:第3章 助于线程安全的三剑客:final & volatile & 线程封闭》

《服务端技术栈》

《Docker 核心设计理念》

《Kafka原理总结》

《HTTP的前世今生》

《如何进行一次高质量CR》

《一时重构一时爽,一直重构一直爽》

《算法系列》

《读懂排序算法(一):冒泡&直接插入&选择比较》

《读懂排序算法(二):希尔排序算法》

《读懂排序算法(三):堆排序算法》

《读懂排序算法(四):归并算法》

《读懂排序算法(五):快速排序算法》

《读懂排序算法(六):二分查找算法》

《设计模式》

《设计模式之六大设计原则》

《设计模式之创建型(1):单例模式》

《设计模式之创建型(2):工厂方法模式》

《设计模式之创建型(3):原型模式》

《设计模式之创建型(4):建造者模式》

《设计模式之创建型(5):抽象工厂设计模式》

《设计模式之结构型(1):代理类设计模式》

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

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

相关文章

CAD指令框找不到了怎么调出来?CAD指令框调出方法

CAD制图过程中,为了提高设计师的绘图效率,经常会用到各种CAD命令快捷键,可是CAD指令框突然不见了,这就让人很头疼了。CAD指令框找不到了怎么调出来呢?本节内容小编以浩辰CAD软件为例来给大家分享一下CAD指令框调出方法…

网络协议(十二):HTTPS(SSL/TLS、TLS1.2的连接)

网络协议系列文章 网络协议(一):基本概念、计算机之间的连接方式 网络协议(二):MAC地址、IP地址、子网掩码、子网和超网 网络协议(三):路由器原理及数据包传输过程 网络协议(四):网络分类、ISP、上网方式、公网私网、NAT 网络…

mysql 数据库 tinyint 类型字段取数变成 true/false 的解决方案

mysql 数据库 tinyint 类型字段取数变成 true/false 的解决方案 灌水 问题描述: 在 mysql 数据库设定上,有个字段类型是 tinyint 类型,长度为 1, 设定如下所示: 常规 sql 取数, 取到润乾报表内的时候&…

女神节告白代码

今天是女神节,送给所有女神们一句话: 爱自己是终生浪漫的开始,无论何时都要好好爱自己 目录 1. 请求动画帧填充 2.点类 3.粒子类 ​编辑 4.ParticlePool 池类 5.创建和填充 6.处理循环队列 7.更新活动粒子 8.移除非活性粒子 9.绘制有…

MQTT协议-CONNECT报文介绍

MQTT协议-CONNECT报文介绍 参考MQTT协议中文笔记:https://mcxiaoke.gitbooks.io/mqtt-cn/content/mqtt/01-Introduction.html Connect报文主要用于客户端连接服务器的,未涉及具体数据的传输,可以使用网络调试助手来连接阿里云平台&#xff…

什么是档案级光盘?它的寿命是多少年?

我们经常会听到有人在说:CD、DVD光盘的寿命多少多少年,蓝光光盘的寿命多少多少年。实际上这个说法是不对的,至少是不准确的,因为同样是CD、DVD光盘或者蓝光光盘,也分等级,而不同等级的光盘的寿命是不一样的…

ENVI_Classic:快速入门_菜单栏常见功能的基本介绍

说明:由于实验要求,所以并没有对各个功能进行详尽的解释,大多点到为止,少部分实验内容是实验要求所以步骤详尽。当然由于经验不足,有一些可能存在错误恳请指正.1. 实验目的通过ENVI Classic对自行下载的遥感图像进行一…

JavaScript Math 算数对象实例集合

文章目录JavaScript Math 算数对象实例集合使用 round() 对数字进行舍入使用 random() 来返回 0 到 1 之间的随机数使用 max() 来返回两个给定的数中的较大的数使用 min() 来返回两个给定的数中的较小的数摄氏度与华氏转换JavaScript Math 算数对象实例集合 注意: 了…

MySQL基础篇2

第一章 SQL语句之DQL 语法:查询不会对数据库中的数据进行修改,根据指定的方式来呈现数据。 语法格式: select * | 列名,列名 from 表名 [where 条件表达式] select 是查询指令,可以读 1 ~ n 行数据; 列名换成 * 号&a…

网络:TCP与UDP相关知识(详细)

目录:1、UDP 和 TCP 的特点与区别2、UDP 、TCP 首部格式3、TCP 的三次握手和四次挥手4、TCP 的三次握手(为什么三次?)5、TCP 的四次挥手(为什么四次?)6、TCP 长连接和短连接的区别7、TCP粘包、拆…

Caddy2学习笔记——Caddy2的安装、部署和编译小白教程

个人环境概述 本人拥有一个国内云服务商的云主机和一个备案好的域名,希望通过caddy2来作为web服务器。我的云主机是公网ip,地址为:43.126.100.78;我备案好的域名是:hotgirl.com。后面的文章都以上述的ip和域名来进行讲…

什么是jvm?

说明:做java开发的几乎都知道jvm这个名词,但是由于jvm对实际的简单开发的来说关联的还是不多,一般工作个一两年(当然不包括爱学习的及专门做性能优化的什么的),很少有人能很好的去学习及理解什么是jvm&…

跨源资源共享(CORS)-亲测理解,以及对http的状态,参数的理解和使用,对预检请求的触发和解决

跨源资源共享(CORS)-亲测理解,以及对http的状态,参数的理解和使用 跨源资源共享(CORS,或通俗地译为跨域资源共享)是一种基于HTTP 头的机制,该机制通过允许服务器标示除了它自己以外的…

Python 的IDE——PyCharm

IDE介绍与安装 介绍 集成开发环境(IDE) 集成开发环境(IDE,integrated Development Environment) —— 集成开发软件需要的所有工具,一般包括以下工具: 图形用户界面 代码编辑器(支持代码补全、自动缩进) 编译器/解释器 调试器…

002+limou+HTML——(2)HTML文档

000、前言 一般来说一个静态网页拥有四种元素:文字、图片、超链接、音频和视频(注意,即使在web网页中植入Javascript语言,也不一定是动态网页,真正的动态网页判断标准:是否和服务器产生交互) …

Nginx 高可用方案

准备工作 10.10.4.5 10.10.4.6 VIP:10.10.4.10 两台虚拟机。安装好Nginx 安装Nginx 更新yum源文件: rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm wget -O /etc/yum.repos.d/CentOS-Ba…

17、经验贝叶斯估计

经验贝叶斯估计贝叶斯估计的问题定义为根据一些观测数据 x 来估计未知参数 θ,用一个损失函数来衡量估计的准确性,如果用均方误差(MSE)来估计的话,将问题建模为等价于求解后验分布的均值最小均方误差估计器 minimum mean square error (MMSE)…

XSS挑战赛(xsslabs)11~16关通关解析

简介 XSS挑战赛,里面包含了各种XSS的防御方式和绕过方式,好好掌握里面的绕过细节,有助于我们更好的去发现XSS漏洞以及XSS的防御。本文更多的是分享解析的细节,不是一个标准的答案,希望大家在渗透的时候有更多的思维。…

MySQL日期和时间函数 整理

1 获取日期、时间 CURDATE() ,CURRENT_DATE() 返回当前日期,只包含年、月、日 CURTIME() , CURRENT_TIME() 返回当前时间,只包含时、分、秒 NOW() / SYSDATE() / CURRENT_TIMESTAMP() / LOCALTIME() / LOCALTIMESTAMP() 返回当…

工作订单之检查

1. 创建并查看检查 1.1 检查存在的意义 检查旨在帮助技术人员轻松回答工作订单中所需要回答的一系列问题,能够帮助技术人员梳理工作步骤,指导技术人员在检查中获得帮助 检查支持脱机操作,即在没有网络的情况下填写数据,并在网络恢…