i want to use apc as cli with opcode cache feature.
using apc.enable_cli to true. but noting happened in benchmark time and memory usage.
; php.ini
apc.enable_cli = 1
but in web based usage different. i see how work apc and do magic for running php scripts.
about half memory usage also about 0.01 faster than normal run php script.
but i think php dont use opcode cache during using apc in cli. how can i use it. is it possible?
I wouldn't expect apc to give any improvement in performance on the command line, because the apc cache is going to be dropped every run.
Related
In the documentation it says "mostly used for debugging" which would lead me think "never enable it unless you've a problem and need to do some debugging," however reading mostly everything that I could find about it says to enable it "opcache.enable_cli 1" but why? I could not find any information concerning this matter, so if anybody knows, why should I enable it if the documentation basically says to keep it on 0?
With PHP7 and file-based caching, it can now make sense to enable opcache for CLI. The best possibility would be to have a separate php.ini for CLI with the following configuration:
opcache.enable=1
opcache.enable_cli=1
opcache.file_cache="/tmp/php-file-cache"
opcache.file_cache_only=1
opcache.file_cache_consistency_checks=1
opcache.file_cache_only=1 makes sure that the in-memory opcache is disabled and only files are used, which is what you want for CLI. This should boost execution time by quite a bit.
In the php.ini for FPM, you will want to have the same settings but use opcache.file_cache_only=0, so in-memory opcache is used and the file cache is used as a fallback (which also makes FPM faster, because the file cache reduces warmup time when FPM is restarted or opcache is reset, because the cached files remain).
This way, CLI and FPM share the file cache, and FPM has the in-memory cache as a second primary cache for maximum speed. A great improvement in PHP7! Just make sure to choose a directory for opcache.file_cache that both CLI and FPM can write to, and that the same user does the writing/reading.
UPDATE 2017
I would not recommend to use the file cache with FPM anymore (only use it for CLI), because there is no way to reset the cache when setting opcache.validate_timestamps=0 - the file cache prevents PHP-FPM from recognizing any changes, because opcache_reset() or even a complete PHP-FPM restart does not affect the file cache and there is no equivalent for the file cache, so changed scripts are never noticed. I reported this as a "bug"/"feature request" in March 2016, but this is currently not seen as an issue. Just beware if you use opcache.validate_timestamps=0!
Leave it off. It's primarily there for use while debugging issues with OPcache itself.
The opcache.enable_cli option enables PHP OPcache when running PHP scripts from the command line (using the php command). However, keep in mind that for PHP 5.x the OPcache extension works by storing cached opcodes in the memory of the current process. This is only useful when the process that's running PHP is going to be handling multiple requests that can reuse these opcodes, like in a web server or under FastCGI. For a process like the PHP CLI, which runs one "request" and exits, it just wastes memory and time.
As per PHP docs:
opcache.enable_cli boolean enables the opcode cache for the CLI version of PHP. This is mostly useful for testing and debugging.
Therefore it should be disabled unless you're really need this.
This can be useful when you've some long-term migration process running from the command-line (personally I've tested OPcache v7.0.3 for CLI by running some extensive migration script and I didn't see much performance improvements).
I'm working on a Windows workstation, on which I use WampServer as my development platform, to write PHP applications which are then run on Linux.
I'm pretty used to APC on Linux, which is blazing fast and a must have for me. However, I'm always surprised to get no performance gain when I use it on Windows.
This leads to generation times close to 1 second per page, on applications relying heavily on the Zend Framework for example. Most of this time is spent parsing PHP files (I verified that by benchmarking include()s). The very same application can run 10x faster on Linux on MacOS.
The extension is properly loaded:
> var_export(extension_loaded('apc'));
true
Here is my config:
[APC]
apc.enabled = 1
apc.cache_by_default = 1
apc.enable_cli = 0
apc.shm_segments = 1
apc.shm_size = 64M
apc.max_file_size = 1M
apc.stat=1
Did anyone have a similar experience and has a few tips to share?
Edit: more information: I copied the apc.php file from the APC source archive to my web directory. There, I can see that the APC cache is at work, reporting more than 90% hits vs misses. Still, the speed does not increase though. It takes half a second to include a few dozen files from the framework, with or without APC. And on an equivalent machine on Linux, it's 10x faster.
I use WampServer and APC a lot with CakePHP and Drupal. I always notice a difference when using APC versus not.
It could be that your application is very heavy. Or that your desktop is that much slower than your servers that the APC file caching is not making a difference. APC reads the files into memory but your computer still has to process them.
I haven't found a solution to this problem so far, so I ended up trying Zend Server CE, and I can now notice the expected performance improvement when APC is enabled.
Not really a solution to my question, rather a workaround, but after one month of use, I'm pretty happy with Zend Server on my development machine.
The documentation on php.net is very spotty about causes of failure for APC writes. What kind of scenarios would cause a call to apc_store() to fail?
There's plenty of disk space available, and the failures are spotty. Sometimes the store operation will succeed and sometimes it'll fail.
For php cli it needs to be enabled with another option:
apc.enable_cli=On
In my situation it was working when running from a webbrowser, but not when executing the same stuff with php cli.
I had exactly the same situation.
I migrated my code from using Cron Jobs, to using Gearman Workers, which were managed through supervisord.
Everything Broke. I couldn't ever get caches to work through APC, and had to revert back to using filebase caching.
Eventually I figured out that when I was using cron jobs, I would load each page via wget, rather than command line. This difference, meant that supervisord, which would load my PHP scripts via command line, wouldn't work, because by default APC will not work through command line.
The fix....
apc.enable_cli=On
out of memory (allocated memory for apc, that is)
this asinine (and closed, for some reason) bug was my problem:
http://pecl.php.net/bugs/bug.php?id=16814
has to roll back to apc version 3.1.2 to get apc to work. no fiddling with apc settings in php.ini helped (i'm on mac os 10.5, using apache 2, php 5.3).
for me, this test script showed 3 "trues" for 3.1.2 and true/false/true for 3.1.3p1
var_dump( apc_store('test', 'one') );
var_dump( apc_store('test', 'two') );
var_dump( apc_store('diff', 'thr') );
http://php.net/manual/en/apc.configuration.php
the apc.ttl and apc.user_ttl settings on php.ini:
Leaving this at zero means that APC's cache could potentially fill up with stale entries while newer entries won't be cached.
Out of disk space or permission denied to the storage directory?
In addition to what Greg said, I'd add that a configuration error could cause this.
There's a bug in the version installed with ubuntu 10.04 and debian stable. If you replace the package with this version: http://packages.debian.org/sid/php-apc (3.1.7) it works as it should.
apc_store will fail if that specific key already exists and you are trying to write again to it before the TTL expires. Therefore you can pretty much ignore the return false because it really did fail but the cache is still there. If you want to get around this, start using apc_add instead. http://php.net/manual/en/function.apc-add.php
Does APC module in PHP when running in CLI mode support code optimization? For example, when I run a file with php -f <file> will the file be optimized with APC before executing or not? Presuming APC is set to load in config file. Also, will the scripts included with require_once be also optimized?
I know optimization works fine when running in fastcgi mode, but I'm wondering if it also works in CLI.
apc_* functions work, but I'm wondering about the code optimization, which is the main thing I'm after here.
Happy day,
Matic
The documentation of apc.enable_cli, which control whether APC should be activated in CLI mode, says (quoting) :
Mostly for testing and debugging.
Setting this enables APC for the CLI
version of PHP. Under normal
circumstances, it is not ideal to
create, populate and destroy the APC
cache on every CLI request, but for
various test scenarios it is useful to
be able to enable APC for the CLI
version of PHP easily.
Maybe APC will store the opcodes in memory, but as the PHP executable dies at the end of the script, that memory will be lost : it will not persist between executions of the script.
So opcode-cache in APC is useless in CLI mode : it will not optimize anything, as PHP will still have to re-compile the source to opcodes each time PHP's executable is launched.
Actually, APC doesn't "optimize" : the standard way of executing a PHP script is like this :
read the file, and compile it into opcodes
execute the opcodes
What APC does is store in opcodes in memory, so the execution of a PHP script becomes :
read the opcodes from memory (much faster than compiling the source-code)
execute the opcodes
But this means you must have some place in memory to store the opcodes. When running PHP as an Apache module, Apache is responsible for the persistence of that memory segment... When PHP is run from CLI, there is nothing to keep the memory segment there, so it is destroyed at the end of PHP's execution.
(I don't know how it works exactly, but it's something like that, at least in the principles, even if my words are not very "technical" ^^ )
Or, by "optimization" you mean something else than opcode cache, like the configuration directive apc.optimization ? If so, this one has been removed in APC 3.0.13
If you have CLI code that generates any configuration based on the environment, then the CLI code will think that APC isn't enabled. For example, when generating Symfony's DI container through the CLI, it will tell Doctrine not to use APC (details).
Also, I have not tested it but there's a chance APC may improve the speed of scripts for files included after a pcntl_fork(). Edit: I've asked the question about APC & pcntl_fork() here.
For completeness, to enable APC on the CLI (in Ubuntu):
echo 'apc.enable_cli = 1' > /etc/php5/cli/conf.d/enable-apc-cli.ini
Well, there's a good reason for APC in CLI Mode:
UnitTesting: I wanna do my unit test using an environment as close to the later production environment as possible. Zend Framework has an internal caching solution, which may use APC's Variable Cache as Storage Backend - and I wanna use this.
There is another reason to use it in CLI mode: some scripts are able to use it as a cache
I'm using APC to cache user variables (with the apc_store/apc_fetch commands). I've also enabled APC for the CLI with the option "apc.enable_cli = 1". However, the CLI version of PHP seems to access a different APC cache from the version used by Apache.
Is it possible to configure APC to use the same cache for both CLI and web invocations?
Not possible.. The only way to accomplish something like what your asking is to use something like memcacheD. Or run what you need to run through your webserver. What's running CLI that you cannot run via a web script with a cronjob?
You can use shm. This technology lend to access to Unix Shared memory. You can put some variable in shm and then in another scritp, even programmed in another languaje you can get the shared variables.
shm_put_var and shm_get_var.
It's slower than APC, but it's faster than memcached, redis, etc.
I hope It will help you, and I'm sorry for my English....
call your CLI as a CGI
/path-to/cgi-sys/php5.cgi /home/name/crons/engine.php
you would need a web server written in php -- the APC cache is shared only by forked child processes. If you had a php webserver, you could start a master cli, init apc, fork and load/run the web server in one child process, and fork and run your php cli script in another. Kind of a gross hack, huh. Fork and require(), I don't think the apc cache would survive an exec()