目录

一、为什么要分库分表

1、IO瓶颈

2、CPU瓶颈

二、分库分表的拆分方法

1.垂直拆分

1.1 数据库垂直拆分

1.2表垂直拆分

根据业务去拆分表,如把user表拆分成user_base表和user_info表,use_base负责存储登录,user_info负责存储基本用户信息

2. 水平拆分

2.1 数据库水平拆分

2.2表水平拆分

三、分库分表常用的思路

四、分库分表的工具

五、分库分表的步骤

六、分库分表带来的问题


一、为什么要分库分表

1、IO瓶颈

第一种:磁盘读IO瓶颈,热点数据太多,数据库缓存放不下,每次查询时会产生大量的IO,降低查询速度 -> 分库和垂直分表。

第二种:网络IO瓶颈,请求的数据太多,网络带宽不够 -> 分库。

2、CPU瓶颈

第一种:SQL问题,如SQL中包含join,group by,order by,非索引字段条件查询等,增加CPU运算的操作 -> SQL优化,建立合适的索引,在业务Service层进行业务计算。

第二种:单表数据量太大,查询时扫描的行太多,SQL效率低,CPU率先出现瓶颈 -> 水平分表。

二、分库分表的拆分方法

1.垂直拆分

1.1 数据库垂直拆分

根据业务拆分,如电商系统:拆分成订单库,会员库,商品库

1.2表垂直拆分

根据业务去拆分表,如把user表拆分成user_base表和user_info表,use_base负责存储登录,user_info负责存储基本用户信息

垂直拆分特点
1.每个库(表)的结构都不一样
2.每个库(表)的数据至少一列一样
3.每个库(表)的并集是全量数据

垂直拆分优缺点

优点:
1.拆分后业务清晰(专库专用按业务拆分)
2.数据维护简单,按业务不同,业务放到不同机器上

缺点:
1.如果单表的数据量,写读压力大
2.受某种业务决定,或者被限制,也就是说一个业务往往会影响到数据库的瓶颈(性能问题,如双十一抢购)
3.部分业务无法关联join,只能通过java程序接口去调用,提高了开发复杂度


2. 水平拆分

2.1 数据库水平拆分

按会员库拆分,拆分成会员1库,会员2库,以userId拆分,userId尾号0-5为1库
6-9为2库,还有其他方式,进行取模,偶数放到1库,奇数放到2库

2.2表水平拆分

如把users表拆分成users1表和users2表,以userId拆分,进行取模,偶数放到users1表,奇数放到users2表

水平拆分的其他方式

range来分,每个库一段连续的数据,这个一般是按比如时间范围来的,但是这种一般较少用,因为很容易产生热点问题,大量的流量都打在最新的数据上了,优点:扩容的时候,就很容易,因为你只要预备好,给每个月都准备一个库就可以了,到了一个新的月份的时候,自然而然,就会写新的库了 缺点:大部分的 请求,都是访问最新的数据。实际生产用range,要看场景,你的用户不是仅仅访问最新的数据,而是均匀的访问现在的数据以及历史的数据
hash分发,优点:可以平均分配每个库的数据量和请求压力 缺点:扩容起来比较麻烦,会有一个数据迁移的这么一个过程
水平拆分特点
1.每个库(表)的结构都一样
2.每个库(表)的数据都不一样
3.每个库(表)的并集是全量数据

水平拆分优缺点

优点:
1.单库/单表的数据保持在一定量(减少),有助于性能提高
2.提高了系统的稳定性和负载能力
3.拆分表的结构相同,程序改造较少。

缺点:
1.数据的扩容很有难度维护量大
2.拆分规则很难抽象出来
3.分片事务的一致性问题部分业务无法关联join,只能通过java程序接口去调用
 

三、分库分表常用的思路

1.hash取模方案
hash的方案就是对指定的路由key(通常为主键id)对分表总数进行取模。
优点:某个表不会出现热点问题(某个表被频繁访问,其他表访问较少的情况)
缺点:对于以后要扩容会比较麻烦,增加表的时候要对所有数据重新hash

2.range范围方案
简单来说就是1-1000万的数据放在1数据库并以此类推。**优点:**有利于将来扩容,有新数据就直接加入就好了
**缺点:**缺点也很明显,有可能出现热点问题。比如刚加进来的数据经常使用之类的问题


四、分库分表的工具

  • sharding-sphere:jar,前身是sharding-jdbc;
  • TDDL:jar,Taobao Distribute Data Layer;
  • Mycat:中间件。

五、分库分表的步骤

根据容量(当前容量和增长量)评估分库或分表个数 -> 选key(均匀)-> 分表规则(hash或range等)-> 执行(一般双写)-> 扩容问题(尽量减少数据的移动)。

六、分库分表带来的问题

  • 分布式事务
  • 跨库join查询
  • 分布式全局唯一id
  • 开发成本对程序员要求高