Wordpress themes are available for download at wordpress-related website.

Uncategorized mmpower on 18 Apr 2008 01:21 pm

[民工日记]LAMP网站建设 之性能优化篇(上)

LAMP网站建设 之性能优化篇(上)

开源的LAMP (linux/Apache/Mysql/PHP) 平台是流行的web application platform,不少网站,包括海归网都是建立在此平台上.

在帮助海归网正式转移到LAMP平台之前, 笔者虽然长期做网站设计和开发方面的工作,但主要是在J2EE 或者 ASP.NET /ASP方面的应用, 具体是在application 层面, 架构设计主要考虑功能/可扩充性和scalability, 而网站反应速度/性能方面一般不是问题–或者流量不大,或者硬件架构足够强(hardware load balancer, cluster, dedicated web/middle tier/DB tier/team等). 在海归网, 让我有机会在LAMP环境下接触和学习到许多以前做应用或自己玩操作系统时难以接触到的问题– 除了系统和网络管理外, 有许多是关于性能优化和scalability方面的.

在这篇里分享一点积攒的LAMP环境下PHP网站的性能优化经验. (谢谢老狼和海归网提供的给我一个发挥点业余爱好的机会); 以后有时间谈谈scalability/availability等.

有许多中小网站都和海归网一样只有一台服务器(海归网有一台dedictaed的dell, 更多更差的网站shared hosting的则是几十几百个网站公用一台server), 而这台服务器需要身兼web server, application server,database server, firewall等等所有一切功能…在网站建设的初期只能在有限的硬件条件下最大限度地进行优化充分利用所有的资源保证基本的功能/性能和稳定性.

1. 编译php/apache/mysql 时的优化选项

一般来说, 用不着自己编译这些东西,直接下载binary packages就可以了–无论是debian 的apt-get 还是redhat的rpm /yum. 但是这些现成的安装包编译时一般并未根据你的服务器硬件配置做优化, 而通过选择合适的C编译器 flags 和其他选项,自己编译往往能使总体性能提高几个到几十个百分点.

推荐在编译之前, 设置 CFLAGS 环境变量:

export CFLAGS="-march=pentium4 -O2 -pipe -msse2 -mfpmath=sse,387 -mmmx -fomit-frame-pointer"

-march , -msse2, -mfpmath, -mmmx 等都是根据自己的服务器CPU类型做的设置; 海归网服务器是个xeon CPU所以用上述标记; 老一些的GCC 编译器还可以加上 -prefer-nopix

一般linux用户都知道, 下载源代码后标准的编译安装过程是:

./configure [options]
make
make install

在运行./configure 时注意尽量避免编译自己不需要的模块或功能以免编译出来的东西过于臃肿.

./configure 时最好不要enable pix, 而是用 –disable-pix选项;


2. 软件版本

linux 核心版本最好在2.6以上, 因为在虚存/线程管理等关键功能上比2.4有了很大的改善,对系统性能影响较大.

