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

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

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

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: 10000001: 20000002: 30000003: 40000004: 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会重复
  1. 不支持跨分片事务写,可以跨分片事务读
  • 如果确保事务操作的内容在一个分片内,就不是分布式事务,和单机行为一致
  • 一个事务涉及多个分片叫跨节点事务,单分片事务支持
  1. update和insert必须带分片列

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

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的思考

一文搞懂MySQL数据库分库分表相关推荐

  1. mysql删除分表键_一文看懂 MySQL 分区和分表,提高表增删改查效率

    原标题:一文看懂 MySQL 分区和分表,提高表增删改查效率 作者:冯帅,精通Oracle. MySQL. 擅长异构数据库数据同步及迁移.数据库的设计和调优,对高可用方案有深入研究. MySQL分区和 ...

  2. 面试官:说说Mysql数据库分库分表,并且会有哪些问题?

    之前一篇文章已经谈到了数据库集群之主从集群也就是读写分离,也提到了读写分离其实只是分担了访问的压力,但是存储的压力没有解决. 存储的压力说白了就是随着系统的演化,需求的增加,可能表的数量会逐渐增多,比 ...

  3. 关于mysql数据库分库分表、事务一致性问题的学习

    很多人张嘴就是分库分表,好像不分库分表就不算牛逼的系统,不谈分库分表就没有逼格一样. 个人觉得,在设备配置别太挫.业务拆分别太渣.sql写法别太low.单表数据不上亿的情况下,靠读写分离.索引优化.表 ...

  4. mysql某个表被行锁了_一文搞懂MySQL行锁、表锁、间隙锁详解

    准备工作 创建表 tb_innodb_lock drop table if exists test_innodb_lock; CREATE TABLE test_innodb_lock ( a INT ...

  5. 一文搞懂 MySQL 索引

    一文搞懂 MySQL 索引 1.MySQL 索引 简介 1.1.MySQL 索引 是什么?  索引是一个单独的.存储在 磁盘 上的 数据库结构 ,包含着对数据表里 所有记录的 引用指针. 1.2. M ...

  6. 面试必问:一文弄懂MySQL数据库索引之底层数据结构和索引类型

    面试必问:一文弄懂MySQL数据库索引之底层数据结构和索引类型 前言 一.索引 1.1作用 1.2特点 1.3使用 1.3.1创建索引 1.3.2删除索引 1.3.3查看表中的索引 1.3.4查看SQ ...

  7. 一文搞懂MySQL XA如何实现分布式事务

    一文搞懂MySQL XA如何实现分布式事务 前言 XA 协议 如何通过MySQL XA实现分布式事务 前言 MySQL支持单机事务的良好表现毋庸置疑,那么在分布式系统中,涉及多个节点,MySQL又是如 ...

  8. mysql分库分表中间件6_当当开源sharding-jdbc,轻量级数据库分库分表中间件

    近期,当当开源了数据库分库分表中间件sharding-jdbc. Sharding-JDBC是当当应用框架ddframe中,从关系型数据库模块dd-rdb中分离出来的数据库水平分片框架,实现透明化数据 ...

  9. mysql分库分表 ppt_数据库分库分表中间件架构解析.ppt

    数据库分库分表中间件架构解析 Processor(1) Processor(n) MySQL MySQL MySQL Cobar结构 Front-end Communication Applicati ...

最新文章

  1. ceres实现的pnp解算后的位姿优化代码详解
  2. backbone.js学习笔记
  3. Android Studio开发配置NDK环境
  4. Linux 文件查找(find)
  5. 关于PHP使用GD库生成的验证码无法在别处显示
  6. POJ 1581 优先队列 priority_queue -- 比赛胜者求解
  7. 08服务器许可证安装向导,08_安装部署GRID许可证服务器.pdf
  8. 湘潭大学 计算机学院程诗婕,云南大学学生获得2019CCF大学生计算机系统与程序设计竞赛西...
  9. Python_爬虫_urllib解析库
  10. Fiddler V5中文版
  11. 安川机器人原点丢失_安川机器人报错代码:原点位置校准和操作方法
  12. android手机怎么用车载高德地图,用手机更新车载高德地图,汽车导航升级方法...
  13. html 卫星地图显示地名,卫星图看:河南10个名字非常好听的县(区),你认识几个?...
  14. idea启动vue项目
  15. Ubuntu常用软件合集
  16. RS-485串口通讯测试及四路集线器功能探究
  17. MySql基础篇之SQL语句(DDL、DML、DQL、RCL)
  18. python3.7-secrets模块
  19. sql查询_SQL查询
  20. 满格信号服务器开小差,明明信号满格,网络却很慢?教你三招解决!

热门文章

  1. input隐藏传值php,使用HTML中input标签的hidden发送隐藏数据的方法
  2. Protobuf序列化原理
  3. 论文解读:(TransH)Knowledge Graph Embedding by Translating on Hyperplanes
  4. Adobe AfterEffects CC 2023(AE2023)安装教程与下载方式
  5. 如何用python处理excel简单考勤统计_如何使用Excel快速考勤,统计迟到早退等情况?...
  6. 计算机毕业设计Java大学生健康电子档案系统(源码+系统+mysql数据库+lw文档)
  7. 四川山海蓝图如何制作抖音短视频
  8. Android 1.5 -10.0 都有哪些新特性?
  9. 上海汉得校招笔试-Java
  10. CDH6.2.0安装phoenix5.0.0