百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

一文搞懂MySQL数据库分库分表

mhr18 2024-12-06 17:56 20 浏览 0 评论

如果数据量过大,大家一般会分库分表。分库需要注意的内容比较少,但分表需要注意的内容就多了。

工作这几年没遇过数据量特别大的业务,那些过亿的数据,因为索引设置合理,单表性能没有影响,所以实战中一直没用过分表。最近手里有个项目,预估数据量会很大,分表方案是选项之一,趁着这次机会,把分表的内容整理一下。

这次要讲的主要是水平分库分表,其它种类的分库、分表比较容易理解。后面如果不详细说明,都指水平分库分表。

1.基础知识

1.1分库分表定义

1.1.1分库

垂直分库:按照业务模块进行切分,将不同模块的表切分到不同的数据库中。

如电商系统有电商数据库,按照业务模块可以分为用户库、商品库、订单库,这些都可以当做独立数据库,不需要放到一起。好处是既能独立变更,又能隔绝相互影响。

1.1.2分表

垂直分表:也就是“大表拆小表”,基于列字段进行的。一般是因为表设计不合理,需要进行拆分。

如一张表存放学生、老师、课程、成绩信息,最好拆分为学生表、课程表、成绩表。

水平分表:针对数据量巨大的单张表(比如订单表),按照某种规则(RANGE,HASH取模等),切分到多张表里面去。但是这些表还是在同一个库中,所以库级别的数据库操作还是有IO瓶颈。不建议采用。

水平分库分表:将单张表的数据切分到多个服务器上去,每个服务器具有相应的库与表,只是表中数据集合不同。水平分库分表能够有效的缓解单机和单库的性能瓶颈和压力,突破IO、连接数、硬件资源等的瓶颈。

1.2分区与分片的区别

分表时经常能看到两个名词:分区和分片。这两个词都是指将大表的数据分成多块,但两者还是有本质区别的。

Sharding(分片) 的思想从分区的思想而来,但数据库分区基本上是数据对象级别的处理,比如表和索引的分区,每个子数据集上能够有不同的物理存储属性,还是单个数据库范围内的操作,而 Sharding 是能够跨数据库,甚至跨越物理机器的。

MySQL5.1提供的分区(Partition)功能确实可以实现表的分区,但是这种分区是局限在单个数据库范围里的,它不能跨越服务器的限制。

我们在分表的时候,一般使用的是分片方案,即数据存放在多个物理机器。

1.3分片策略

分片规则一般有如下:

1.3.1按照哈希切片

  1. mod-long:用于分区列为数值的hash分区分片列 id=分区列值 mod 分片数
  2. mod-long-by-hash:用于分区列为字符串的hash分区分片列id=hash(分区列值) mod 分片数

1.3.2按照范围切片

  1. range:建表时创建分区规则,根据分区规则就可以确定分区列的值在哪个分区上一般分区列为时间或者数值,如date_range:
    0: 1000000
    1: 2000000
    2: 3000000
    3: 4000000
    4: maxvalue
    如果分区列值为1500000,则数据放到1号分片上。

2.分库分表中间件

需要使用者感知不到这是分片表,使用时需要和正常表一样,一般需要引入中间件。

操作分片表一般有三种方式:

2.1客户端分片

所谓的客户端分片即在使用数据库的应用层直接操作分片逻辑,分片规则需要在同一个应用的多个节点间进行同步,每个应用层嵌入一个操作切片的逻辑实现。如当当网的Sharding JDBC。

2.2代理分片

代理分片就是在应用层和数据库层之间添加一个代理层,把分片的路由规则配置在代理层,代理层对外提供与JDBC兼容的接口给应用层,在业务实现之后,在代理层配置路由规则即可。如Mycat就是基于此种解决方案来实现的。

2.3支持事务的分布式数据库

支持分布式事务的框架,目前有OceanBase、TiDB框架,这些框架将可伸缩特定和分布式事务的实现包装到了分布式数据库内部实现,对使用者透明,使用者不需要直接控制这些特性,但是对事务的支持不如关系型数据,适合大数据日志系统、统计系统、查询系统、社交网站等。

2.4说明

