分库分表

一、数据库性能影响因素

  • 数据量

MySQL单库数据量在5000万以内性能比较好,超过阈值后性能会随着数据量的增大而变弱。MySQL单表的数据量是500w-1000w之间性能比较好,超过1000w性能也会下降(因为表数据为1000万时建立的索引如果是B+Tree类型的话一般树高在3~5之间,所以查询的速度自然也是很快速的)。

  • 磁盘、CPU、内存等机器性能

因为单个服务的磁盘空间是有限制的,如果并发压力下,所有的请求都访问同一个节点,肯定会对磁盘IO造成非常大的影响。

  • 数据库连接

数据库连接是非常稀少的资源,如果一个库里既有用户、商品、订单相关的数据,当海量用户同时操作时,数据库连接就很可能成为瓶颈(在高并发情况下,大量请求落入数据库,最终会导致数据库的活跃连接数增加,进而逼近甚至达到数据库可承载活跃连接数的阈值)。 

二、分库分表

综述:垂直拆分更偏向于业务拆分的过程,在技术上我们更倾向于水平切分的方案

2.1 分表

按照规则把一张表划分成多张表,使用时时根据规则找到对应数据,然后操作它。

  • 分表原因:单表数据量过大时,查询会很慢。(索引会很大,开销大;频繁读写,加锁操作密集)
  • 多张表还是在一台机器上。

2.1.1 水平分表——按行进行划分,横着切成多个表。

  • 方案1:按范围切分方式。可以根据某个字段的范围做划分,比如订单号字段,从0到10000一个表,10001到20000一个表。
    • 优点:扩容比较方便,因为如果ID范围不够了,只需要调整规则,然后建好新表即可。  
    • 缺点:无法解决热点问题,如果某一段数据访问QPS特别高,就会落到单表上进行操作。 
  • 方案2:HASH取模。可以根据某个字段的HASH取模做划分,建议是 2^n,这样可以方便在扩容的时尽可能的少迁移数据。比如将一个用户表分成8个子表,可以取用户id,然后hash后取8的模,从而分配到不同的数据库上。
    • 优点:数据散列均衡,每个表的数据量大致相同;请求压力散列均衡,不存在访问热点。
    • 缺点:扩容不方便,需要数据迁移。这种划分一旦确定后,就无法改变子表数量了。
  • 方案3:根据业务(地理/国籍/类型等)划分。比如按照华东,华南,华北这样来区分业务表,或者安卓用户,IOS用户等来区分用户表。
  • 方案4:按照时间切分,比如将6个月前,甚至一年前的数据切出去放到另外的一张表,因为随着时间流逝,这些表的数据被查询的概率变小,所以没必要和“热数据”放在一起,这个也是“冷热数据分离”。

2.1.2 垂直分表——按列进行划分,将不常用的属性列拆分出来。

  • 方案1:按活跃度划分。将“不常用”或者“数据量大”的字段拆分到“扩展表”上。这样避免查询时,数据量太大造成的“跨页”问题。

2.2 分库

将一个库分成多个库,并部署在多个服务器上。

  • 分库原因:单机的机器性能(磁盘IO瓶颈)有限,分库可以减小单机的压力、突破性能瓶颈。
2.2.1 水平分库
  • 将单个库中的表作水平分表,然后将子表分别置于不同的子库当中,独立部署。

  • 因为库中内容的主要载体是表,所以水平分库和水平分表基本上如影随形。

2.2.2 垂直分库
  • 以表为依据,按照业务归属不同,将不同的表拆分到不同的库中。

2.3 具体分库分表

首先考虑:数据量、并发量

  • 数据量大,就分表;
  • 并发高,就分库。

一般情况下,我们的方案都需要同时做分库分表,这时候分多少个库,多少张表,分别用预估的并发量和数据量来计算就可以了。

 

参考资料

https://zhuanlan.zhihu.com/p/342814592

posted @   zhegeMaw  阅读(19)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示