[Turn]php accelerate PHP APC analysis
PHP APC provides two kinds of caching functions, namely cache opcode (target file), which we call Apc_compiler_cache. It also provides interfaces for PHP developers to host user data in memory, which we call Apc_user_cache. Here we mainly control the configuration of PHP-APC.
Installing the PHP APC
As a test environment, we are using CentOS5.3 (2.6.18-128.EL5PAE) + Apache2.0 (prefork) + php5.2. We can go to pecl APC Download apc-3.0.19.tgz
# TAR-XZVF APC-3.0.19.TGZ#CD apc-3.0.19#/usr/bin/phpize#/configure--ENABLE-APC--enable-mmap-- Enable-apc-spinlocks--disable-apc-pthreadmutex#make#make Install
Note: We support mmap here, while using spinlocks spin lock. Spinlocks is recommended by Facebook and is also a locking mechanism recommended by APC developers.
PHP APC Configuration Parameters
If you are using a system environment that is the same as my test environment, you can create a file Apc.ini in the/ETC/PHP.D directory, and the related configuration writes to the/etc/php.d/apc.ini file. Here, we picked out some of the commonly used configurations and explored them. Put the relevant configuration together to explain.
Apc.enabled=1
The default value of apc.enabled is 1 and you can set it to 0 to disable APC. If you set it to 0, also comment out the extension=apc.so (which saves memory resources). Once the APC feature is enabled, opcodes to shared memory is cached.
Apc.shm_segments = 1
Apc.shm_size = 30
Since APC caches data in memory, it is necessary for us to limit it to memory resources. These two configurations allow you to limit the amount of memory space an APC can use. APC.SHM_SEGMENTS Specifies the number of shared memory blocks, while apc.shm_size specifies a chunk of shared memory space, in M. Therefore, the amount of memory allowed to be used by APC should be apc.shm_segments * apc.shm_size = 30M. You can adjust the size space of a piece of shared memory. Of course, the maximum value of a piece of shared memory is limited by the operating system, i.e. it cannot exceed the/proc/sys/kernel/shmmax size. Otherwise, the APC will fail when it creates the shared memory. When the apc.shm_size reaches the upper limit, you can set the apc.shm_segments to allow APC to use more memory space. We recommend that if you call APC to use memory space, the first filter apc.shm_size, after the filter apc.shm_segments. The specific value can be planned and adjusted according to the apc.php monitoring situation. It is worth noting that each adjustment requires restarting the httpd daemon so that the Apc.so module can be reloaded. Following the httpd daemon boot, the apc.so module will be loaded. apc.so load initialization, the memory specified by the MMAP request is allocated, that is, apc.shm_size * apc.shm_segments. Moreover, the use of anonymous memory mapping, by mapping a special device/dev/zero, provides a "large", filled with 0 of the memory for APC management.
To verify the above statement, we commented out the Apc.ini configuration and wrote the following PHP script to observe the allocated memory space of the Apc.so module initialization.
#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},
Red part, as we can see. 30M (31457280/1024/1024) memory space is allocated through the MMAP system kernel call. prot_read| Prot_write indicates that the memory space is available for reading and writing. Map_shared indicates that the memory space is shared with other processes, that is, other processes can also read and write, and we can manage that block of memory space through apc.php and also benefit from this setting. The map_anonymous represents an anonymous mapping. Where Fd=-1 is ignored because of the special device/dev/zero that is mapped here. The last 0 indicates no offset. We can also view the details of the block memory through the process image file
#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
It is easy to find the starting address 0xb5ce7000 the same address that was returned by the MMAP system kernel call above. The block memory is read-write RW and shares s with other processes. The/dev/zero is a mapping file, and the file node is 633695. Where size represents the memory space that the process can use, and RSS represents the actual allocated memory space, and as Private_dirty can see, the actual allocated 44kb memory is allocated by the current process itself.
Apc.num_files_hint = 1000
Apc.user_entries_hint = 4096
This two configuration specifies how many cache entries an APC can have. Apc.num_files_hint explains how many files you might expect to have the corresponding opcodes need to be slowed down, that is, about how many Apc_compiler_cache entries you can have. Another apc.user_entries_hint indicates how many Apc_userdata_cache entries you might expect to be cached. If you do not use Apc_store () to cache user data in your project, the value can be set smaller. This means that the sum of Apc.num_files_hint and Apc.user_entries_hint determines the number of maximum cache object entries that APC allows. Setting these two values accurately results in optimal query performance. Of course, if you don't know how many caches you want to make (cache object instances), you don't have to modify these two configurations.
Apc.user_entries_hint to estimate the value size of the Apc_store () entry based on the actual development of the project. By contrast, apc.num_files_hint can be more easily estimated by the find command. For example, if our web root is/var/vhosts, we can use the Find command below to roughly count the current number of 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
These two parameters are only related to the Apc_compiler_cache cache and do not affect Apc_user_cache. We mentioned earlier that Apc_complier_cache, which caches the object is the PHP source file one by one corresponding to the opcodes (target file). PHP source files are stored on the disk device, corresponding to the opcodes target file location memory space (shared memory), then when the PHP source files are modified, how to notify the update memory space opcodes? After each request is received, APC will check the last modified time of the open PHP source file, and if the last modification time of the file is inconsistent with the last modification time of the corresponding memory space cache object record, APC will assume that the opcode target file (cache object) that is stored in the memory space has expired. The ACP clears the cached object and saves the newly parsed opcode. We are concerned that, even if no PHP source files are updated, each time an HTTP request is received, APC requests that the system kernel call stat () to obtain the last modification of the PHP source file. We can ask APC not to check if the PHP source files for opcodes are updated by setting Apc.stat to 0. This allows for optimal performance and we recommend it. However, the downside of this is that once a PHP source file has been updated, it is necessary to restart the httpd daemon or call the Apc_cache_clear () function to empty the APC cache to ensure that the PHP source file is consistent with the opcodes of the cache in memory space.
# strace-e trace=file-p ' cat/var/run/httpd.pid ' getcwd ("/var/www/html", 4096) = 14stat64 ("/var/www/html/i1.php ", {st_mode=s_ifreg|0644, st_size=39, ...}) = 0stat64 ("/var/www/html/i2.php", {st_mode=s_ifreg|0644, st_size=39, ...}) = 0lstat64 ("/var", {st_mode=s_ifdir|0755, st_size=4096, ...}) = 0lstat64 ("/var/www", {st_mode=s_ifdir|0755, st_size=4096, ...}) = 0lstat64 ("/var/www/html", {st_mode=s_ifdir|0755, st_size=4096, ...}) = 0lstat64 ("/var/www/html/i3.php", {st_mode=s_ifreg|0644, st_size=39, ...}) = 0open ("/var/www/html/i3.php", O_RDONLY) = 12stat64 ("/var/www/html/i3.php", {st_mode=s_ifreg|0644, st_size=39, ...}) = 0lstat64 ("/var", {st_mode=s_ifdir|0755, st_size=4096, ...}) = 0lstat64 ("/var/www", {st_mode=s_ifdir|0755, st_size=4096, ...}) = 0lstat64 ("/var/www/html", {st_mode=s_ifdir|0755, st_size=4096, ...}) = 0lstat64 ("/var/www/html/i4.php", {st_mode=s_ifreg|0644, st_size=39, ...}) = 0open ("/var/www/html/i4.php", O_RDONLY) = 12stat64 ("/var/www/html/i4.php", {st_mode=s_ifreg|0644, st_size=39, ...}) = 0stat64 ("/var/www/html/i5.php", {st_mode=s_ifreg|0644, st_size=39, ...}) = 0stat64 ("/var/www/html/i6.php", {St_mode =s_ifreg|0644, st_size=39, ...}) = 0chdir ("/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
The comparison shows that when apc.stat=0, we save a lot of system kernel calls, we did not see the system kernel call Stat64. Of these, i3.php and i4.php are PHP include_once and require_once function calls, which are given to the Fstat () system kernel call to check if the file is open. The Require is better than require_once performance alone.
Setting the meaning of Apc.stat_ctime is very large. If the Apc.stat_ctime value is 1 o'clock, the mtime time of the cached object will be replaced by the CTime of the PHP source file only if the PHP source file creation time (CTime) is greater than the last modified time (mtime) of the PHP source file. Otherwise, the mtime of the cached object is still recorded as the mtime of the PHP source file. This is done to prevent the mtime of PHP source files from being flushed by CVS, SVN, or rsync, which can cause APC to determine whether the cached object has expired than the time CTime the PHP source file was created. We recommend that you keep the default value, which is Apc.stat_ctime = 0
Apc.ttl=0
Apc.user_ttl=0
The life cycle of the cached object. Where the TTL represents time to Live, which means that the cached object is purged after a specified period. where 0 means never expire. As we mentioned earlier, APC can cache entries that are qualified, and if you never expire the TTL setting, the cache will fail after the cache entry is full or the cache space is insufficient.
Where Apc.ttl acts on Apc_compiler_cache. When Apc.ttl is greater than 0 o'clock, each request will compare this request time with the last Request time difference is greater than apc.ttl, if greater than Apc.ttl, will be recognized cache entries expire, will be cleaned up.
The interesting thing is Apc.user_ttl, which mainly acts on the Apc_user_cache cache. We know that this type of cache is a cache object created by Apc_store ($key, $var, $ttl = 0). We are concerned about the similarities and differences between the $ttl specified in the function Apc_store () and the Apc.user_ttl set in php.ini. Because they also act on the Apc_userdata_cache cache. After analysis, we know: the basis of judging Apc_user_cache cache expiration is that when APC.USER_TTL is greater than 0, and the difference between HTTP request time and last HTTP request time is greater than Apc.user_ttl, the corresponding cache entry is considered expired; User.data.ttl (the $ttl specified in PHP function Apc_store () is greater than 0, and the difference between the HTTP request time and the cache object creation time CTime is greater than User.data.ttl, then the cache entry is also considered expired and will be purged.
We recommend that if your project is more stable, and Apc.stat is set to 0. At the same time apc.shm_size, Apc.num_files_hint set reasonable, Apc.ttl recommended set to 0. That is, Apc_compiler_cache is never recycled until the httpd daemon is restarted or the function apc_cache_clear () is called to clear the cache. As for Apc.user_ttl, the recommended setting is 0, when the developer calls the Apc_store () function, set the $ttl to specify the lifetime of the cached object.
Apc.slam_defense=0
Apc.write_lock=1
apc.file_update_protection=2
These three configurations are explained together because they are very similar in meaning. Where apc.file_update_protection better understand that its unit is the time unit of the second. If the current HTTP request time and PHP source file The best modification time mtime difference is less than apc.file_update_protection time, APC will not cache the PHP source file corresponding to the opcodes, until the next visit, And the last modification time of the access time and PHP source file is greater than apc.file_update_protection time, the corresponding opcodes of the phase will be cached to the shared memory space. The advantage of this is that it is not easy for users to access the source files that you are modifying. We recommend that the value can be set a bit larger in the development environment, but in an operating environment, we recommend keeping the default values.
When your Web site is very large, multiple sub-processes that are forked by the HTTP daemon can simultaneously cache the same copy of the opcodes. By Apc.slam_defense, you can reduce the likelihood of this happening. For example, when the Apc.slam_defense value is set to 60, when an opcodes is encountered that is not cached, 60 times per 100 times is not cached. For sites with a small amount of concurrency, we recommend that this value be set to 0, and for sites with high concurrency we can adjust this value appropriately based on statistics. While Apc.write_lock is a Boolean value, when the value is set to 1, when multiple processes cache the same opcodes at the same time, the other is invalid only if the first process cache is valid. Through the Apc.write_lock setting, effectively avoids the occurrence of cache write competition.
apc.max_file_size=1m
Apc.filters = NULL
Apc.cache_by_default=1
These three configurations are put together because they are used to limit the cache. Where apc.max_file_size means that if the PHP source file exceeds 1M, then the corresponding opcodes is not cached. Instead, apc.filters specifies a file filter list, separated by commas (,). When Apc.cache_by_default equals 1 o'clock, files that match the file name specified in the Apc.filters list are not cached. Conversely, Apc.cache_by_default equals 0 o'clock, only files that match the files specified in the Acp.filters list are cached.
Summarize
1, using spinlocks lock mechanism, can achieve the best performance.
The 2,APC provides apc.php for monitoring and managing the APC cache. Don't forget to change your administrator name and password
3,APC By default, the shared memory is created by Mmap Anonymous mappings, and the cache objects are stored in this "large" memory space. The shared memory is managed by APC itself
4, we need to adjust the value of Apc.shm_size, Apc.num_files_hints, apc.user_entries_hint by statistics. Until the best
5, okay, I admit that Apc.stat = 0 can achieve better performance. Anything I can do is acceptable.
6,php pre-defined constants, you can use the apc_define_constants () function. However, according to APC developers said PECL HiDef better performance, define it, it is inefficient.
7, Function Apc_store (), for PHP variables such as system settings, the lifecycle is the entire application (from the httpd daemon until the httpd daemon shuts down), using APC is better than memcached. Must not go through the Network Transport Protocol TCP.
8,APC is not suitable for caching frequently changed user data through the function Apc_store (), there are some strange phenomena.