不要为了“分库分表”而“分库分表”!
1,《往期精选优秀博文都在这里了!》 2、Spring 解决循环依赖的 3 种方式! 3、微信支付的软件架构,到底有多NB! 4、真能一快遮"百丑"?为什么要弃坑FastJson 5、我把SpringBoot项目从18.18M瘦身到0.18M,部署起来真省事!
来源:rrd.me/gEJnq数据库瓶颈
IO 瓶颈:
第一种:磁盘读 IO 瓶颈,热点数据太多,数据库缓存放不下,每次查询会产生大量的 IO,降低查询速度→分库和垂直分表。
第二种:网络 IO 瓶颈,请求的数据太多,网络带宽不够→分库。
CPU 瓶颈:
第一种:SQL 问题:如 SQL 中包含 join,group by,order by,非索引字段条件查询等,增加 CPU 运算的操作→SQL 优化,建立合适的索引,在业务 Service 层进行业务计算。
第二种:单表数据量太大,查询时扫描的行太多,SQL 效率低,增加 CPU 运算的操作→水平分表。
分库分表
水平分库
每个库的结构都一样
每个库中的数据不一样,没有交集
所有库的数据并集是全量数据
水平分表
每个表的结构都一样。
每个表的数据不一样,没有交集,所有表的并集是全量数据。
垂直分库
每个库的结构都不一样。
每个库的数据也不一样,没有交集。
所有库的并集是全量数据。
垂直分表
每个表的结构不一样。
每个表的数据也不一样,一般来说,每个表的字段至少有一列交集,一般是主键,用于关联数据。
所有表的并集是全量数据。
分库分表工具
常用的分库分表工具如下:
Sharding-JDBC(当当)
TSharding(蘑菇街)
Atlas(奇虎 360)
Cobar(阿里巴巴)
MyCAT(基于 Cobar)
Oceanus(58 同城)
Vitess(谷歌) 各种工具的利弊自查
分库分表带来的问题
事务一致性问题
①分布式事务
②最终一致性
跨节点关联查询 Join 问题
①全局表
②字段冗余
③数据组装
④ER 分片
跨节点分页、排序、函数问题
全局主键避重问题
①UUID
②结合数据库维护主键 ID 表
`id` bigint(20) unsigned NOT NULL auto_increment,
`stub` char(1) NOT NULL default '',
PRIMARY KEY (`id`),
UNIQUE KEY `stub` (`stub`)
) ENGINE=MyISAM;
SELECT LAST_INSERT_ID();
③Snowflake 分布式自增 ID 算法
第一位未使用。
接下来的 41 位是毫秒级时间,41 位的长度可以表示 69 年的时间。
5 位 datacenterId,5 位 workerId。10 位长度最多支持部署 1024 个节点。
最后 12 位是毫秒内计数,12 位的计数顺序号支持每个节点每毫秒产生 4096 个 ID 序列。
数据迁移、扩容问题
什么时候考虑分库分表
①能不分就不分
②数据量过大,正常运维影响业务访问
对数据库备份,如果单表太大,备份时需要大量的磁盘 IO 和网络 IO。
对一个很大的表做 DDL,MySQL会锁住整个表,这个时间会很长,这段时间业务不能访问此表,影响很大。
大表经常访问和更新,就更有可能出现锁等待。