有些版本的php/apache/mysql有比较严重的bug,导致系统严重不稳定. 比如 mysql 5.1.11会导致数据库表/索引频繁崩溃;最新的php5.2.5和php5.2.6 development snapshot 似乎有memory leak, 导致系统内存很快被用光服务器奇慢无比甚至死机等等.We learned it the hard way :(

3. 使用google的tcmalloc 内存分配函数代替libc里的标准malloc.

google的开源性能优化工具包 perftool 被证明对提高应用程序性能确有帮助. tcmalloc是其中一个, 与标准的malloc相比, 在内存的分配上效率很高; 编译mysql时建议使用tcmalloc库–
简单来说, 只要在./configure 后生成的Makefile里改一下, 在连接库的那行最后面加上 -ltcmalloc即可.

如果已经使用的是已编译的binary,或者只想简单测试一下tcmalloc的效果, 可以用LD_PRELOAD环境变量制定运行时使用tcmalloc库; 例如在mysqld_safe里加入

export LD_PRELOAD=/usr/local/lib/libtcmalloc.so

确定程序是否使用tcmalloc库可以用lsof命令:

lsof -n| grep tcmalloc

我的经验是使用tcmalloc后mysql的性能确实得到了提高,但在php和apache上没什么效果.

4. PHP config

一个是打开 zlib_compression开关,这样网页内容被传输到浏览器之前会先被压缩,从而减少网站流量并且加快page load速度.

当然也可以不在php里压缩.而是在apache里用mod_deflate.

5. Apache config

MPM: apache标准MPM是prefork, 起一大堆进程每个进程处理一个请求. 如果可行, 尽量使用apache worker MPM, 多线程模式可以减少apache内存使用提高性能. 最新的event mpm在worker mpm的基础上进一步提高了性能,但是目前(截至apache 2.2.8)尚处于实验阶段不推荐在production使用.

使用worker mpm要求编译apache时使用worker mpm选项, 并且php需要编译成thread-safe的,链接到mysql的thread-safe client library.

httpd.conf里一些影响性能的设置(不一一解释了, apache在线文档里都有):
– mpm的设置
– keep alive: 大部分设成 on 比较好; 个别网站设成off更好;这个需要自己测试
– keep alive time out: 1-2 秒.
– maxkeepaliveRequest: 设成比较大的数目, 比如 1000或2000.
– extended server status: disable
– allow override: 设成不允许 (也就是说尽量避免每个目录下的.htaccess文件)
– HostnameLookups Off
–LogLevel: 在production box上设成 error或crit

尽量少用mod_rewrite

除了用apache worker MPM + mod_php, 另一种常见的apache配置是用apache+ mod_fastCGI + php-fcgi; 使用fast CGI 的apache进程可以重用,另外还有安全上的一些特点.

顺便提一句, 虽然apache在web server里最有名, 但性能方面并不怎么样, 相比一些其他open source产品来说体积庞大臃肿占内存速度又慢. lighttpd是一个日渐流行的http server, 速度较apache快效率更高. 许多其他的基于scripting language的web app 例如ruby/python/perl都以lighttpd+fast cgi的模式运行.


6. mysql tunning

–mysql storage engine的选择: 最流行的是MyISAM 和INNODB. 前者是mysql初期的主要engine, 至今仍大量使用,优点是查询速度很快,并且具有全文检索等别的engine没有的功能. 但是不支持事务处理(transaction), 写操作效率也不高. innodb支持transaction和其他一些现代关系数据库的功能. 这个完全根据你的网站应用的需要了…如果涉及到ecommerce之类最好使用innodb.

–mysql 的一些系统参数的优化:

query_cache_size: 这个很重要; 太小了每个sql都得到硬盘数据库里找一次, 太大了占用内存过多影响系统其他部分. 另外query cache里相关的记录若被修改则所有cache的查询结果都会被清除.

此外, myisam 的 key_buffer, table_open_cache, sort_buffer_size, thread_cache_size, thread_concurrency, tmp_table_size,max_heap_table_size,join_buffer_size, max_connections等都影响performance. 此外.对于IINNODB, 还有一个很重要的参数是innodb_buffer_pool_size.

有一个简单的perl script可以帮助你调节上述参数: ( http://rackerhacker.com/mysqltuner/ ) .

对许多web 应用来说, 数据库往往是性能的瓶颈; 而数据库性能最常见的问题是索引问题–sql 查询/join字段不通过索引导致full table scan…可以在mysql的启动参数上加上 log-slow-queries 选项记录所有执行速度太慢的sql 语句. 甚至打开log-queries-not-using-indexes 记录所有没有使用索引的sql…然后根据情况解决: 或者给相关字段加上索引, 或者优化/改写应用程序里的sql语句.

一时写不完, 等下半篇再说说reverse proxy/ opcode cache/ data caching 等.

16 Responses to “[民工日记]LAMP网站建设 之性能优化篇(上)”

  1. on 18 Apr 2008 at 1:26 pm 1.mmpower said …

    标题:刚看了个新闻, sun在收购了mysql后正在封闭 MySQL 中的一部分代码

    在 MySQL 用户大会上,MySQL 前 CEO 对技术爱好者证实,SUN 正在封闭 MySQL 中的一部分代码。此次被关闭的代码主要设计 MySQL 的备份方案和其他一些高级功能的源代码,这些代码将不会再免费向开源社区贡献。

    MYSQL 的命运堪忧.

  2. on 18 Apr 2008 at 2:33 pm 2.海音音 said …

    标题:实在是觉得

    搞IT的都是投错了行。
    POWER M1人干数人的职责,看来可以SINGLE HANDED搭个网站
    都用在炒股上,肯定能成几笔吧。

  3. on 18 Apr 2008 at 3:31 pm 3.tahiticn said …

    标题:他母亲的

    SUN这个混蛋,应该叫孙子。 :oops:

  4. on 18 Apr 2008 at 4:17 pm 4.Link said …

    标题:顶!等着看下集

    有时间聊聊scalability方面的东东吧

  5. on 18 Apr 2008 at 11:02 pm 5.ceo/cfo said …

    标题:Thanks for sharing!

  6. on 18 Apr 2008 at 11:05 pm 6.ceo/cfo said …

    标题:真是干一行,怨一行!!

  7. on 19 Apr 2008 at 12:31 am 7.BT said …

    标题:谢谢,俺搭建的时候都是用的默认设置,不过看上去这些还是有用的,收藏先

  8. on 19 Apr 2008 at 12:41 am 8.海音音 said …

    标题:会干1行爱1行的,只是___问题。

  9. on 19 Apr 2008 at 1:21 am 9.ceo/cfo said …

    标题:and money, let me finish the sentence for you, 嘻嘻。

  10. on 19 Apr 2008 at 1:57 am 10.mmpower said …

    标题:谢谢支持, 有空一定!

  11. on 19 Apr 2008 at 1:58 am 11.mmpower said …

    标题:希望能有点用 :)

  12. on 19 Apr 2008 at 4:22 am 12.wanyan said …

    标题:其实frontend性能也是很重要的

    甚至比backend更重要,当然好多是两者相关的。
    mm泡知道yslow吧。

    http://developer.yahoo.com/performance/

    海归的得分是54分。其实分没多大关系,主要一项是expires headers.
    在apache里把mod_expires打开。再加入:
    FileETag None
    ExpiresActive On
    ExpiresDefault \"access plus 10 years\"
    分就能提高不少。
    另外还是用mod_deflate吧,不要用php里的gzip了。这样吧css,js也一块gzip了。

    另外你知道ttplayer吗,自动sync歌词的,很好用,推荐给你。

  13. on 19 Apr 2008 at 8:14 am 13.mmpower said …

    标题:小王爷好

    一直是用了mod_expire的,但是只用在了image文件上 (记得曾经用在了js/css但是不知怎么后来去掉了…); 应该把这两项加回去.

    (现在是

    <IfModule>
    ExpiresActive On
    ExpiresByType image/jpg \"access plus 300 month\"
    ExpiresByType image/jpeg \"access plus 300 month\"
    ExpiresByType image/gif \"access plus 300 month\"
    ExpiresByType image/png \"access plus 300 month\"
    </IfModule>

    )

    回头用mod_deflate试一下…就压缩本身的CPU资源占用来说, 你试过跟php zlib的比较吗?

    frond end performance 我想你主要是指client side page load的速度…这方面许多是程序和网页设计的问题, 需要仔细一个一个看…归坛现在的页面乱糟糟的需要彻底重新设计, 不过估计要花很长时间.

    ttplayer 看了, 很棒,谢谢! 以前用过些类似软件但对中文歌的支持太差… 这个真不错!希望也有个*nix /mac 版本.

    顺便,你的新站什么时候完功啊?

  14. on 19 Apr 2008 at 1:57 pm 14.wanyan said …

    标题:没有比较过

    但它们应该差不多吧. 我想用了mod_deflate,静态和php的都处理了.就不用zlib compression了.

    新站没法推出,因为我抓的十几万个坐标是mapbar的,用到googlemap上差了几十米,显示的地址驴唇不对麻醉,我操他大爷的.

    我可能重新抓. 还没想好,也可能改其他方向.反正没事慢慢做吧.

    我才做了个这个 http://caipu.org 纯粹公益的, 呵呵.

  15. on 19 Apr 2008 at 2:01 pm 15.mmpower said …

    标题:嗯,我刚改成了mod_deflate试试效果。

    先睡了, 回头再benchmark看看. 另外刚写了性能篇(下)请赐教。

    之前看了菜谱了, 还纳闷你怎么又玩开wiki了。

  16. on 20 Apr 2008 at 10:28 am 16.alias said …

    标题:人各有志嘛

Trackback This Post | Subscribe to the comments through RSS Feed

Leave a Reply

校验码:  

Buy movie . Why buy movies at the store while you can download complete movies at our home? You can pay with your credit card. Lowest prices over the Internet.

21 queries in 0.154 seconds.© 2004-2008.   海归博客. RSS Comments RSS