说明:APC-3.1.13 适应于 php-5.4.27

下载:
wget http://blog.xinfilm.com/softdir/APC-3.1.13.tgz

tar -zxvf APC-3.1.13.tgz

cd APC-3.1.13

/server/php5/bin/phpize

./configure --enable-apc --enable-mmap --enable-apc-spinlocks --with-php-config=/server/php5/bin/php-config

make && make install

在/server/php5/etc/php.ini 加入

extension = "apc.so" ;

;APC setting

apc.enabled = 1

apc.shm_segments = 1

apc.shm_size = 64M

apc.optimization = 1

apc.num_files_hint = 0

apc.ttl = 0

apc.gc_ttl = 3600

apc.cache_by_default = on

重启apache 或者 /server/php5/sbin/php-fpm restart

查看phpinfo apc

检查是否支持PHP APC apc_store apc_fetch PHP APC 配置参数 把相关的配置放在一起解释。

apc.enabled=1 apc.enabled默认值是1,你可设成0禁用APC。如果你设置为0的时候,同样把extension=apc.so也注释掉(这样可以节约内存资源)。一旦启用了APC功能,则会缓存Opcodes到共享内存。

apc.shm_segments = 1

apc.shm_size
= 30
APC既然把数据缓存在内存里面,我们就有必要对它进行内存资源限定。通过这二个配置可以限定APC可以使用的内存空间大小。
apc.shm_segments指定了使用共享内存块数,而apc.shm_size则指定了一块共享内存空间大小,单位是M。所以,允许APC使用的
内存大小应该是 apc.shm_segments * apc.shm_size =
30M。你可以调整一块共享内存的大小空间。当然,一块共享内存最大值是受操作系统限制的,即不能超过/proc/sys/kernel/shmmax大
小。否则APC创建共享内存的时候,会失败。在apc.shm_size达到了上限的时候,你可以通过设置apc.shm_segments来允许APC
使用更多的内存空间。我们推荐,如果调用APC使用内存空间的话,先考滤apc.shm_size,后考滤apc.shm_segments。具体数值,
可以根据apc.php监控情况进行规划与调整。值得注意的是,每一次调整需要重启httpd守护进程,这样可以重新加载apc.so模块。跟随着
httpd守护进程启动,apc.so模块就会加载。apc.so加载初始化的时候,通过mmap请求分配内存指定大小的内存,即
apc.shm_size *
apc.shm_segments。而且,这里使用的是匿名内存映射方式,通过映射一个特殊设备/dev/zero,提供一个“大型”的,填满了零的内存
供APC管理。 为了验证以上陈述,我们注释掉apc.ini配置,并且写了以下php脚本观察apc.so模块初始化的分配的内存空间。

#strace
-p `cat /var/run/httpd.pid` open("/var/www/html/apc_load.php",
O_RDONLY) = 13 ... mmap2(NULL, 31457280, PROT_READ|PROT_WRITE,
MAP_SHARED|MAP_ANONYMOUS, -1, 0) = 0xb5ce7000 ... nanosleep({3600, 0},
红色部分,我们可以看出。通过mmap系统内核调用分配了30M(31457280/1024/1024)内存空间。
PROT_READ|PROT_WRITE表示该内存空间可供读取与写入。

MAP_SHARED表示该内存空间与其它进程是共享的,即其它
进程也可以进行读取与写入,我们可以通过apc.php进行管理该块内存空间亦是受益于此设定。MAP_ANONYMOUS则表示匿名映射。其中fd=-
1表示忽略,因为这里映射的特殊设备/dev/zero。最后的0表示无偏移量。我们还可以通过进程映像文件查看该块内存的具体情况

#cat
/proc/14735/smaps b5ce7000-b7ae7000 rw-s 00000000 00:08 633695
/dev/zero (deleted) Size: 30720 kB Rss: 44 kB Shared_Clean: 0 kB
Shared_Dirty: 0 kB Private_Clean: 0 kB Private_Dirty: 44 kB
可以很容易地发现起始地址0xb5ce7000与上面mmap系统内核调用返回的地址一样。该块内存是可读写rw,并与其它进程共享s。而/dev
/zero则是映射文件,该文件节点是633695。其中,size表示进程可以使用的内存空间,而rss则表示实际分配的内存空间,且由
Private_Dirty可以看出,实际分配的44kb内存是由当前进程自己分配的。 apc.num_files_hint = 1000
apc.user_entries_hint = 4096
这二配置指定apc可以有多少个缓存条目。apc.num_files_hint说明你估计可能会有多少个文件相应的opcodes需要被缓成,即大约可
以有多少个apc_compiler_cache条目。另外apc.user_entries_hint则说明你估计可能会有多少个
apc_userdata_cache条目需要被缓存。如果项目中不使用apc_store()缓存用户数据的话,该值可以设定得更小。也就是说
apc.num_files_hint与apc.user_entries_hint之和决定了APC允许最大缓存对象条目的数量。准确地设置这二个值可
以得到最佳查询性能。当然,如果你不清楚要进行多少缓存(缓存对象实例)的情况下,你可以不必修改这二项配置。
其中apc.user_entries_hint要根据项目实际开发使用了apc_store()条目估计其值大小。相较而
言,apc.num_files_hint可以通过find命令,更容易地估计其大小。比如我们的web根目是/var/vhosts,则使用下面的
find命令可以大致地统计当前apc.num_files_hint数目.

#find /var/vhosts \( -name
“*.php” -or -name “*.inc” \) -type f -print |wc -l 1442 apc.stat = 1
apc.stat_ctime = 0
这二个参数,只跟apc_compiler_cache缓存相关,并不影响apc_user_cache。我们前面提到过
apc_complier_cache,它缓存的对象是php源文件一一对应的opcodes(目标文件)。PHP源文件存放在磁盘设备上,与之相对应的
Opcodes目标文件位置内存空间(共享内存),那么当php源文件被修改以后,怎么通知更新内存空间的opcodes呢?每次接收到请求后,APC都
会去检查打开的php源文件的最后修改时间,如果文件的最后修改时间与相应的内存空间缓存对象记录的最后修改时间不一致的话,APC则会认为存放在内存空
间的Opcode目标文件(缓存对象)已经过期了,acp会将缓存对象清除并且保存新解析得到的Opcode。我们关心的是,即便没有更新任何php源文
件,每次接受到http请求后,APC都会请求系统内核调用stat()来获取php源文件最后修改时。我们可以通过将apc.stat设置为0,要求
APC不去检查Opcodes相对应的php源文件是否更新了。这样可以获得最佳的性能,我们也推荐这么做。不过,这样做有一点不好的就是,一旦有PHP
源文件更新了之后,需要重启httpd守护进程或者调用apc_cache_clear()函数清空APC缓存来保证php源文件与缓存在内存空间的
Opcodes相一致。