支持事务的分布式数据库算另一种选型了,和MySQL已经没有关系。

对于客户端分片和代理分片,目前工作过的两家公司用的都是代理方式,一家用的是MyCAT,一家用的Dbatman。客户端分片方式没有接触过。这两种的区别为:

3.分布式事务

分片意味数据分布在多台物理机器上,引入分布式事务问题。我们将单表的数据切片后存储在多个数据库甚至是多个数据库实例中,所以依靠数据库本身的事务机制不能满足需要,这时就需要用到分布式事务来解决。关于分布式事务的相关内容可以看分布式系统与一致性协议。

这里不细讲分布式事务如何处理,后面会单独写篇文章。我们聊一下分布式事务会对操作MySQL产生什么影响。

既然知道引入了分布式事务问题,那么操作MySQL的时候,肯定不能和单表一样进行操作。不同中间件能力不一样,所以需要单独分析,我以Dbatman为例,阐述使用上的区别。

1.分片版本不维护自增与主键唯一,业务可自行维护唯一键

  • 意味不同分片的主键id会重复

2.不支持跨分片事务写,可以跨分片事务读

  • 如果确保事务操作的内容在一个分片内,就不是分布式事务,和单机行为一致
  • 一个事务涉及多个分片叫跨节点事务,单分片事务支持

3.update和insert必须带分片列

总结一下就是操作同一个分片没影响,操作不同分片需要看中间件支持不支持。

如果使用中间件,即使同一个分片,尽量不要用特殊的SQL,有些中间件可能无法支持,如insert not exists。

4.是否选择分库分表

选择做分库分表,考虑的几个要素是:

  1. 空间方面:单个物理实例无法支撑数据存储需求,单台物理机无法继续通过加盘的方式扩容
  2. 主库性能:受限于单个主库的CPU/内存/磁盘IOPS的影响,接近或者达到上限后,需要拆分
  3. 容灾方面:减少单个主库宕机对于写入的影响。

针对以上3点,我们还可以多考虑一下,有没有更合适的方案

1.空间方面:

  • 删除历史数据清空空间
  • 修改存储模型降低对于MySQL磁盘的占用
  • 改用空间压缩比更高的存储引擎

2.主库性能:

  • 可以通过读写分离的方式,降低对于写库的读请求量,从而提升对于写入的支撑。
  • 优化数据写入模型,减少批量写入(削峰)

3.容灾方面:

  • 如果业务对于读高可用要求比较高,一般建议是做读写分离,将重要的请求路由至读库。读库数量一般会比写库多N个,在代理层面会做容灾的自动切换。
  • 从集群整体的角度看,分库分表实际上是会扩大故障率,假设单台物理机的SLA是99.99%,那么2台物理机的SLA就是99.98(约数), 10台物理机的SLA就只剩下99.90%了。平均每年的故障时间也会从52分钟提升到525分钟。所以在有些场景下,单个节点故障可能会导致代理整个不可用,从而放大故障的影响范围。

5.设计

现在项目需求为:

  1. 生成唯一码,码值为整数
  2. 码值需要批量插入数据库
  3. 对码的更新操作都是单条处理,而且对码值进行操作需要进行记录
  4. 最终数量不定,长远看数据量会很大

基于上面的需求,做如下设计:

  1. 以码值为主键,自己控制主键唯一
  2. 码表使用range进行分片,如分片范围为01亿,1亿2亿
  3. 码表的操作记录表同样使用range进行分片,分片范围和码表一致

通过这种设计能够实现需求。

但计算后发现,单表能存百亿条数据,而且索引设计比较合理,业务逻辑相对简单,无高并发请求,单表好像也可以搞。

总结

正常情况下,我们一般需要做水平分库分表,这就涉及到分布式事务,一定要考虑清楚是否能满足自己的需求、想用的SQL语句是否都能支持,考虑一下是否还有别的方案。

关于中间件的实现原理,了解的不是很深,后面有时间的话,可以学习一下。

