注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

胡益兵的博客

新的岗位,新的方向,新的使命,stem教育进行中。

 
 
 

日志

 
 

【转】Moodle性能优化指南  

2012-11-02 08:57:46|  分类: 魔灯专栏 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
http://log.dongsheng.org/2012/11/01/moodle-performance/

Moodle是个相当复杂的PHP程序,因为架构和功能的复杂性,大中小型Moodle站点都会遇到各种性能问题,加上信息流通的障碍,这些问题在中文社区尤其严重,各种优化技巧和解决问题的工具没法流通起来。所以我起草本文分析一般性的Moodle性能问题和相应的解决方案,更加具体的方面再写新的文章详谈。您如果有意见和想法,请留言,不胜感激。

为什么Moodle这么慢

这是最常被问起的问题,慢有很多种解释,常让回答的人无所适从。

一般人觉得Moodle慢是因为Moodle的页面载入缓慢,这个问题的根源是Moodle载入了大量的JavaScript和CSS文件,于是浏览器要建立大量的连接去读取,某些页面常常会假死几百毫秒,给人造成不流畅的感觉,另一方面,Moodle的CSS定义写的相当不简洁,不少CSS规则是重复的,浏览器要消耗不少时间去处理分析,解决这些问题的一些技巧:

  • 关闭主题设置模式(themedesignermode),开启这个选项可以让设计师载入单个js和css文件,但会造成大量的http连接,让前端性能直线下降,关闭以后,moodle会用一个php脚本把多个css和js文件合并成单个,这样大量减少http连接已优化性能,而且这个合并脚本小心处理了HTTP header里的浏览器缓存选项,下次打开该页的时候浏览器会从本地读取而不是再次访问moodle
  • 检查你在moodle里开启的过滤器,如果不是必须要用尽量关闭,过滤器会对字符串进行正则匹配,如果内容过多,会造成页面渲染时间变长
  • 启用文本缓存(cachetext),这是个跟过滤器有关的选项,可以避免php重复处理文本
  • 启用语言缓存(langstringcache),moodle支持多语言,一如既往的,你获得这一特性,就要为这特性付出性能代价,moodle一张页面上调用上千次多语言并不稀奇,所以一定要开启多语言缓存选项,这样能适当提高获取语言字符串的效率

然后是提高前端性能的必杀技:

  • 使用Chrome浏览器!!我知道你有一万个使用IE的理由,但在电脑上装个Chrome不会影响你对IE的爱,Chrome有比IE强的多的载入和渲染性能,让你不用在moodle上下什么功夫就获得前端性能的飞跃!
  • 如果你把moodle的主题设置成base,你会发现,打开moodle的速度真是快了很多,因为这个base主题没有华丽花哨的图片和大量修饰用的css,当然了,这个主题没法看,这就需要你花点时间,以这个主题为基础,对css的规则进行删减和修改,去掉那些无用规则,然后一点点改进页面的外观

应用上面的技巧以后,主要是后两条,我对Moodle的前端性能基本满意。关于优化Moodle的CSS规则,可以使用Chrome的Audits工具,它常常会告诉你超过90%的CSS规则在当前页是没有用到的 :-)

服务器性能优化

这是Moodle性能优化的大头。

硬件方面自然是越强越好,选择尽可能强大的多核处理,更大的RAM,速度更快的硬盘(SSD就更好了),数据库服务器最好和WEB服务器独立处理,两者用G比特网卡联通。
操作系统方面,请尽量选择*nix操作系统,我本人并不熟悉Windows的服务器搭建,所以不敢说*nix会有比windows更好的性能,用*nix的最大好处是丰富的工具链和成熟解决方案,这些工具可以让你组建高可用性高性能的架构,本文也是假设您使用*nix系统。

这个部分可以分为PHP,WEB服务器和数据库性能优化。

PHP性能

  • 最重要的一条:安装一个PHP加速器,比如APC,Xcache或者eAccelerator,如果你不确定选择哪一个,那就用APC,这是PHP官方开发,这些工具用的同一套思想,所以性能不会有质的差异。使用加速器可以让PHP的执行效能大幅提高。
  • 将PHP加速器生成的中间码写到TMPFS上以提高IO性能,详见:http://docs.moodle.org/23/en/TMPFS
  • 修改php.ini里的memory_limit选项,原则上是越大越好512M以上吧,防止内存不够用PHP执行不下去
  • 毫不吝啬的升级PHP版本,新的版本总是在修复bug并改进性能,没有理由不升级,说到这里不得不提一下PHP 5.4,先不要让Moodle跑在这个版本上,5.4引入了mysqlnd,非常有意义的改进,我在数据库那节详谈

