正确使用PHP的Opcache加速模块

前几天一个朋友问了 PHP 中的 Opcache ,自己就去看了线上服务器的相关配置,其中的一个参数让我思索了半天,所以就详细去了解这个模块。

Opcache 对于 PHP 开发人员来说,应该是比较熟悉的,PHP 在执行的时候需要由解析器将源码转换为 byte-code,对于同一个 PHP 文件来说,假如每次执行的时候就需要转换一次,那就太影响性能了,因此出现了很多的加速模块,而从 PHP 5.5 开始 Opcache 已经成为官方标准的模块。

假如你还是个新手,就不要去了解其它的加速模块了(比如 APC),因为既然是官方的,那么性能、稳定性、适配性各方面就不用太担心了,也有一些文章比较 APC cache 和 Opcache。

对于应用层的开发者来说,只要知道 Opcache 是一个 PHP 内置的加速模块就行,当 PHP 解析器在解析一个 PHP 文件的时候,假如该文件对应的 byte-code 存储在内存中,则省去了转换过程直接执行了;反之则会编译,并将编译后的 byte-code 存入到内存中(以文件名作为索引)。

那么用了 Opcache 性能有多大的提升呢(这是应用的本质),看了一些文章列举的测试,整体的脚本响应时间最少提升 10%(取决于不同的 PHP 开发框架和具体的应用),虽然提升仅仅是几毫秒,但是对于一个大网站来说,能够极大的降低负载并且也会提高并发请求数。

不管是通过源码还是包安装,默认 Opcache 安装后是开启的,相关的参数类似于:

#/etc/php5/fpm/php.ini 

validate_timestamps=1
revalidate_freq=0
memory_consumption=64
max_accelerated_files=4000 
opcache.fast_shutdown=0

validate_timestamps 这个参数很重要,假如等于 0,那么 PHP 解析器只要发现内存中有对应 PHP 文件的 byte-code 内容就会加载,反应灵敏的同学可能会想,假如开发者修改了其开发的 PHP 代码,那么这个 byte-code 不就是“脏”内容吗,确实是这样的(如何解决呢?)。

假如 validate_timestamps 等于 1,PHP 解析器从内存中获取某个 PHP 文件对应的
byte-code,会通过一定的方法比较 byte-code 内容是不是最新的(读取文件系统),假如比较后发现 byte-code 已经过期,应该重新编译生成。
需要注意,PHP 解析器不是每次都会去检查(一切为了效率),检查的频率取决于 revalidate_freq 参数( 0 表示每次都检查)。

memory_consumption 这个参数很好理解,代表这块内存区开辟的大小,另外需要注意不同 PHP SAPI 内存区不是共享的,就是说同一个 PHP 文件,运行在命令行模式或者 PHP-FPM 模式下,对应的 byte-code 会存储在不同的内存区中。

max_accelerated_files 表示内存区最大能存储的 PHP 文件数量。

如何了解 Opcache 的运行状况

上面主要说了 Opcache 的定义、安装、配置、简单的运作机制,对于开发者来说,了解这些就足够了,但是可进一步了解 Opcache 到底缓存了什么,PHP 提供了一些函数(opcache_get_configuration()和 and opcache_get_status())获取配置信息和运行信息,比如了解那些文件被缓存了、使用了多少内存、内存命中率等等。

我截取了一段线上服务器的运行信息:

Array
(
    [opcache_enabled] => 1
    [cache_full] => 
    [restart_pending] => 
    [restart_in_progress] => 
    [memory_usage] => Array
        (
            [used_memory] => 16975736
            [free_memory] => 116769216
            [wasted_memory] => 472776
            [current_wasted_percentage] => 0.35224556922913
        )

    [opcache_statistics] => Array
        (
            [num_cached_scripts] => 340
            [num_cached_keys] => 1071
            [max_cached_keys] => 7963
            [hits] => 22016549
            [start_time] => 1486840022
            [last_restart_time] => 0
            [oom_restarts] => 0
            [hash_restarts] => 0
            [manual_restarts] => 0
            [misses] => 352
            [blacklist_misses] => 0
            [blacklist_miss_ratio] => 0
            [opcache_hit_rate] => 99.99840122822
        )

    [scripts] => Array
        (
            [/usrPincode.php] => Array
                (
                    [full_path] => /usr/Pincode.php
                    [hits] => 0
                    [memory_consumption] => 323800
                    [last_used] => Sun Feb 12 06:16:14 2017
                    [last_used_timestamp] => 1486851374
                    [timestamp] => 1469520891
                )
        )
)

也有一些工具可以更直观的获取运行信息。

validate_timestamps 指令

其实写这篇文章,主要是为了了解这个指令,文档上建议生产环境不开启,开发环境不开启。
不开启的意思就是不校验 PHP 文件最近有没有修改过,主要是为了效率(参考前面讲的),那么如何解决文件更新带来的问题呢(让它保持最新),有两种方法:

第一种方法就是调用 opcache_reset() 函数,第二种重启 PHP SPAI,比如运行service php5-fpm restart等。

但是上面两种方式都太凶残,假如开发的项目频繁上线,每次缓存区都要全部清空,可以使用opcache_invalidate()函数更新特定文件的缓存。

不管那种方式,为了清除失效的 byte-code,在部署代码的时候必然会有一些麻烦,可以写一些脚本来做到自动化更新缓存。

关闭这个指令的好处:

  • 不用频繁读取文件系统(校验内存中的 byte-code 是不是最新的)
  • 同个文件不会缓存多份(因为某个文件 byte-code 并不会因为过期而释放内存区)

另外推荐这篇文章,说的比较详细。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容