什么情况下用到分库分表:
1.写操作永久的超过了服务器的磁盘负载,太多写入导致副本同步永远落后了
2.读到的数据量太大以至于撑爆内存,并且大多数读操作开始直击硬盘而不是从内存中读数据
库:database 表:table 分库分表:sharding
数据库架构演变:
开始单机数据库就够用了,后来随着业务增长,请求增多,开始进行读写分离,主库(master)负责写,从库(slaver)负责读,从库从主库同步更新数据,保持数据一直。但是当用户量级上来以后,一个master会遇到性能瓶颈,于是又开集群,多个master,但是多个master之间,也需要互相同步,这样也是一样耗性能的。这时可以用分库分表,对写操作进行切分。
分库分表前的问题:
单库太大: 单个数据库处理能力有限,可能会遇到IO瓶颈、磁盘空间不足等问题,需要切分成更小的库
单表太大:CRUD性能瓶颈、查询超时、索引膨胀,需要切分成数据集更小的表
分库分表的方法
一般原则是先垂直分,后水平分。
垂直切分:
1.垂直分表:
也就是一张大表,把不常用的,数据较大的字段拆分出一个表
2.垂直分库
可以根据业务,把不同业务类型的表放到不同数据库中,降低单个数据库服务器的压力,在高并发情况下,可以提高很大性能。
水平切分:
1.水平分表
针对数据量巨大的单张表,按照某种规则,且分到多张表里面去,但是这张表还是在同一个库中,所以会遇到io瓶颈,连接数瓶颈等,不建议采用
2.水平分库分表
把单张表的数据分到不同数据库服务器上,能够有效的缓解单机和单库的性能瓶颈,突破io,连接数、硬件资源等的限制
3.水平分库分表原则
RANG: 某一个数据量一张表
HASH取模:根据某关联字段,做hash取模,放到不同表中,如:根据用户id,存订单表
地理位置:华北、华中、东南等,或者按照省
时间:某几年或者几个月的数据放到一张表
分库分表后遇到问题:
事务:变成了分布式事务
关联查询、分组查询、排序等:因为在不同哭中,这些查询可能会遇到问题,解决办法:全局表:所有数据有一个总表或者总库。 字段冗余:降低部分查询做表关联的耦合性
分库分表方案产品:
基于代理方式的有MySQL Proxy和Amoeba,基于jdbc的sharding-jdbc,基于Hibernate的Hibernate Shards,基于mybatis的蘑菇街TSharding,通过重写spring的ibatis template类的Cobar Client。
还有一些大公司的开源产品:
因为分库分表后会带来一些问题,所以不建议这么做。
参考文献:
实时内容请关注微信公众号,公众号与博客同时更新:程序员星星