WEB服务器性能

先说Apache,Apache最大的问题是内存消耗太厉害,主要是因为用了传统的进程模型,内存消耗难降下来,关键的几个优化点:

  • 调整MaxClients,这个值大致可以是计划分配给apache的可用内存除以单个apache进程消耗的最大内存,请用top命令观察
  • MaxRequestsPerChild保持在20-30左右,这个也要根据你服务器的情况细调
  • AllowOverride这个必须是None,在每个目录都查找.htaccess是个不小的开销
  • 关掉不用的module

然后是Nginx,首先,Nginx不会让Moodle运行的更快,它对Apache最直观的优势是内存用的少多了。Nginx和Lighttpd这种服务器采用异步IO可以提高服务器处理大并发的问题,但不会提高PHP的执行效率,Nginx的典型用例是充当负载均衡的前端,也可以搭配PHP-FPM充当后端服务器。

MySQL性能

这个其实是Moodle性能的终极问题,所有持续发展的Moodle站点最终都会走到数据库瓶颈这里。Moodle是个对数据库相当饥渴的系统,每页有七八十条查询毫不稀奇,所以优化MySQL至关重要。首先,要使用InnoDB数据库引擎,MyISAM是必须抛弃的,一个不支持事务不提供行级锁的引擎不是个真正的数据库引擎,所以请使用moodle自带的转换工具将表统统换成InnoDB,告别锁表这种荒诞的错误。

InnoDB优化的原则是让查询尽量都发生在RAM里,尽量不要反复到磁盘查询,几个关键的选项(在my.cnf里):

  • query_cache_type和query_cache_size,我的设置成了128M,这个请根据你的具体情况设置,详情参见mysql的文档
  • table_cache,moodle有三百多张数据表,所以设置这个值可以降低开表的开销
  • innodb_buffer_pool_size,这个可以设置成可用内存的80-90%
  • innodb_flush_log_at_trx_commit = 2,这个让InnoDB批量写入而不是每次有写入请求就写磁盘,这个非常关键
  • innodb_log_buffer_size和innodb_log_buffer_size,请根据服务器状况设置合理的值,详见mysql文档

MySQL还有很多其他关于thread和io的选项,强烈推荐阅读High Performance MySQL

代码级优化

除非你真的知道你在做什么,否则不要随意修改Moodle的核心代码,这会给你以后升级带来无穷的麻烦,而且大多数Moodle核心代码里的查询都是必需的,优化的空间和效果,不太明显。

在这一节说说Moodle的Session问题,从Moodle 2.0开始,使用数据库存储Session,每次页面请求就多了一次读取和写入,当并发用户特别大,且Session size比较大的时候,这就变成了数据库服务器的巨大负担,还好Moodle 2.x允许你创建自己的Session handler,你可以自己写一个,把Session写到MongoDB或者Redis或者Memcached里,这在大并发的时候能给你带来惊喜。

架构

比起前面提到的小优化技巧能带来的效果是有限的,可以小幅提高性能或者避免不当的设置,但真正解决问题的是架构的横向扩展。

架构是至关重要的,programming language doesn’t scale,architecture does。

WEB服务器这一层是容易scale out的,用Nginx在前端做个负载均衡入口,然后在后端设置多个Apache或者Ningx+PHP-FPM实例,Moodle代码用NFS共享到这些WEB服务器上,一旦遇到性能瓶颈就加HTTP服务器,但注意,HTTP服务器这一层不是越多越好,越多的实例意味这更多的连接开销,并且Moodle使用了PHP静态变量做缓存,这种cache策略是无法在多个实例间共享的,这是性能的损失。

真正困难的是数据库层的横向扩展,单一数据库总有一天会碰到性能的天花板顶,除了升级硬件,横向扩展的解决的办法是架设MySQL的master-slave,然后实现读写分离,我现在正在考虑的是两个解决方案:

  • 使用MySQL-Proxy实现读写分离,顺便log一下Moodle的查询,统计下被查询最多的表,针对性优化
  • 我前文提到PHP 5.4开始使用mysqlnd,之前的版本php用的libmysqlclient,mysqlnd是个native的库,可以利用php内置的机制优化,并且这给使用mysqlnd_ms变成可能,使用这个扩展可以设置MySQL的读写分离,解决单一数据库服务器的性能瓶颈

在master-slave架构里的主要问题是MySQL的replication是异步的,也就是说在master里写入的东西,并不一定是实时的出现在slave里,这就需要采用RAID或者DRBD之类的技术保证数据的一致性,这个很大的话题,请参阅Google,就不详谈了。

  评论这张
 
阅读(1711)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018