include(ROOTP . 'i1.php'); require(ROOTP . 'i2.php');
include_once(ROOTP . 'i3.php'); require_once(ROOTP . 'i4.php');
require(ROOTP . 'i5.php'); include(ROOTP . 'i6.php'); ?>

#strace
-e trace=file -p `cat /var/run/httpd.pid` getcwd("/var/www/html", 4096)
= 14 stat64("/var/www/html/i1.php", {st_mode=S_IFREG|0644, st_size=39,
...}) = 0 stat64("/var/www/html/i2.php", {st_mode=S_IFREG|0644,
st_size=39, ...}) = 0 lstat64("/var", {st_mode=S_IFDIR|0755,
st_size=4096, ...}) = 0 lstat64("/var/www", {st_mode=S_IFDIR|0755,
st_size=4096, ...}) = 0 lstat64("/var/www/html", {st_mode=S_IFDIR|0755,
st_size=4096, ...}) = 0 lstat64("/var/www/html/i3.php",
{st_mode=S_IFREG|0644, st_size=39, ...}) = 0
open("/var/www/html/i3.php", O_RDONLY) = 12
stat64("/var/www/html/i3.php", {st_mode=S_IFREG|0644, st_size=39, ...}) =
0 lstat64("/var", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/var/www", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/var/www/html", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/var/www/html/i4.php", {st_mode=S_IFREG|0644, st_size=39, ...})
= 0 open("/var/www/html/i4.php", O_RDONLY) = 12
stat64("/var/www/html/i4.php", {st_mode=S_IFREG|0644, st_size=39, ...}) =
0 stat64("/var/www/html/i5.php", {st_mode=S_IFREG|0644, st_size=39,
...}) = 0 stat64("/var/www/html/i6.php", {st_mode=S_IFREG|0644,
st_size=39, ...}) = 0 chdir("/tmp") = 0

#strace -e trace=file -p
`cat /var/run/httpd.pid` getcwd("/var/www/html", 4096) = 14
open("/var/www/html/i3.php", O_RDONLY) = 12 open("/var/www/html/i4.php",
O_RDONLY) = 12 chdir("/tmp") = 0
对比可见,当apc.stat=0时,省了很多系统内核调用,我们没有看到系统内核调用stat64了。其中,i3.php和i4.php分别是php的
include_once和require_once函数调用,它要交给fstat()系统内核调用来检查文件是否打开过。单从性能角度出发的
话,require比require_once性能更佳。

设置apc.stat_ctime的意义并是很大。如果
apc.stat_ctime值为1时,仅当php源文件的创建时间(ctime)大于php源文件的最后修改时间(mtime)时,缓存对象的
mtime时间会被php源文件的ctime所代替,否则缓存对象的mtime依然记录为php源文件的mtime。这样做是防止通过cvs,
svn或者rsync等工具刷新php源文件的mtime,这样会导致APC通过比对php源文件的创建时间ctime来决定缓存对象有没有过期。我们推
荐该保持默认值,即apc.stat_ctime = 0

apc.ttl=0 apc.user_ttl=0
缓存对象的生命周期。其中ttl表示Time To
Live,意味着指定时间后缓存对象会被清除。其中0表示永不过期。我们前面提过,APC能缓存的条目是受限定的,如果你把ttl设置永不过期的话,当缓
存条目已满或者缓存空间不够,之后的缓存都将失败。
其中apc.ttl作用于apc_compiler_cache。当apc.ttl大于0时,每次请求都会对比这次的请求时间与上一次请求时间之差是不是
大于apc.ttl,如果大于apc.ttl,则会被认缓存条目过期了,会被清理。
比较有意思的是apc.user_ttl,它主要作用于apc_user_cache缓存。

我们知道,这种类型的缓存是通过
apc_store($key, $var, $ttl =
0)创建的缓存对象。函数apc_store()中指定的$ttl与php.ini中设定的apc.user_ttl有什么异同,是我们比较关心的。因为
它们同样作用于apc_userdata_cache缓存。经过分析,我们知道:判断apc_user_cache缓存过期的依据是,当
apc.user_ttl大于0,且这次http请求时间与上一次http请求时间之差大于apc.user_ttl,则认为相应的缓存条目已过期;或
者,user.data.ttl(php函数apc_store()中指定的$ttl)大于0,且这次http请求时间与缓存对象创建时间ctime之差
大于user.data.ttl,则同样认为缓存条目已过期,会被清除。
我们推荐,如果你的项目较为稳定,并且apc.stat设置为0。同时apc.shm_size、apc.num_files_hint设置合理的
话,apc.ttl建议设置为0。即apc_compiler_cache永不回收,直到重启httpd守护进程或者调用函数
apc_cache_clear()清缓存。

至于apc.user_ttl,建议设置为0,由开发人员调用apc_store()函数的时
候,设置$ttl来指定该缓存对象的生命周期。 apc.slam_defense=0 apc.write_lock=1
apc.file_update_protection=2
之所以把这三个配置放在一起解释,是因为他们的意义很相近。其中apc.file_update_protection最好理解,它的单位是时间单位秒。
如果当前http请求时间与php源文件最好修改时间mtime之差小于apc.file_update_protection时间,APC则不会缓存该
php源文件与之对应的Opcodes,直到接下来的某次访问,并且访问时间与php源文件的最后修改时间大于
apc.file_update_protection时间,相之相应的Opcodes才会被缓存到共享内存空间。这样做的好处是,不容易被用户访问到你
正在修改的源文件。我们推荐在开发环境,该值可以设置得更大一点,但在运营环境,我们推荐保留默认值即可。
当你的网站并发量很大的时候,可能出现由http守护进程fork的多个子进程同时缓存同一份Opcodes的情况。通过
apc.slam_defense则可以减少这种事情的发生机率。比如,apc.slam_defense值设置为60的时候,当遇到未缓存的
Opcodes,每100次有60次是不缓存的。对于并发量不大的网站,我们推荐该值设定为0,对于并发量高的网站我们可以根据统计适当地调整该值。而
apc.write_lock是一个布尔值,当该值设置为1的时候,当多个进程同时缓存同一份Opcodes时,仅当最先那个进程缓存有效,其它的无效。
通过apc.write_lock设置,有效地避免了缓存写竞争的出现。 apc.max_file_size=1M apc.filters =
NULL apc.cache_by_default=1
这三个配置放在一起,是因为他们都用于限制缓存。其中apc.max_file_size表示如果php源文件超过了1M,则与之对应的opcodes不
被缓存。而apc.filters指定一个文件过滤列表,以逗号(,)隔开。当apc.cache_by_default等于1时,与
apc.filters列表中指定的文件名相匹配的文件不会被缓存。相反,apc.cache_by_default等于0时,仅缓存与
acp.filters列表中指定的文件相匹配的文件。

疑问: apc.ttl = 3600 没用啊。php 更改后,会自动更新php

总结 1,使用Spinlocks锁机制,能够达到最佳性能。

2,APC提供了apc.php,用于监控与管理APC缓存。不要忘记修改管理员名和密码

3,APC默认通过mmap匿名映射创建共享内存,缓存对象都存放在这块”大型”的内存空间。由APC自行管理该共享内存

4,我们需要通过统计调整apc.shm_size、apc.num_files_hints、apc.user_entries_hint的值。直到最佳

5,好吧,我承认apc.stat = 0 可以获得更佳的性能。要我做什么都可以接受.

6,PHP预定义常量,可以使用apc_define_constants()函数。不过据APC开发者介绍说pecl hidef性能更佳,抛异define吧,它是低效的。

7,函数apc_store(),对于系统设置等PHP变量,生命周期是整个应用(从httpd守护进程直到httpd守护进程关闭),使用APC比Memcached会更好。必竟不要经过网络传输协议tcp。

8,APC不适于通过函数apc_store()缓存频繁变更的用户数据,会出现一些奇异现象。

给php加速安装APC的更多相关文章

  1. 用豆瓣加速安装pandas、numpy、matplotlib(画图)

    安装pandas.numpy会同时被安装 #pthony2.x,用豆瓣加速安装pandas pip install -i https://pypi.doubanio.com/simple/ panda ...

  2. PHP安装APC扩展,亲测成功

    1.在浏览器中输入https://pecl.php.net/package/APC选择安装包激进型下载.(可以选择Windows版本或者是Linux版本).注:以下是在Linux系统上进行操作!

  3. 加速安装 Sharepoint 2013 SP1

    第一次安装把人吓了一跳,居然花了5个半小时.想想有一大堆服务器要升级,不得不想想有什么加速的办法. 试了好几种方法,以下的办法最为简单 1:停止 IIS ADMIN,WWW 服务 2:停止所有 sha ...

  4. mac下安装apc并且使用

    1.到网站下载对应PHP版本apc压缩包http://git.php.net/?p=pecl/caching/apc.git;a=commit;h=08e2ce7ab5f59aea483d877e2b ...

  5. pip安装模块使用国内镜像源加速安装

    今天在安装Python模块matplotlib的时候,一直安装不成功,老是提示“socket.timeout: The read operation timed out”或者“Read timed o ...

  6. linux下为php安装APC扩展

    wget http://pecl.php.net/get/APC-3.1.9.tgztar xzvf APC-3.1.9.tgzcd APC-3.1.9/usr/local/php/bin/phpiz ...

  7. Android SDK离线安装方法详解(加速安装) 转

    AndroidSDK在国内下载一直很慢··有时候通宵都下不了一点点,最后只有选择离线安装,现在发出离线安装地址和方法,希望对大家有帮助! 离线安装包下载地址:http://dl.vmall.com/c ...

  8. linux下安装apc

    wget htdtp://pecl.php.net/get/APC tar zxvf APC-3.1.3p.tgz cd APC-3.1.3p /usr/local/php/bin/phpize ./ ...

  9. Ubuntu16.04下配置pip国内镜像源加速安装【转】

    本文转载自:https://blog.csdn.net/yucicheung/article/details/79095742 问题描述 基于国内网速的问题,我们直接pip安装包通常速度非常慢,而且经 ...

随机推荐

  1. 2017广东工业大学程序设计竞赛初赛 题解&源码(A,水 B,数学 C,二分 D,枚举 E,dp F,思维题 G,字符串处理 H,枚举)

    Problem A: An easy problem Description Peter Manson owned a small house in an obscure street. It was ...

  2. Gym100971B Gym100971C Gym100971F Gym100971G Gym100971K Gym100971L(都是好写的题。。。) IX Samara Regional Intercollegiate Programming Contest Russia, Samara, March 13, 2016

    昨天训练打的Gym,今天写题解. Gym100971B 这个题就是输出的时候有点小问题,其他的都很简单. 总之,emnnn,简单题. 代码: #include<iostream> #inc ...

  3. 0/1背包 dp学习~6

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1203 I NEED A OFFER! Time Limit: 2000/1000 MS (Java/O ...

  4. HDU_4826

    Labyrinth Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  5. B. OR in Matrix

    B. OR in Matrix time limit per test 1 second memory limit per test 256 megabytes input standard inpu ...

  6. sscanf()用法

    http://blog.chinaunix.net/uid-26284412-id-3189214.html #include<cstdio> #include<cstring> ...

  7. PL/SQL游标详解

    刚打开游标的时候,是位于一个空行,要用fetch into 才能到第一行. 只是要注意用更新游标的时候,不能在游标期间commit. 否则会报ORA-01002: fetch out of seque ...

  8. c++(单向链表)

    有的时候,处于内存中的数据并不是连续的.那么这时候,我们就需要在数据结构中添加一个属性,这个属性会记录下面一个数据的地址.有了这个地址之后,所有的数据就像一条链子一样串起来了,那么这个地址属性就起到了 ...

  9. 微信小程序模板消息详解

    先放代码 wxml: <form name='pushMsgFm' report-submit bindsubmit='orderSign'> <view> 单号: 0< ...

  10. 在tomcat中布置项目的介绍(一)

    一:为什么要在tomcat中单独布置项目 因为上线到服务器上需要项目的功能之间彼此独立,这个以后我会细说. 二:简单的步骤一个都不能少 conf文件里的配置文件需要配置好:logback.xml文件会 ...