分库|分表|分区|分片的最全指南

读压力大时读写分离、一主多备
写压力大时分库分表
IO瓶颈分库和垂直分表
CPU瓶颈SQL优化和水平分表
分库分库:当一个库中的表过多(单机容量不够),访问量太大(单个实例无法支持)时候,可以分库
水平分库:一般是在垂直拆分后进行;将存储的同张表的数据划分到不同的库中(压力分摊到不同的库,如:订单、用户);问题:数据路由
垂直分库:将系统中不存关联关系或不同业务的数据放在不同库中;一定程度能突破IO、连接数及单机硬件资源的瓶颈;问题:跨数据库的事务,join查询等问题
分库后的问题:分布式事务、跨库join、排序|分页|分组
分表分表:把一张表按一定的规则分解成N个具有独立存储空间的实体表。分为水平分表和垂直分表。
分区

分区:将表的数据均衡分摊到不同的硬盘,系统或是不同服务器存储介质中。(重点突破硬盘瓶颈)
分区只是一张表中的数据的存储位置发生改变,是逻辑层面进行了水平分割,对于应用程序来说,它仍是一张表。
水平分区:通过某个属性列来分割。eg:一个包含十年发票记录的表可以被分区为十个不同的分区,每个分区包含的是其中一年的记录

垂直分区: ?????

分表 & 分区:

区别:(分区提高读写,分表提高并发)分区重点是如何突破磁盘的读写能力,分表重点是存取数据时如何提高mysql并发。

当访问量大,且表数据比较大时,两种方式可以互相配合使用。
分区分表策略:a.Range(范围)  b.Hash(哈希)  c.按照时间拆分  d.Hash之后按照分表个数取模
e.在认证库中保存数据库配置(建立一个DB,这个DB单独保存user_id到DB的映射关系)

分片数据分片:
(1)确定数据在多台存储设备上分布的技术:数据分布均匀,访问负载均衡,扩缩容数据迁移少。
(2)将数据集划分成相互独立、正交的数据子集,然后将数据子集分布到不同的节点上。
分片方式:
(1)使用Key或Key的哈希值来计算Key的分布
(2)划分号段:缺点是数据可能分布不均匀、数据热度不同导致各个设备的负载不均衡,扩容也不够灵活,只能成倍地增加设备
(3)取模:Hash(Key)%N就可以确定数据所在的设备编号。缺点:扩容的时候,会产生大量的数据迁移
(4)检索表:在检索表中存储Key和设备的映射关系。缺点:需要存储检索表的空间可能比较大
(5)一致性哈希的算法: 简单而巧妙,很容易做到数据均分布,其单调性也保证了扩缩容的数据迁移是比较少的。

目录

一、数据库瓶颈

1、IO瓶颈---分库和垂直分表

 2、CPU瓶颈---SQL优化和水平分表

二、什么时候分库分表?

三、分库分表

1、水平分库和水平分表

2、垂直分库和垂直分表

(1)垂直分库

(2)垂直分表

四、分库分表的工具和步骤

1、分库分表的工具---mycat

 2、分库分表步骤

 五、分库分表问题

5.1、非partition key的查询问题

 5.1.1、端上除了partition key只有一个非partition key作为条件查询

5.1.2、端上除了partition key不止一个非partition key作为条件查询

5.1.3、后台除了partition key还有各种非partition key组合条件查询

5.2、非partition key跨库跨表分页查询问题---ES

5.3、扩容问题

六、分库分表总结

七、分库分表示例

一、数据库瓶颈

1、IO瓶颈---分库和垂直分表

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

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

 2、CPU瓶颈---SQL优化和水平分表

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

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

二、什么时候分库分表?

 经测试在单表1000万条记录一下,写入读取性能是比较好的。再留点buffer,那么单表全是数据字型的保持在800万条记录以下, 有字符型的单表保持在500万以下。如果按100库100表来规划,如用户业务:500万 x 100 x 100 = 5000000万 = 500亿记录。

三、分库分表

1、水平分库和水平分表

(1)划分:以字段为依据,按照一定策略(hash、range等),将一个库/表中的数据拆分到多个库/表中。
(2)使用场景:库多了,io和cpu的压力自然可以成倍缓解;单表数据量少了,单次SQL执行效率高,减轻了CPU的负担。

2、垂直分库和垂直分表

(1)垂直分库

划分:以表为依据,按照业务归属不同,将不同的表拆分到不同的库中。
使用场景:公用的配置表、字典表等越来越多,这时可以将这些表拆到单独的库中,甚至可以服务化。

(2)垂直分表

划分:以字段为依据,按照字段的活跃性,将表中字段拆到不同的表(主表和扩展表)中。
使用场景:将热点数据(可能会冗余经常一起查询的数据)放在一起作为主表,非热点数据放在一起作为扩展表。减少了随机读IO;注意分表后,要想获得全部数据就需要关联两个表来取数据,记住千万别用join,因为join不仅会增加CPU负担并且会讲两个表耦合在一起(必须在一个数据库实例上)。关联数据,应该在业务Service层做文章,分别获取主表和扩展表数据然后用关联字段关联得到全部数据。

四、分库分表的工具和步骤

1、分库分表的工具---mycat

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

 2、分库分表步骤

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

 

 五、分库分表问题

5.1、非partition key的查询问题

基于**水平分库分表**,拆分策略为常用的**hash法**。

 5.1.1、端上除了partition key只有一个非partition key作为条件查询

(1)映射法
(2)基因法
注:写入时,基因法生成user_id,如图。关于xbit基因,例如要分8张表,23=8,故x取3,即3bit基因。根据user_id查询时可直接取模路由到对应的分库或分表。根据user_name查询时,先通过user_name_code生成函数生成user_name_code再对其取模路由到对应的分库或分表。id生成常用snowflake算法。

5.1.2、端上除了partition key不止一个非partition key作为条件查询

映射法
冗余法
注:按照order_id或buyer_id查询时路由到db_o_buyer库中,按照seller_id查询时路由到db_o_seller库中。

5.1.3、后台除了partition key还有各种非partition key组合条件查询

NoSQL法
冗余法

5.2、非partition key跨库跨表分页查询问题---ES

基于水平分库分表,拆分策略为常用的hash法。解决方法是用NoSQL法解决(ES等)。

5.3、扩容问题

基于水平分库分表,拆分策略为常用的hash法。
水平扩容库(升级从库法),注:扩容是成倍的。

水平扩容表(双写迁移法)
第一步:(同步双写)修改应用配置和代码,加上双写,部署;第二步:(同步双写)将老库中的老数据复制到新库中;第三步:(同步双写)以老库为准校对新库中的老数据;第四步:(同步双写)修改应用配置和代码,去掉双写,部署;注:双写是通用方案。

六、分库分表总结

分库分表,首先得知道瓶颈在哪里,然后才能合理地拆分(分库还是分表?水平还是垂直?分几个?)。且不可为了分库分表而拆分。
选key很重要,既要考虑到拆分均匀,也要考虑到非partition key的查询。
只要能满足需求,拆分规则越简单越好。

七、分库分表示例

[分库分表的git示例](https://link.zhihu.com/?target=https://github.com/littlecharacter4s/study-sharding)

 [1]: https://zhuanlan.zhihu.com/p/137368446

转自:[分库分表方案](https://zhuanlan.zhihu.com/p/137368446)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值