系统性能调优LAMP架构.docx
《系统性能调优LAMP架构.docx》由会员分享,可在线阅读,更多相关《系统性能调优LAMP架构.docx(12页珍藏版)》请在冰豆网上搜索。
系统性能调优LAMP架构
现在,使用LAMP(Linux®、Apache、MySQL和PHP/Perl)架构的应用程序不断被开发和部署。
但是,服务器管理员对应用程序本身几乎没有控制能力,因为应用程序是别人编写的。
这份共三部分的系列文章将讨论许多服务器配置问题,这些配置会影响应用程序的性能。
第一篇文章讨论LAMP架构、一些性能度量技术以及一些基本的Linux内核、硬盘和文件系统调节。
后续的文章将研究Apache、MySQL和PHP组件的调优。
本文大纲:
LAMP架构、优化Apache和PHP、MySQL的调优
Linux、Apache、MySQL和PHP(或Perl)是许多Web应用程序的基础——从to-do列表到blog,再到电子商务站点。
WordPress和Pligg是两个支持大容量Web站点的常用软件包。
这种架构简称为LAMP。
几乎每个Linux发布版都包含Apache、MySQL、PHP和Perl,所以安装LAMP软件是非常容易的。
安装的简便性使人误以为这些软件会自行顺利地运行,但是实际情况并非如此。
最终,应用程序的负载会超出后端服务器自带设置的处理能力,应用程序的性能会降低。
LAMP安装需要不断监控、调优和评估。
系统调优对于不同的人有不同的含义。
本系列主要关注LAMP组件(Linux、Apache、MySQL和PHP)的调优。
对应用程序本身进行调优是另一个复杂的问题。
应用程序和后端服务器之间存在一种共生关系:
未能适当调优的服务器甚至会使最好的应用程序在负载之下崩溃,而借助充分的调优,完全可以避免编写得很糟糕的应用程序使服务器缓慢如牛。
幸运的是,正确的系统调优和监视可以指出应用程序中的问题。
系统性能调优,第1部分:
理解LAMP架构
LAMP架构
对任何系统调优的第一步都是了解它的工作原理。
按照最简单的形式,基于LAMP的应用程序是用PHP这样的脚本语言编写的,它们作为Linux主机上运行的ApacheWeb服务器的一部分运行。
PHP应用程序通过请求的URL、所有表单数据和已捕获的任意会话信息从客户机获得信息,从而确定应该执行什么操作。
如有必要,服务器会从MySQL数据库(也在Linux上运行)获得信息,将这些信息与一些HypertextMarkupLanguage(HTML)模板组合在一起,并将结果返回给客户机。
当用户在应用程序中导航时,这个过程重复进行;当多个用户访问系统时,这个过程会并发进行。
但是,数据流不是单向的,因为可以用来自用户的信息更新数据库,包括会话数据、统计数据(包括投票)和用户提交的内容(比如评论或站点更新)。
除了动态元素之外,还有静态元素,比如图像、JavaScript代码和层叠样式表(CSS)。
在研究LAMP系统中的请求流之后,就来看看可能出现性能瓶颈的地方。
数据库提供许多动态信息,所以数据库对查询的响应延迟都会反映在客户机中。
Web服务器必须能够快速地执行脚本,还要能够处理多个并发请求。
最后,底层操作系统必须处于良好的状态才能支持应用程序。
通过网络在不同服务器之间共享文件的其他设置也可能成为瓶颈。
度量性能
持续地对性能进行度量在两个方面有帮助。
首先,度量可以帮助了解性能趋势,包括好坏两方面的趋势。
作为一个简单的方法,查看一下Web服务器上的中央处理单元(CPU)使用率,就可以了解CPU是否负载过重。
同样,查看过去使用的总带宽并推断未来的变化,可以帮助判断什么时候需要进行网络升级。
这些度量最好与其他度量和观测结合考虑。
例如,当用户抱怨应用程序太慢时,可以检查磁盘操作是否达到了最大容量。
性能度量的第二个用途是,判断调优是对系统性能有帮助,还是使它更糟糕了。
方法是比较修改之前和之后的度量结果。
但是,为了进行有效的比较,每次应该只修改一个设置,然后对适当的指标进行比较以判断修改的效果。
每次只修改一个设置的原因应该是很明显的:
同时做出的两个修改很可能会相互影响。
选择用来进行比较的指标比较微妙。
选择的指标必须能够反映应用程序用户感觉到的响应。
如果一项修改的目标是减少数据库的内存占用量,那么取消各种缓冲区肯定会有帮助,但是这会牺牲查询速度和应用程序性能。
所以,应该选择应用程序响应时间这样的指标,这会使调优向着正确的方向发展,而不仅仅是针对数据库内存使用量。
可以以许多方式度量应用程序响应时间。
最简单的方法可能是使用curl命令,见清单1。
清单1.使用cURL度量Web站点的响应时间
1.$ curl -o /dev/null -s -w %{time_connect}:
%{time_starttransfer}:
%{time_total}\ 0.081:
0.272:
0.779
2.
清单1给出对一个流行的新闻站点执行curl命令的情况。
输出通常是HTML代码,通过-o参数发送到/dev/null。
-s参数去掉所有状态信息。
-w参数让curl写出表1列出的计时器的状态信息:
表1.curl使用的计时器
计时器描述
time_connect建立到服务器的TCP连接所用的时间
time_starttransfer在发出请求之后,Web服务器返回数据的第一个字节所用的时间
time_total完成请求所用的时间
这些计时器都相对于事务的起始时间,甚至要先于DomainNameService(DNS)查询。
因此,在发出请求之后,Web服务器处理请求并开始发回数据所用的时间是0.272-0.081=0.191秒。
客户机从服务器下载数据所用的时间是0.779-0.272=0.507秒。
通过观察curl数据及其随时间变化的趋势,可以很好地了解站点对用户的响应性。
当然,Web站点不仅仅由页面组成。
它还有图像、JavaScript代码、CSS和cookie要处理。
curl很适合了解单一元素的响应时间,但是有时候需要了解整个页面的装载速度。
用于Firefox浏览器的TamperData扩展(参见参考资料一节中的链接)可以在日志中记录Web浏览器发出的每个请求,并显示每个请求所用的下载时间。
使用这个扩展的方法是,选择Tools>TamperData来打开Ongoingrequests窗口。
装载要考察的页面,然后就会看到浏览器发出的每个请求的状态和装载每个元素所用的时间。
图1给出装载developerWorks主页的结果。
图1.用于装载developerWorks主页的请求细目
每一行描述一个元素的装载情况。
显示的数据包括发出请求的时间、装载所用的时间、大小和结果。
Duration栏列出装载元素本身所用的时间,TotalDuration栏列出所有子元素所用的时间。
在图1中,装载主要页面所用的时间是516毫秒(ms),但是装载所有东西并显示整个页面所用的时间是5101ms。
TamperData扩展有一种有用的模式,将页面装载数据的输出绘制成图形。
右击Ongoingrequests窗口上半部分的任何地方,并选择Graphall。
图2显示图1中数据的图形化视图。
图2.用于装载developerWorks主页的请求的图形化视图
在图2中,每个请求的持续时间显示为深蓝色,并相对于页面装载的启始时间显示。
所以,可以看出哪些请求使整个页面的装载变慢了。
尽管关注的重点是页面装载时间和用户体验,但是也不要忽视核心系统指标,比如磁盘、内存和网络。
有许多实用程序可以捕获这些信息;其中最有帮助的可能是sar、vmstat和iostat。
基本系统调节
在对系统的Apache、PHP和MySQL组件进行调优之前,应该花一些时间确保底层Linux组件的运行正常。
还应该对正在运行的服务进行缩减,只运行需要的那些服务。
这不但是一种良好的安全实践,而且可以节省内存和CPU时间。
内核调优措施
大多数Linux发布版都定义了适当的缓冲区和其他TransmissionControlProtocol(TCP)参数。
可以修改这些参数来分配更多的内存,从而改进网络性能。
设置内核参数的方法是通过proc接口,也就是通过读写/proc中的值。
幸运的是,sysctl可以读取/etc/sysctl.conf中的值并根据需要填充/proc,这样就能够更轻松地管理这些参数。
清单2展示在互联网服务器上应用于Internet服务器的一些比较激进的网络设置。
清单2.包含较为激进的网络设置的/etc/sysctl.conf
1.# Use TCP syncookies when needednet.ipv4.tcp_syncookies = 1# Enable TCP window scalingnet.ipv4.tcp_window_scaling:
= 1# Increase TCP max buffer sizenet.core.rmem_max = 16777216net.core.wmem_max = 16777216# Increase Linux autotuning TCP buffer limitsnet.ipv4.tcp_rmem = 4096 87380 16777216 net.ipv4.tcp_wmem = 4096 65536 16777216# Increase number of ports availablenet.ipv4.ip_local_port_range = 1024 65000
2.
将这些设置添加到/etc/sysctl.conf的现有内容中。
第一个设置启用TCPSYNcookie。
当从客户机发来新的TCP连接时,数据包设置了SYN位,服务器就为这个半开的连接创建一个条目,并用一个SYN-ACK数据包进行响应。
在正常操作中,远程客户机用一个ACK数据包进行响应,这会使半开的连接转换为全开的。
有一种称为SYN泛滥(SYNflood)的网络攻击,它使ACK数据包无法返回,导致服务器用光内存空间,无法处理到来的连接。
SYNcookie特性可以识别出这种情况,并使用一种优雅的方法保留队列中的空间(细节参见参考资料一节)。
大多数系统都默认启用这个特性,但是确保配置这个特性更可靠。
启用TCP窗口伸缩使客户机能够以更高的速度下载数据。
TCP允许在未从远程端收到确认的情况下发送多个数据包,默认设置是最多64KB,在与延迟比较大的远程客户机进行通信时这个设置可能不够。
窗口伸缩会在头中启用更多的位,从而增加窗口大小。
后面四个配置项增加TCP发送和接收缓冲区。
这使应用程序可以更快地丢掉它的数据,从而为另一个请求服务。
还可以强化远程客户机在服务器繁忙时发送数据的能力。
最后一个配置项增加可用的本地端口数量,这样就增加了可以同时服务的最大连接数量。
在下一次引导系统时,或者下一次运行sysctl-p/etc/sysctl.conf时,这些设置就会生效。
配置磁盘来提高性能
磁盘在LAMP架构中扮演着重要的角色。
静态文件、模板和代码都来自磁盘,组成数据库的数据表和索引也来自磁盘。
对磁盘的许多调优(尤其是对于数据库)集中于避免磁盘访问,因为磁盘访问的延迟相当高。
因此,花一些时间对磁盘硬件进行优化是有意义的。
首先要做的是,确保在文件系统上禁用atime日志记录特性。
atime是最近访问文件的时间,每当访问文件时,底层文件系统必须记录这个时间戳。
因为系统管理员很少使用atime,禁用它可以减少磁盘访问时间。
禁用这个特性的方法是,在/etc/fstab的第四列中添加noatime选项。
清单3给出了一个配置示例。
清单3.演示如何启用noatime的fstab示例
1./dev/VolGroup00/LogVol00 / ext3 defaults,noatime 1 1LABEL=/boot /boot ext3 defaults,noatime 1 2devpts /dev/pts devpts gid=5,mode=620 0 0tmpfs /dev/shm tmpfs defaults 0 0proc /proc proc defaults 0 0sysfs /sys sysfs defaults 0 0LABEL=SWAP-hdb2 swap swap defaults 0 0LABEL=SWAP-hda3 swap swap defaults 0 0
2.
在清单3中只修改了ext3文件系统,因为noatime只对驻留在磁盘上的文件系统有帮助。
为让这一修改生效,不需要重新引导;只需重新挂装每个文件系统。
例如,为了重新挂装根文件系统,运行mount/-oremount。
有多种磁盘硬件组合,而且Linux不一定能够探测出访问磁盘的最佳方式。
可以使用hdparm命令查明和设置用来访问IDE磁盘的方法。
hdparm-t/path/to/device执行速度测试,可以将这个测试结果作为性能基准。
为了使结果尽可能准确,在运行这个命令时系统应该是空闲的。
清单4给出在hda上执行速度测试的结果。
清单4.在/dev/hd上执行的速度测试
1.# hdparm -t /dev/hda/dev/hda:
Timing buffered disk reads:
182 MB in 3.02 seconds = 60.31 MB/sec
2.
这一测试说明,在这个磁盘上读取数据的速度是大约每秒60MB。
在尝试一些磁盘调优选项之前,必须注意一个问题。
错误的设置可能损害文件系统。
有时候会出现一个警告,指出这个选项与硬件不兼容;但是,有时候没有警告消息。
因此,在将系统投入生产之前,必须对设置进行彻底的测试。
在所有服务器上都采用标准的硬件也会有所帮助。
表2列出比较常用的一些选项。
表2.hdparm的常用选项
选项描述
-vi向磁盘查询它支持的设置以及它正在使用的设置。
-c查询/启用(E)IDE32位I/O支持。
hdparm-c1/dev/hda启用这个设置。
-m查询/设置每中断多扇区模式。
如果设置大于零,设置值就是每个中断可以传输的最大扇区数量。
-d1-X启用直接内存访问(DMA)传输并设置IDE传输模式。
hdparm手册页详细说明了在-X后面可以设置的数字。
只有在-vi说明目前并未使用最快速的模式的情况下,才需要进行这个设置。
不幸的是,对于FiberChannelandSmallComputerSystemsInterface(SCSI)系统,调优依赖于具体的驱动器。
必须将有帮助的设置添加到启动脚本中,比如rc.local。
网络文件系统调优
网络文件系统(NFS)是一种通过网络共享磁盘的方法。
NFS可以帮助确保每个主机具有相同数据的拷贝,并确保修改反映在所有节点上。
但是,在默认情况下,NFS的配置不适合大容量磁盘。
每个客户机应该用rsize=32768,wsize=32768,intr,noatime挂装远程文件系统,从而确保:
使用大的读/写块(数字指定最大块大小,在这个示例中是32KB)。
在挂起时NFS操作可以被中断。
不持续更新atime。
可以将这些设置放在/etc/fstab中,见清单3。
如果使用自动挂装器,那么应该将这些设置放在适当的/etc/auto.*文件中。
在服务器端,一定要确保有足够的NFS内核线程来处理所有客户机。
在默认情况下,只启动一个线程,但是RedHat和Fedora系统会启动8个线程。
对于繁忙的NFS服务器,应该提高这个数字,比如32或64。
可以用nfsstat-rc命令评估客户机,了解是否有阻塞的现象,这个命令显示客户机远程过程调用(RPC)统计数据。
清单5显示一个Web服务器的客户机统计数据。
清单5.显示NFS客户机的RPC统计数据
1.# nfsstat -rcClient rpc stats:
calls retrans authrefrsh1465903813 0 0
2.
第二列retrans是零,这表示从上一次重新引导以来没有出现需要重新传输的情况。
如果这个数字比较大,就应该考虑增加NFS内核线程。
设置方法是将所需的线程数量传递给rpc.nfsd,比如rpc.nfsd128会启动128个线程。
任何时候都可以进行这种设置。
线程会根据需要启动或销毁。
同样,这个设置应该放在启动脚本中,尤其是在系统上启用NFS的脚本。
关于NFS,最后要注意一点:
如果可能的话,应该避免使用NFSv2,因为NFSv2的性能比v3和v4差得多。
在现代的Linux发行版中这应该不是问题,但是可以在服务器上检查nfsstat的输出,了解是否有任何NFSv2调用。
后续内容
本文讨论了LAMP的一些基本知识以及LAMP安装的一些简单Linux调优措施。
除了NFS内核线程之外,可以设置本文中讨论的参数,然后就不用理会它们了。
本系列中的后两篇文章主要关注Apache、MySQL和PHP调优。
这些组件的调优与Linux的调优有很大的差异,因为随着通信量的增长、读写操作分布情况的变化和应用程序的演化,需要不断重新考察这些参数。
LAMP架构、优化Apache和PHP、MySQL的调优
调优Apache
Apache是一种高度可配置的软件。
它具有大量特性,但每一种都代价高昂。
从某种程度上来说,调优Apache来说就是以恰当的方式分配资源,还涉及到将配置简化为仅包含必要内容。
配置MPM
Apache是模块化的,因为可以轻松添加和移除特性。
在Apache的核心,多处理模块(Multi-ProcessingModule,MPM)提供了这种模块化功能性——管理网络连接、调度请求。
MPM使您能够使用线程,甚至能够将Apache迁移到另外一个操作系统。
每次只能有一个MPM是活动的,必须使用--with-mpm=(worker|prefork|event)静态编译。
每个请求使用一个进程的传统模型称为prefork。
较新的线程化模型称为worker,它使用多个进程,每个进程又有多个线程,这样就能以较低的开销获得更好的性能。
最新的eventMPM是一种实验性的模型,为不同的任务使用单独的线程池。
要确定当前使用的是哪种MPM,可执行httpd-l。
如:
1.[root@localhost ~]# httpd -l
2.
3.Compiled in modules:
4.
5.core.c
6.
7.prefork.c
8.
9.http_core.c
10.
11.mod_so.c
12.
选择使用何种MPM取决于许多因素。
在eventMPM脱离实验状态之前,不应考虑这种模型,而是在使用线程和不使用线程之间作出选择。
表面上看来,如果所有底层模块(包括PHP使用的所有库)都是线程安全的,线程要优于分叉(forking)。
而Prefork是较为安全的选择;如果选择了worker,则应该谨慎测试。
性能收益还取决于您的发布版所附带的库及硬件。
无论选择了哪种MPM,都必须恰当地配置它。
一般而言,配置MPM包括告知Apache怎样去控制有多少worker正在运行,它们是线程还是进程。
preforkMPM的重要配置选项如清单1所示。
清单1.preforkMPM的配置
1.StartServers 50
2.
3.MinSpareServers 15
4.
5.MaxSpareServers 30
6.
7.MaxClients 225
8.
9.MaxRequestsPerChild 4000
10.
prefork模型会为每个请求创建一个新进程。
多余的进程保持空闲,以处理传入的请求,这缩短了启动延迟。
只要Web服务器出现,预先完成的配置就会立即启动50个进程,并尽力保持10到20个空闲服务器运行。
进程数的硬性限制由MaxClients指定。
尽管一个进程能够处理许多相继的请求,Apache还是会取消连接数超过4,000以后的进程,这降低了内存泄漏的风险。
配置线程化MPM与之类似,不同之处只是必须确定使用多少线程和进程。
Apache文档解释了所有必要的参数和计算。
要经过几次尝试和出错之后才能选好要使用的值。
最重要的值是MaxClients。
目标在于允许足够多的workder进程或线程运行,同时又不会导致服务器进行过度的交换。
如果传入的请求超出处理能力,那么至少满足此值的那些请求会得到服务,其他请求被阻塞。
如果MaxClients过高,那么所有客户机都将体验到糟糕的服务,因为Web服务器会试图换出一个进程,以使另一个进程能够运行。
而设得过低意味着可能会不必要地拒绝服务。
查看高负载下运行的进程数量和所有Apache进程所导致的内存占用情况对设置这个值很有帮助。
如果MaxClients的值超过256,必须将ServerLimit也设为同样的数值,请仔细阅读MPM的文档,了解相关信息。
根据服务器的角色调优要启动和保持空闲的服务器数量。
如果服务器仅运行Apache,那么可以使用适中的值,如清单1所示,因为这样就能充分利用机器。
如果系统中还有其他数据库或服务器,那么就应该限制运行中的空闲服务器的数量。
有效地使用选项和重写
Apache处理的每个请求都要履行一套复杂的规则,这些规则指明了Web服务器必须遵循的约束或特殊指令。
对文件夹的访问可能按IP地址约束为某个特定文件夹,也可配置用户名和密码。
这些选项还包含处理特定文件,例如,如果提供了一个目录列表,该如何处理的文件,或输出结果是否应压缩。
这些配置以httpd.conf中容器的形式出现,例如,以便指定所用配置引用的是磁盘上的一个位置;再如,表示引用是URL中的路径。
清单2展示了一个实际的Directory容器。
清单2.为根目录应用的一个Directory容器
1.AllowOverride None
2.
3.Options FollowSymLinks
4.
在清单2中,位于一对Directory和/Directory标记之间的配置应用于给定目录和该目录下的一切内容——在本例中,这个给定目录是根目录。
此处,AllowOverride标记指出,用户不允许重写任何选项(稍后将进一步介绍)。
FollowSymLinks选项被启用,它允许Apache查看之前的符号连接来为请求提供服务,即便文件位于包含Web文件的目录之外。
这就意味着,如果Web目录中的一个文件是/etc/passwd的符号连接,Web服务器将在请求时顺利为该文件提供服务。
如果使用了-FollowSy