历史背景
MySql性能瓶颈
- 1. 表数据量过大
- 2. Sql查询过于复杂
- 3. Sql没走索引
- 4. 数据库服务器性能低
解决方案
阿里开发手册:单表行数超过500W或者单表容量超过2G
数据库分库分表
- 分库分表
- 冷热数据分离
- 历史数据分离
数据库分库分表
- 1. 垂直拆分
- 垂直分表(大表拆成多个小表)
优点
- 防止单表字段过多产生页分裂从而导致IO次数过多,效率差的问题
- 可以达到最大化利用Cache的目的,具体在垂直拆分的时候可以将不常变的字段放一起,将经常改变的放一起
缺点
1. 主键出现冗余,需要管理冗余例
2. 会引起表连接JOIN操作(增加CPU开销
3. sql以及事务处理复杂
- 垂直分库(单个库拆成多个库 微服务系统)
优点
分散单库访问压力
缺点
分布式事务问题
- 2. 水平拆分
- 1. 水平分表
优点
单库单表的数据能保持在一定的量级,有助于性能的提高。
2.切分的表结构相同,应用层改造较少,只需要增加路由规则即可。
3.提高了系统的稳定性和负载能力。
缺点
- 切分后,数据是分散的,跨库join操作难和性能差
- 拆分规则难以抽象
- 分片事务的一致性难以解决
- 数据扩容的难度和维护量极大
- 2. 水平分库
分库分表算法
- 1. 哈希取模算法
优点
算法简单,数据分布相对均匀
缺点
扩容问题,需要哈希取模全部数据迁移(比如增加user_05,算法变成id%5,01-04里面数据全部需要重新分布)
- 2. 一致性哈希算法
当B需要移除时
hash环的偏斜
在实际的映射中,服务器可能会被映射成如下模样。
如果服务器被映射成上图中的模样,那么被缓存的对象很有可能大部分集中缓存在某一台服务器上,如下图所示。
虚拟节点(定义虚拟节点,让哈希环分布均匀)
- 3. 按照范围分片算法(按照不同的数据业务特性定义分片键)
- 按照商家
- 按照时间月份
- 按照地域
案例
用户表
- 1. 功能
注册,登录,查询,修改
- 2. 使用范围
- 1. 用户端(用户登录,修改用户,信息查询)
根据用户ID查询用户信息->90%
根据phone,email查询用户信息->10%
- 2. 管理员端
- 统计用户信息
- 查询条件多变查询
可以根据用户ID进行分片
分库分表中间件
- 1. 分库分表组件(Sharding-JDBC 代码实现)
- 2. 服务端代理(MyCat)
分库分表问题
- 1. 历史数据迁移
- 2. 复杂SQL联合查询
- 3. 分页问题
- 4. 事务问题