水平分库分表
水平分库
当数据库中单表的数据量很大时,采用水平分区的方式对数据进行拆分(将同一个表中不同的数据拆分到不同数据库中)。比如,以对某个主键进行hash取模的方式(以保证对N个数据库的访问负载是均衡的),将数据分布表到N个数据库中。
值得一提的是,进行分库分表后,进行对跨库的表join、事务操作或者数据统计、排序时,又出现了新的性能问题。
使用原因
大部分互联网业务数据量很大,单库容量容易成为瓶颈,如果希望:
- 线性降低单库数据容量
- 线性提升数据库写性能
此时可以使用水平切分架构。
一句话总结,水平切分主要解决“数据库数据量大”问题,在数据库容量扛不住的时候,通常水平切分。
水平分表
水平分表也称为横向分表,比较容易理解,就是将表中不同的数据行按照一定规律分布到不同的数据库表中(这些表保存在同一个数据库中),这样来降低单表数据量,优化查询性能。最常见的方式就是通过主键或者时间等字段进行 Hash 和取模后拆分。
切分策略
1 查询切分
将ID和库的Mapping关系记录在一个单独的库中。
优点:ID和库的Mapping算法可以随意更改。
缺点:引入额外的单点。
2 范围切分
比如按照时间区间或ID区间来切分。
优点:单表大小可控,天然水平扩展。
缺点:无法解决集中写入瓶颈的问题。
3 Hash切分
一般采用Mod来切分,下面着重讲一下Mod的策略。
数据水平切分后我们希望是一劳永逸或者是易于水平扩展的,所以推荐采用mod2n这种一致性Hash。
以统一订单库为例,我们分库分表的方案是32*32的,即通过UserId后四位mod 32分到32个库中,同时再将UserId后四位Div 32 Mod 32将每个库分为32个表,共计分为1024张表。线上部署情况为8个集群(主从),每个集群4个库。
垂直分表分库
垂直分表
典型的应用场景是在文章列表这样的场景,一般来讲,我们的文章表会有title、userId、Content等字段,其中的Content字段一般是Text或者LongText类型,而其它的字段都是固定长度的数据类型。我们知道一个数据库优化规则是:
- 如果一个表的所有字段都是固定长度类型的,那么它就是定长表,定长表比动态长度表查询性能要高
- 那么,我们就可以使用垂直分表来将文章表分成文章表和文章内容表。于是文章列表页面所需的查询,就只需要查询一张定长表了。
或者,某个表中的字段比较多,可以新建立一张“扩展表”,将不经常使用或者长度较大的字段拆分出去放到“扩展表”中。
垂直分库
垂直分库针对的是一个系统中的不同业务进行拆分,比如用户User一个库,商品Producet一个库,订单Order一个库。 切分后,要放在多个服务器上,而不是一个服务器上。为什么?
我们想象一下,一个购物网站对外提供服务,会有用户,商品,订单等的CRUD。没拆分之前, 全部都是落到单一的库上的,这会让数据库的单库处理能力成为瓶颈。按垂直分库后,如果还是放在一个数据库服务器上, 随着用户量增大,这会让单个数据库的处理能力成为瓶颈,还有单个服务器的磁盘空间,内存,tps等非常吃紧。 所以我们要拆分到多个服务器上,这样上面的问题都解决了,以后也不会面对单机资源问题。
数据库业务层面的拆分,和服务的“治理”,“降级”机制类似,也能对不同业务的数据分别的进行管理,维护,监控,扩展等。 数据库往往最容易成为应用系统的瓶颈,而数据库本身属于“有状态”的,相对于Web和应用服务器来讲,是比较难实现“横向扩展”的。 数据库的连接资源比较宝贵且单机处理能力也有限,在高并发场景下,垂直分库一定程度上能够突破IO、连接数及单机硬件资源的瓶颈。
分库分表中间件
- cobar
- TDDL
- atlas
- sharding-jdbc
- mycat
Reference
- 数据库读写分离架构,为什么我不喜欢 - http://www.10tiao.com/html/249/201801/2651960806/1.html
- MySQL读写分离最佳实践 - https://www.jianshu.com/p/1ac435a6510e
- 分库分表的几种常见形式以及可能遇到的难 - https://www.infoq.cn/article/key-steps-and-likely-problems-of-split-table
- 大众点评订单系统分库分表实践 - https://tech.meituan.com/2016/11/18/dianping-order-db-sharding.html
- MySQL 分库分表方案,总结的非常好! - https://juejin.im/entry/5b5eb7f2e51d4519700f7d3c
- 表的垂直拆分和水平拆分 - https://www.kancloud.cn/thinkphp/mysql-design-optimalize/39326
- 基于MySQL数据库下亿级数据的分库分表 - https://zhuanlan.zhihu.com/p/54594681?utm_source=wechat_session&utm_medium=social&utm_oi=559493336751333376&from=singlemessage&isappinstalled=0