资料

  1. MySQL 分库分表方案,总结的非常好!
  2. MySQL之分库分表(MyCAT实现)
  3. Mysql分库分表实战(一)——一文搞懂Mysql数据库分库分表
  4. MySql分表、分库、分片和分区知识
  5. 数据库分片(Sharding)与分区(Partition)的区别(转)
  6. 数据库分库分表中间件对比(很全)
  7. 分库分表中间件
  8. 分库分表:中间件方案对比
  9. XA 分布式事务原理

最后

大家如果喜欢我的文章,可以关注我的公众号(程序员麻辣烫)

我的个人博客为:https://shidawuhen.github.io/

往期文章回顾:

招聘

  1. 字节跳动|内推大放送
  2. 字节跳动|今日头条广州服务端研发工程师内推
  3. 字节跳动|抖音电商急招上海前端开发工程
  4. 字节跳动|抖音电商上海资深服务端开发工程师-交易
  5. 字节跳动|抖音电商武汉服务端(高级)开发工程师
  6. 字节跳动|飞书大客户产品经理内推咯
  7. 字节跳动|抖音电商服务端技术岗位虚位以待
  8. 字节跳动招聘专题

设计模式

  1. Go设计模式(15)-门面模式
  2. Go设计模式(14)-适配器模式
  3. Go设计模式(13)-装饰器模式
  4. Go设计模式(12)-桥接模式
  5. Go设计模式(11)-代理模式
  6. Go设计模式(10)-原型模式
  7. Go设计模式(9)-建造者模式
  8. Go设计模式(8)-抽象工厂
  9. Go设计模式(7)-工厂模式
  10. Go设计模式(6)-单例模式
  11. Go设计模式(5)-类图符号表示法
  12. Go设计模式(4)-代码编写优化
  13. Go设计模式(4)-代码编写
  14. Go设计模式(3)-设计原则
  15. Go设计模式(2)-面向对象分析与设计
  16. Go设计模式(1)-语法

语言

  1. 再也不怕获取不到Gin请求数据了
  2. 一文搞懂pprof
  3. Go工具之generate
  4. Go单例实现方案
  5. Go通道实现原理
  6. Go定时器实现原理
  7. Beego框架使用
  8. Golang源码BUG追查
  9. Gin框架简洁版
  10. Gin源码剖析

架构

  1. 分页复选设计的坑
  2. 支付接入常规问题
  3. 限流实现2
  4. 秒杀系统
  5. 分布式系统与一致性协议
  6. 微服务之服务框架和注册中心
  7. 浅谈微服务
  8. 限流实现1
  9. CDN请求过程详解
  10. 常用缓存技巧
  11. 如何高效对接第三方支付
  12. 算法总结

存储

  1. MySQL开发规范
  2. Redis实现分布式锁
  3. 事务原子性、一致性、持久性的实现原理
  4. InnoDB锁与事务简析

网络

  1. HTTP2.0基础教程
  2. HTTPS配置实战
  3. HTTPS连接过程
  4. TCP性能优化

工具

  1. GoLand实用技巧
  2. 根据mysql表自动生成go struct
  3. Markdown编辑器推荐-typora

读书笔记

  1. 《毛选》推荐
  2. 原则
  3. 资治通鉴
  4. 敏捷革命
  5. 如何锻炼自己的记忆力
  6. 简单的逻辑学-读后感
  7. 热风-读后感
  8. 论语-读后感
  9. 孙子兵法-读后感

思考

  1. 对写博客的一些思考
  2. 晚上打119的经历
  3. 为动员一切力量争取胜利而斗争
  4. 反对自由主义
  5. 实践论
  6. 评价自己的标准
  7. 2020博客总结
  8. 服务端团队假期值班方案
  9. 项目流程管理
  10. 对项目管理的一些看法
  11. 对产品经理的一些思考
  12. 关于程序员职业发展的思考
  13. 关于代码review的思考

相关推荐

【预警通报】关于WebLogic存在远程代码执行高危漏洞的预警通报

近日,Oracle官方发布了2021年1月关键补丁更新公告CPU(CriticalPatchUpdate),共修复了包括CVE-2021-2109(WeblogicServer远程代码执行漏洞)...

医院信息系统突发应急演练记录(医院信息化应急演练)

