数据库分库分表估计很多小伙伴都没有实践过,因为他们公司业务不多,没有那么多数据。如果有一天项目的人数增加了,你写的系统已经支撑不住了,希望这篇文章能给你一些思路。》前言面试过程中,你是否经常遇到数据库分库分表的方案?看博客的时候,你是不是经常看MySQL如何分库分表?但是,你点进去了吗?退出看了不到10秒就直接跳出这个窗口,那是因为你写的文章不是横的就是竖的,你所在的公司没有用过,如果你只知道分库分表不知道如果你去做的话,花五分钟看完你会有不同的想法1.公司初期结构小,项目针对的用户群体很小,日活跃用户数据只有几千或者上万,数据库单表的增加一般不会超过10万,并发更无所谓,对于这种规模的项目,我们认真快速的开发业务逻辑,提升用户体验,从而增加用户粘性项目并准备容纳更多用户。这时候我们项目一个16核32G的服务器就完全没问题了。数据库可以放在单独的服务器上,也可以全部放在一台服务器上。这时的项目架构图是这样的。二是用户开始激增。解决方案在经历了第一阶段后,由于项目的用户体验度高,项目吸引了大量的用户。此时,我们项目的日活跃度已经达到了百万级别,注册用户已经突破了千万。该数据是根据以往公司项目数据计算得出的。此时单表新增数据达到100万条/天,并发请求数达到每秒数万条。这个时候,单一的系统是应付不了的。假设每天新增100万条数据,那么每月就是3000条。万条,一年近5亿条数据。数据库以这个速度运行,数据勉强能撑到2000W到3000W,但是你会发现数据库日志中会出现越来越慢的查询。虽然并发1W,但是我们可以部署10台机器或者20台机器,平均每台机器可以处理500到1000个请求,绰绰有余。但是数据库还是用一台服务器来支持每秒几万个请求,那么你就会遇到下面的问题。数据库所在服务器的磁盘IO、网络带宽、CPU负载、内存消耗都会非常高。这时候最明显的感受就是SQL性能变差了,就是用户获取一条数据可能要10秒以上才返回。如果前期服务器配置不是很高,就会面临数据库宕机的情况,那么这个时候我们该如何优化项目的结构呢!根据大佬们的经验,数据库连接数可以控制在2000个/秒。然后我们部署5台1W并发的机器,每台机器部署一个相同结构的数据库。此时,五个数据库有同一个数据库。表名规则可以这样设置。这时,每个项目库都有同一张表。比如db_project1有tb_play_recode1,db_project2有tb_play_recode2……这样就实现了一个分库分表的基本思路,从原来的数据库服务器变成了五台数据库服务器,从一个数据库变成了五个数据库,一个桌子变成了五张桌子。这时候就需要使用数据库中间件来完成写入数据,比如mycat。这时候就需要用回放记录表的自增ID进行取模5,比如每天向回放记录增加100W的数据。此时20W数据会落入db_project1的db_play_recode1,其他四个库也分别落入20W数据。查询数据时,根据播放记录的自增ID取模5,然后到对应的数据库中,从对应的表中查询数据。实现了这个架构之后,我们来分析一下。本来回放记录只有一张表,现在有五张表,每张表变成1/5。按照原项目计算,如果一年有1亿条数据,那么每张表只有2000万条数据。按照每天增加50W的数据,每个表每天增加10W的数据。这是否初步缓解了单表数据量过大影响系统性能的问题?另外,对于每秒1W的请求,此时每台服务器平均有2000个请求,瞬间将并发请求降低到安全范围内。3.保证查询性能上面的数据库架构会遇到一个问题,就是单表的数据量还是很大的。按照每年1亿的数据,单表就有2000万的数据,还是太大了。比如播放记录表可以拆分成100张表,然后分布到5台数据库服务器。此时单表数据只有100W,查询还是不够用!写入数据时,需要经过两条路由。首先,数据库的数量以回放记录ID为模。这时候可以路由到一个数据库,然后那个数据库上的表数取模,最后路由到数据上的A表。通过这一步,每个表的数据都可以很小。按照100张表,1亿条数据,落入每张表的数据只有100W。此时的系统架构是这样的。4、配置读写分离,按需扩容。上面架构的整体效果已经很不错了。假设以上100张表仍然不能满足需求,可以通过用户增量计算配置合理的表。同时也可以保证单表SQL执行的效率。这时候,又会出现一个问题。如果每台服务器每秒承载2000个请求,则其中400个是写入,1600个是查询。也就是说增删改查中只有20%的SQL是增删改查,80%的请求是查询。安装前的推理,现在所有数据都翻倍了,每台服务器都达到了4000个并发请求。那么800个请求是写,3200个请求是查询。如果我们安装现状来扩容,只需要增加一个数据库服务器即可。但是会涉及到表的迁移,因为把一些表迁移到新的数据库中是很麻烦的。其实,这是没有必要的。可以使用读写分离来解决这个问题,也就是主从复制。写的时候去主库,读数据的时候去从库,这样就可以在不同的数据库上分别执行一张表的读写请求。经过这样的设计,我们算一下,如果写主库的请求是400/s,查询从库的请求是1800/s,那么主库下只需要配置两个从库即可。此时的结构如下。在实际生产环境中,读请求的增长速度远高于写请求。因此,读写分离后,大部分从库都需要进行扩容,以支持更高的读请求。还有一点,对于同一张表,如果既写数据又读数据,可能会涉及到锁冲突,从而影响读写性能。所以一旦读写分离,主库中的表只是写入,任何查询都不会影响到主库。对于从库来说,只是查询而已。五、并发数据库结构总结针对并发场景,需要精心设计数据库级架构。而且在配置主复制的时候,会有很多问题等待解决。这篇文章就是从大的角度为大家梳理一个思路。你可以根据你公司的业务和项目,考虑如何把你的系统分库分表。分库分表的实现需要借助mycat或者其他数据库中间件来实现。更多学习内容,可访问【与各大厂商对比】优质PHP架构师教程目录。只要能读懂,就能保证你的薪水更上一层楼(持续更新中)。以上内容希望对大家有所帮助。很多PHPer总会遇到一些问题和瓶颈,业务代码写多了没有方向感,不知道从哪里开始改进,我整理了一些这方面的资料,包括但不限于:分布式架构,高可扩展性、高性能、高并发、服务器性能调优、TP6、laravel、YII2、Redis、Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等知识点免费分享给你如果你需要高级干货。有需要的可以点击链接领取高级PHP月薪30k>>>架构师成长之路【免费获取视频和面试资料】
