5000万pv小程序,高并发及缓存优化,入坑
小程序日均5000万的pv,超出想象,流量一路涨上来,服务器压力太大,各种宕机,不得不开始各种优化。
首先硬件的升级是必不可少,是革命的本钱,硬件升级如下
1 单机
2单机+云数据库
3单机+云数据库+6G的redis缓存
4五台服务器负载均衡 + 云数据库多台主从读写分离 + 16G的redis缓存
5十台服务器负载均衡 + 云数据库多台主从读写分离 + 32G的redis缓存
因为我们的小程序有很少图片文件,没有考虑CDN和oss文件存储
硬件不够用了就升级,不过可以一个月一个月的买,不然太贵了
下面的按一条一条的写,想到哪里写哪里。
1、分析瓶颈,小程序是兄弟公司的新手做的,不过效果还挺好,拿到我们这边来推广,没想到流量一路上涨。当流量多了以后,首先系统的瓶颈出现在数据库,查询很慢,看了看表,索引做的不好,甚至有些关键的地方都没有索引,赶紧加上索引。
数据库的压力刚缓解一会,服务器cpu的占用一直在90%以上,甚至出现宕机,分析了一下业务,我们的小程序主要是社交出题答题类的,并没有很高的计算需求,也就在最后用户生成分享图片的地方会有计算压力,果然在从单机扩展到负载均衡以后,服务器的cpu没有再出现过压力。从此压力主要围绕在数据的读和存这一块,也就是数据库和redis压力
2、redis是个好东西,每次能正确的缓存常用的数据,数据库的压力就能减轻很多。redis有两种缓存思想,一是针对数据库缓存,在用户写入数据的时候例如出题、答题,往数据库和redis中都写入,查询的时候先插redis的数据,没有的话从数据库中取;二是针对接口缓存,直接缓存接口返回的json数据,用户再次查相同的内容,直接返回json数据。我个人比较喜欢第二种缓存方式,简单高效,但要针对数据不怎么变化的接口,根据查询条件生成合理的redis key值,还要设置合理的过期时间,不然数据量太大。例如有一个接口是用户查询自己之前出的题及正确答案,因为自己出的题不可能再变,就根据他的这一套题的id进行缓存;
3、负载均衡,将流量分发到不同的服务器上进行处理,对cpu的压力大大减轻,但因为数据库的数据要共享,只能用云数据库,对数据库的帮助不明显
未完待续
4、小程序矩阵 社交类小程序免不了分享之类的操作,使用多个小程序部署,小程序之间使用unionid互通,减小微信突然抽风封你功能或小程序带来的损失
5、业务代码优化
6、数据库表结构问题
为了避免过多的join联合查询,可以采取以空间换时间的策略,例如用户的出题表,肯定会存用户的id,然后再根据id去用户表里查昵称,如果只是查昵称就不划算了,干脆在出题表里也存昵称,就不用去用户表里查询了,只是举个例子
7、前端提交数据过滤
前端数据过滤及验证,虽然并不能保证100%安全,但能大大的减少bug出现的风险和可能大大减少服务器的压力
8、上千万条记录甚至上亿记录的大表,不要使用limit分页查询,即使有索引,速度一定慢到怀疑人生,一般类似的需求,不如直接使用主键的区间,例如十万的区间按主键取数据,id 1~100000,100000~200000,以此类推,这样的取
9、开发时很多人都有喜欢到处记日志的习惯,问题这些日志隐藏在代码中,也不影响使用,但当访问量多起来,这些日志文件动辄就达到上G的大小,浪费磁盘空间和IO,要是只是错误日志也就罢了
10、各种手机设备的兼容性问题