LAMP网站性能优化记

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介:

先说说背景:一个LAMP在线测试网站,日均PV1万左右,比赛时一小时就好几万吧。目前数据库大约有30万条记录。服务器配置很高。近期出现性能问题,当访问量增大的时候,数据库服务器的压力非常大,mysql的内存占用率通常能到400%,这时候基本不能提供服务了,连网站页面都打不开。理论上说现在的数据量还不算大,访问量也不是很大,服务器的配置也很高,出现这种状况是不正常的。这个问题究结了很久,昨天终于找到问题的原因了,记录一下,以后遇到类似的问题可以有个参考。先看一张图片,这是glances监控软件的截图,可以看到红色的496.6就是mysql的CPU占用率

  之前遇到这个问题,只能重启mysql服务,但这只是暂时的,重启之后不到1分钟CPU占用率接着就上来了,不是长久之计。

  然后考虑修改数据库和apache的配置文件,加大缓存空间,但效果还是不明显。

  后来又考虑是不是路由器的问题,因为目前是两台服务器通过一个小路由器连起来,组成一个小局域网,一个放apache(压力很小),另一个服务器放数据库(压力很大),交换数据都要先经过路由器。于是开始怀疑路由器的性能问题,干脆直接用一根网线把两个服务器连起来(服务器有两个网卡)。这样两个服务器就能直接通信了。事实证明,这样还是不能解决数据库压力大的问题。

  接下来,还是各种纠结,想过各种方法,比如换nginx,换其他数据库,弄个数据库集群什么的,都比较麻烦,还需要修改php代码,比较费劲,关键是php这东西看着就恶心……  

  有一天,我发现了memcached,memcached是一个缓存系统,这么说吧,假如有一个查询语句,很费时间,如果没有缓存的话,每次刷新页面就要访问数据库查询一次,这样数据库压力就比较大。 如果有缓存就不一样了,如果要查询的数据在缓存中存在的话,就直接从缓存中取出来,这样就不用去数据库查询了,如果访问量大的话可以明显减少数据库的查询次数,当然也减轻了数据库的压力。先贴一段没有缓存的代码:

$list = $statics->getFirstTenList();

下面是加上缓存的代码:

$list = null;
if (!($list = $cache->get('top_ten_list'))) {
    $list = $statics->getFirstTenList();
    $cache->set('top_ten_list', $list, 7200);
}

没有缓存的代码,每次都要调用查询函数从数据库获取数据。下面的有缓存的就不一样了。当需要查询一个数据之前,首先看看缓存里面有没有,就是代码中$cache->get(),如果从缓存取得了,就不用执行那条查询数据库的语句了。如果缓存服务器没有,就要从数据库里面查询,查询以后,用$cache->set()方法就刚才的查询结果保存到缓存服务器,并设置这个缓存存在的时间,这里是7200秒,7200秒之后,这个缓存就失效了,就要从新更新。还有一点比较重要,就是要给每一个缓存取一个名字,不同的缓存名字不能相同,缓存服务器是根据缓存的名字来区分缓存,如果名字相同的话,从缓存取出来的数据就不是我们需要的数据。举个例子来说:有两个比赛,比赛的排名页面做一个缓存,如果两个缓存名字都叫ranklist,首先刷新一下第一个比赛的排名页面,那么第一个比赛的排名数据就存在缓存服务器了。如果这时再刷新一下第二个比赛的排名页面,因为ranklist在缓存中存在,直接就从缓存中取出来了,但是取出来的数据并不是我们需要的,这种问题还是比较小的。如果是不同类型的数据,那么网站就乱了。

  缓存是个好东西,然后打算通过大量增加缓存来减轻服务器的压力。但后来我发现,这样也不行。因为我们的网站是一个在线测评系统,是一个实时动态的系统,一个用户提交一个答案以后,想立即看到评判结果,当答案正确的时候,要立即更新排名信息。如果增加缓存的话,从缓存中取出来的信息就不是最新的,不能显示实时的排名等信息。这就好比你订了一张票,但是系统好久才提示你订票成功,中间的等待时间是最难熬的。还有一个原因也限制了缓存的使用,就是对于大量的页面,比如说服务器上有2000个题,一个题一个页面,如果一个页面一个缓存的话肯定会降低缓存的性能。但是对于一些数据,长时间变动不大,比如说总做题数的排名,就可以考虑增加一个缓存,可以设置半天或者一天的生存时间,也就是半天或者一天更新一次。

  由于大量缓存并不适用与我们这种实时性很高的系统,因此我并没有增加很多缓存。数据库压力还是那么大。还是没找到问题的根源。

  找到一本mysql性能优化的书,然后就开始研究,首先想到的还是加索引,后来用show index from table_name来查看,发现里面已经对常用的查询词加索引了,我甚至开始考虑是不是因为索引太多加重了数据库的压力?经过一些测试(删除某些索引),发现还是不行,看来通过增加索引已经不能很好得解决OJ问题。

  后来发现了一个语句,是 show processlist,这条命令的作用是显示哪些线程正在执行,执行了多长时间,还有一些其他信息,看截图:

