有了主从数据库为啥还需要分库分表
如果一个网站业务快速发展,那这个网站流量也会增加,数据的压力也会随之而来,比如电商系统来说双十一大促对订单数据压力很大,Tps十几万并发量,如果传统的架构(一主多从),主库容量肯定无法满足这么高的Tps,业务越来越大,单表数据超出了数据库支持的容量,持久化磁盘IO,传统的数据库性能瓶颈,产品经理业务·必须做,改变程序,数据库刀子切分优化。数据库连接数不够需要分库,表的数据量大,优化后查询性能还是很低,需要分。当单表的数据量达到1000W或100G以后,由于查询维度较多,即使添加从库、优化索引,做很多操作时性能仍下降严重。此时就要考虑对其进行切分了,切分的目的就在于减少数据库的负担,缩短查询时间。
分库:将一个库的数据拆分到多个相同的库中,访问的时候访问一个库
分表:把一个表的数据放到多个表中,操作对应的某个表就行
有垂直拆分和水平拆分两种
垂直拆分特点
每个库(表)的结构都不一样
每个库(表)的数据至少一列一样
每个库(表)的并集是全量数据
优点:
拆分后业务清晰(专库专用按业务拆分)
数据维护简单,按业务不同,业务放到不同机器上
通过"大表拆小表",更便于开发与维护,也能避免跨页问题,MySQL底层是通过数据页存储的,一条记录占用空间过大会导 致跨页,造成额外的性能开销。另外数据库以行为单位将数据加载到内存中,这样表中字段长度较短且访问频率较高,内存能加载更多的数据,命中率更高,减少了 磁盘IO,从而提升了数据库性能。
缺点:
如果单表的数据量过大,写读压力大
受某种业务决定,或者被限制,也就是说一个业务往往会影响到数据库的瓶颈(性能问题,如双十一抢购)
部分业务无法关联join,只能通过java程序接口去调用,提高了开发复杂度
按会员库拆分,拆分成会员1库,会员2库,以userId拆分,userId尾号0-5为1库
6-9为2库,还有其他方式,进行取模,偶数放到1库,奇数放到2库
水平拆分的其他方式
range来分,每个库一段连续的数据,这个一般是按比如时间范围来的,但是这种一般较少用,因为很容易产生热点问题,大量的流量都打在最新的数据上了,优点:扩容的时候,就很容易,因为你只要预备好,给每个月都准备一个库就可以了,到了一个新的月份的时候,自然而然,就会写新的库了 缺点:大部分的 请求,都是访问最新的数据。实际生产用range,要看场景,你的用户不是仅仅访问最新的数据,而是均匀的访问现在的数据以及历史的数据
hash分发,优点:可以平均分配每个库的数据量和请求压力 缺点:扩容起来比较麻烦,会有一个数据迁移的这么一个过程
一致性哈希:形成环状,避免大面积击穿
优点
单库/单表的数据保持在一定量(减少),有助于性能提高
提高了系统的稳定性和负载能力
拆分表的结构相同,程序改造较少。
缺点:
数据的扩容很有难度维护量大
拆分规则很难抽象出来
分片事务的一致性问题部分业务无法关联join,只能通过java程序接口去调用
不到万不得已不用轻易使用分库分表这个大招,避免**“过度设计"和"过早优化”。分库分表之前,不要为分而分,先尽力去做力所能及的事情,例如:升级硬件、升级网络、读写分离、索引优化等等。当数据量达到单表的瓶颈时候,再考虑分库分表。
在业务层面上垂直切分**,将不相关的业务的数据库分隔,因为每个业务的数据量、访问量都不同,不能因为一个业务把数 据库搞挂而牵连到其他业务。利用水平切分,当一个数据库出现问题时,不会影响到100%的用户,每个库只承担业务的一部分数据,这样整体的可用性就能提 高。