聊聊数据库分库分表策略

1. 为何分表

  当一张表的数据达到千万级时甚至亿级时,查询一次所花的时间会变多,如果有联合查询的话可能会死在那儿了。分表的目的就在于此,减小数据库的负担,缩短查询时间。

  • 大数据量并且访问频繁的表,将其分为若干个表:

  比如对于某些网站平台的数据库表,数据量很大,这种能预估出来的大数据量表,我们就事先分出个N个表,这个N是多少,根据实际情况而定。

  某网站现在的数据量假设是5000万条,可以设计每张表容纳的数据量是500万条,也就是拆分成10张表。

那么如何判断某张表的数据是否容量已满呢?可以在程序段对于要新增数据的表,在插入前先做统计表记录数量的操作,当<500万条数据,就直接插入,当已经到达阀值,可以在程序段新创建数据库表(自动扩容),再执行插入操作。

数据库架构

1.简单的数据库(PG/MySQL)主从复制:
数据库的主从复制解决了数据库的读写分离,(一主多备)能很好的提升读的性能,其图如下:
在这里插入图片描述

  • 但是,主从复制也带来其他一系列性能瓶颈问题:
    :---------:1.写入无法扩展
    :---------:2.写入无法缓存
    :---------:3.复制延时
    :---------:4.锁表率上升
    :---------:5.表变大,缓存率下降
  • 那问题产生总得解决的,这就产生下面的优化方案,一起来看看。
1、垂直分区

  如果把业务切割得足够独立,那把不同业务的数据放到不同的数据库服务器将是一个不错的方案,而且万一其中一个业务崩溃了也不会影响其他业务的正常进行,并且也起到了负载分流的作用,大大提升了数据库的吞吐能力。经过垂直分区后的数据库架构图如下:
在这里插入图片描述  然而,尽管业务之间已经足够独立了,但是有些业务之间或多或少总会有点联系,如用户,基本上都会和每个业务存在关联,况且这种分区方式,也不能解决单张表数据量暴涨的问题。

2、水平分区(Sharding)

  将用户按一定规则(按id哈希)分组,并把该组用户的数据存储到一个数据库分片中,即一个sharding,这样随着用户数量的增加,只要简单地配置一台服务器即可,原理图如下:
在这里插入图片描述
  如何来确定某个用户所在的shard呢,这个时候我们可以建一张用户和shard对应的数据表,每次请求先从这张表找用户的shard id,再从对应shard中查询相关数据,如下图所示:
在这里插入图片描述

  • 单库单表

  单库单表是最常见的数据库设计,例如,有一张用户(user)表放在数据库db中,所有的用户都可以在db库中的user表中查到

  • 单库多表

  随着用户数量的增加,user表的数据量会越来越大,当数据量达到一定程度的时候对user表的查询会渐渐的变慢,从而影响整个DB的性能。还有一个更严重的问题是,事务提交会锁表,期间所有的读写操作只能等待。

  • 一主多备

  在实际的应用中,大部分情况都是读远大于写。DB提供了读写分离的机制,所有的写操作都必须对应到Master,读操作可以在 Master和Slave机器上进行,Slave与Master的结构完全一样,一个Master可以有多个Slave,甚至Slave下还可以挂 Slave,通过此方式可以有效的提高DB集群的 QPS.

  所有的写操作都是先在Master上操作,然后同步更新到Slave上,所以从Master同步到Slave机器有一定的延迟,当系统很繁忙的时候,延迟问题会更加严重,Slave机器数量的增加也会使这个问题更加严重。

此外,可以看出Master是集群的瓶颈,当写操作过多,会严重影响到Master的稳定性,如果Master挂掉,整个集群都将不能正常工作。

2. 致谢

好了,到这里又到了跟大家说再见的时候了。我只是一个会写爬虫的段子手而已,一个希望有朝一日能够实现财富自由,能够早日荣归故里的游子罢了。希望我的文章能带给您知识,带给您帮助,带给您欢笑!同时也谢谢您能抽出宝贵的时间阅读,创作不易,如果您喜欢的话,点个赞再走吧。您的支持是我创作的动力,希望今后能带给大家更多优质的文章

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
相关推荐
©️2020 CSDN 皮肤主题: 点我我会动 设计师:白松林 返回首页
实付 29.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值