上面的图片是在负载不是很大的时候截的,从上图我们能看到有两条sql查询语句已经执行了7秒了,还有一个正在往临时表拷贝数据的操作。真正比赛的时候比这个问题严重多了!有几个sql语句执行时间超过10秒,总的sql查询语句个数有200多个,当然大部分线程是被阻塞的。 在这里我们就能很明显看出来到底是哪一条sql语句在浪费时间,接下来,我们就要找到底这条sql查询语句是从哪发起的,从php源吗中找这条语句,如果一条一条找就费劲了,这里我们用强大的grep命令来帮助我们查找。

很明显,这几条语句就在一个文件里面,让我们打开这个文件看看,下面是其中的一个函数,包含上面的查询语句

这个函数是从哪调用的?再找

 看到了吧,这里有八条类似的语句,这8条语句的作用是什么?其中第一条的作用是从30万的表里找到今天提交的并且AC的题目总数,第二条就是统计今天的提交总数,下面几条分别是统计这周,这月,这年的AC和提交总数。显示提交状态的solution表中目前大约有30万条信息,并且随时都会更新,只要有人提交就会插入新数据并更新一些数据。在数据库理论里面将,统计和插入更新是互相冲突的,这里就需要加锁,当执行查询语句的时候,将这个表锁住,防止其他数据更新而影响查询结果。也就是说,当执行上面的查询语句时,数据库里面的其他语句就被阻塞了,就被迫去sleep。在提交高峰期,数据库里面被阻塞的语句能达到200多条甚至更多,mysql的CPU占用率达到能达到500%,肯定不能对外提供服务了!

  接下来,我们要找找到底是在哪个页面里面有这个统计,哪个页面调用了这个函数,(强大的grep)

当看到上面的结果的时候,我的心凌乱了~~靠,怎么回事?这个多页面都有这个统计,然后打开页面文件找找,找到了

(上图是我修改之后的查询结果,大部分都被我用//注释掉了,原来是没有注释的~)

在一个不起眼的边栏里,我看到了上面的一个统计。我调查了一些用户,你们注意过这个统计信息吗?你们关注过这个统计信息吗?答案和我想的一样,没有!谁都不关注那这个统计还有什么意义?不知道当初设计者怎么想到的这个功能。当初数据量小的时候没有这个问题,随着数据量增加,问题就暴露出来了。就是这8个数字,拖慢了整个网站的速度!

  接下来解决方案也很清晰了,两种方法:1.删除这个统计,2.给这个统计增加缓存。综合各方面的意见,我决定只在总的排名页面保留这个统计,当然是要增加缓存的,6个小时更新一次。其他页面全部去掉!

  解决这个问题之后,再试试网站的访问速度,那叫一个快啊!泪奔啊!纠结了这么久的性能问题终于解决啦!orz


博主ma6174对本博客文章(除转载的)享有版权,未经许可不得用于商业用途。转载请注明出处http://www.cnblogs.com/ma6174/

对文章有啥看法或建议,可以评论或发电子邮件到ma6174@163.com


本文转自ma6174博客园博客,原文链接:http://www.cnblogs.com/ma6174/archive/2012/12/16/2818666.html,如需转载请自行联系原作者

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
7月前
|
关系型数据库 MySQL PHP
LAMP架构及搭建LAMP+Discuz论坛
LAMP架构及搭建LAMP+Discuz论坛
123 0
|
关系型数据库 MySQL Linux
LAMP及论坛搭建纯实操(一)
LAMP及论坛搭建纯实操(一)
100 0
LAMP及论坛搭建纯实操(一)
|
关系型数据库 MySQL 数据库
LAMP及论坛搭建纯实操(二)
LAMP及论坛搭建纯实操(二)
105 0
LAMP及论坛搭建纯实操(二)
|
缓存 关系型数据库 MySQL
LAMP及论坛搭建纯实操(三)
LAMP及论坛搭建纯实操(三)
99 0
LAMP及论坛搭建纯实操(三)
|
前端开发 关系型数据库 MySQL
前端架构一之XAMPP
前端架构一之XAMPP
|
关系型数据库 MySQL Apache
快速搭建LAMP环境--学习记录
快速搭建LAMP环境--学习记录
103 0
|
应用服务中间件 Linux nginx
一键安装服务器中的超跑Nginx!让网站性能起飞,不花冤枉钱!
学委之前写过 Docker玩腻了,不妨试试用Vagrant 和 Vagrant使用笔记
211 0
一键安装服务器中的超跑Nginx!让网站性能起飞,不花冤枉钱!
|
Web App开发 关系型数据库 应用服务中间件
LAMP网站架构方案分析
LAMP(Linux-Apache-MySQL-PHP)网站架构是目前国际流行的Web框架,该框架包括:Linux操作系统,Apache网络服务器,MySQL数据库,Perl、PHP或者Python编程语言,所有组成产品均是开源软件,是国际上成熟的架构框架,很多流行的商业应用都是采取这个架构,和Java/J2EE架构相比,LAMP具有Web资源丰富、轻量、快速开发等特点,微软的.NET架构相比,LAMP具有通用、跨平台、高性能、低价格的优势,因此LAMP无论是性能、质量还是价格都是企业搭建网站的首选平台。
3036 0
|
关系型数据库 Apache PHP