学习总结 2021.12.31
0. 参考
CSDN:彻底搞清分库分表(垂直分库,垂直分表,水平分库,水平分表)
知乎:面试官:MYSQL单表数据达2000万性能严重下降,为什么?
分片是一种通用的架构模式,数据库分库分表就是数据库领域的分片架构
课程中分开讲,是因为数据库分库分表用的太多了,而且要自己设计,而其它存储系统,基本都有自己内置的分片架构
1. 垂直分表
定义:将一个表按照字段分成多表,每个表存储其中一部分字段
分析:
业务实体中各个数据项的访问频次是不一样的,如用户在浏览商品列表时,只有对某个商品感兴趣时才会查看商品详情,也就是商品名称、价格访问频次高,存储空间小,商品描述字段访问频次低,存储空间大;因此,将访问频次高商品基本信息和访问频次低的商品描述信息存放在不同的表,避免了 IO 争抢,提升热门数据的操作效率
页是数据库存储的最小单位,以 MySQL InnoDB 存储引擎为例,每个页的默认大小为 16KB,行数据占用空间越小,单页内的数据行就越多,数据库的整体性能越好,而大字段占用空间大,单页存储的行数就少,IO 效率就低
内存汇总可以加载更多的字段长度较短且访问频率较高的数据,命中率更高,减少了磁盘 IO
优点:
可以避免 IO 争抢并减少锁表的几率,查看详情的用户与商品信息浏览互不影响
充分发挥热门数据的操作效率,商品信息的操作的高效率不会被商品描述的低效率所拖累
缺点:
需要 join
依然会存在单表数据量过大的问题,需要进行水平切分
垂直拆分的条件:
单表数据量未来可能千万,字段超过 20 个
且包含了超长的 vchar、clob、blob 等大字段拆分出来放在附表中
2. 垂直分库
定义:垂直分库是指按照业务将表进行分类,分布到不同的数据库上面,每个库可以放在不同的服务器上,它的核心理念是专库专用
分析:
库内垂直分表只解决了单一表数据量过大的问题,但并没有将表分不到不同的服务器上,每个表还是竞争同一个物理机的 CPU、内存、网络 IO、磁盘;根据业务耦合度,将表进行分类,分布到不同的数据库(耦合度高的要放到同一个库),这样每个库可以放在不同的服务器上,其核心理念是专库专用
优点:
解决业务层面的耦合,业务清晰
能对不同业务的数据进行分级管理、维护、监控、扩展
多个服务器共同分担压力,降低单机硬件资源瓶颈
缺点:
部分表无法 join,需要通过接口聚合方式解决
增加了分布式事务处理复杂度
依然会存在单表数据量过大的问题,需要进行水平切分
3. 水平分库
定义:水平分库是把同一个表的数据按一定规则拆到不同的数据库中,每个库可以放在不同的服务器上
分析:
垂直分库、分表,解决不了数据量过大的问题,比如,随着业务发展,商品信息与日聚餐,这个时候单台服务器的性能就已经无法支持
业界流传 MySQL 单表数据量大于 2000 万行,性能会明显下降;阿里巴巴《Java 开发手册》提出单表行数超过 500 万行或者单表容量超过 2GB,推荐进行分库分表;这些说法的理论依据来源于 MySQL 的 B+ 树索引结构,也就是数据量越大,B+ 树的高度会增加,从而导致更多次的 IO 操作,通常 B+ 数的高度是 1-3 比较合适
假设主键 ID 为 bigint 类型,长度为 8 字节,而指针大小在 InnoDB 源码中设置为 6 字节,这样一共 14 字节,一页的大小是 16K,那么就可以存放 16384/14=1170
如果 B+ 树高度为 2,可以存放 1170*16=18720
如果 B+ 树高度为 2,可以存放 1170*1170*16=21902400
优点:
解决单库数据量过大、高并发的性能瓶颈,提升系统稳定性和负载能力
缺点:
跨分片的事务一致性难以保证
跨库的 join 关联查询性能较差
数据多次扩展难度和维护量极大
数据分片规则:
根据数值范围,如,按照时间区间或 ID 区间来切分
优点,单表大小可控,便于水平扩展,后续想进行扩容,增加节点即可
缺点,热点数据成为性能瓶颈
根据数值取模,一般采用 hash 取模的切分方式
优点,不容易出现热点和并发访问
缺点,后期分片集群扩容时,需要迁移旧数据;容易面临跨分片查询的复杂问题
4. 水平分表
定义:水平分表是在同一个数据库内,把同一个表的数据按一定规则拆到多个表中
分析:
把一个表的数据(按数据行)分到多个同一个数据库的多张表中,每个表只有这个表的部分数据,这样做能小幅提升性能,它仅仅作为水平分库的一个补充优化
5. 小结
一般来说,在系统设计阶段就应该根据业务耦合松紧来确定垂直分库,垂直分表方案,在数据量及访问压力不是特别大的情况,首先考虑缓存、读写分离、索引技术等方案。若数据量极大,且持续增长,再考虑水平分库水平分表方案。
分库分表能有效的环节单机和单库带来的性能瓶颈和压力,突破网络 IO、硬件资源、连接数的瓶颈,同时也带来了以下问题:
事务一致性问题
跨节点关联查询 join 问题
跨节点分页、排序、函数问题
全局主键避重问题
数据迁移、扩容问题
何时需要考虑切分:
能不切分尽量不要切分,避免过度设计和过早优化
数据量过大,正常运维影响业务访问
随业务发展,需要对某些字段垂直拆分
数据量快速增长
安全性和可用性
评论