信息系统突发事件应急预案演练记录演练内容信息系统突发事件应急预案演练参与人员信息科参与科室:全院各部门日期xxxx-xx-xx时间20:00至24:00地点信息科记录:xxx1、...

一文掌握怎么利用Shell+Python实现完美版的多数据源备份程序

简介:在当今数字化时代,无论是企业还是个人,数据的安全性和业务的连续性都是至关重要的。数据一旦丢失,可能会造成无法估量的损失。因此,如何有效地对分布在不同位置的数据进行备份,尤其是异地备份,成为了一个...

docker搭建系统环境(docker搭建centos)

Docker安装(CentOS7)1.卸载旧版Docker#检查已安装版本yumlistinstalled|grepdocker#卸载旧版本yumremove-ydocker.x...

基础篇:数据库 SQL 入门教程(sql数据库入门书籍推荐)

SQL介绍什么是SQLSQL指结构化查询语言,是用于访问和处理数据库的标准的计算机语言。它使我们有能力访问数据库,可与多种数据库程序协同工作,如MSAccess、DB2、Informix、M...

Java21杀手级新特性!3行代码性能翻倍

导语某券商系统用这招,交易延迟从12ms降到0.8ms!本文揭秘Oracle官方未公开的Record模式匹配+虚拟线程深度优化+向量API神操作,代码量直降70%!一、Record模式匹配(代码量↓8...

一文读懂JDK21的虚拟线程(java虚拟线程)

概述JDK21已于2023年9月19日发布,作为Oracle标准Java实现的一个LTS版本发布,发布了15想新特性,其中虚拟线程呼声较高。虚拟线程是JDK21中引入的一项重要特性,它是一种轻量级的...

效率!MacOS下超级好用的Linux虚拟工具:Lima

对于MacOS用户来说,搭建Linux虚拟环境一直是件让人头疼的事。无论是VirtualBox还是商业的VMware,都显得过于笨重且配置复杂。今天,我们要介绍一个轻巧方便的纯命令行Linux虚拟工具...

所谓SaaS(所谓三维目标一般都应包括)

2010年前后,一个科技媒体的主编写一些关于云计算的概念性问题,就可以作为头版头条了。那时候的云计算,更多的还停留在一些概念性的问题上。而基于云计算而生的SaaS更是“养在深闺人未识”,一度成为被IT...

ORA-00600 「25027」 「x」报错(报错0xc0000001)

问题现象:在用到LOB大对象的业务中,进行数据的插入,失败了,在报警文件中报错:ORA-00600:内部错误代码,参数:[25027],[10],[0],[],[],[],[],[...

安卓7源码编译(安卓源码编译环境lunch失败,uname命令找不到)

前面已经下载好源码了,接下来是下载手机对应的二进制驱动执行编译源码命令下载厂商驱动https://developers.google.com/android/drivers?hl=zh-cn搜索NGI...

编译安卓源码(编译安卓源码 电脑配置)

前面已经下载好源码了,接下来是下载手机对应的二进制驱动执行编译源码命令下载厂商驱动https://developers.google.com/android/drivers?hl=zh-cn搜索NGI...

360 Vulcan Team首战告捷 以17.5万美金强势领跑2019“天府杯“

2019年11月16日,由360集团、百度、腾讯、阿里巴巴、清华大学与中科院等多家企业和研究机构在成都联合主办了2019“天府杯”国际网络安全大赛暨2019天府国际网络安全高峰论坛。而开幕当日最激荡人...

Syslog 日志分析与异常检测技巧(syslog发送日志配置)

系统日志包含有助于分析网络设备整体运行状况的重要信息。然而,理解并从中提取有效数据往往颇具挑战。本文将详解从基础命令行工具到专业日志管理软件的全流程分析技巧,助你高效挖掘Syslog日志价值。Gr...

从Oracle演进看数据库技术的发展(从oracle演进看数据库技术的发展的过程)

数据库技术发展本质上是应用需求驱动与基础架构演进的双向奔赴,如何分析其技术发展的脉络和方向?考虑到oracle数据库仍然是这个领域的王者,以其为例,管中窥豹,对其从Oracle8i到23ai版本的核...

取消回复欢迎 发表评论: