Php apc opcode cache - caching whole files vs variables - php

Are entire php files added to apc just by using and enabling it?
I understand how fetch and store works with variables, but when should this be used? Is the caching of whole files done automatically? If a variable is cached - should it only be a global variable or a user-specific variable?

Generally, you should cache Database responses that don't need to be updated frequently, but is accessed frequently. This data need not be from a database — could also be from a file or any type of data store. The key is to feed the most popular things from cache/memory to avoid i/o which is costly.
Take a look at this answer for a good explanation of Opcode caching. Opcode caching basically just stores your PHP file on memory, so that it can be interpreted quicker when run.
APC works automatically, and detects changes to your file to see if it needs re-caching. Quoting from the above answer:
The apc.stat option defines whether APC should examine the last modification date/time of a file to decide between using the opcodes from RAM, or re-compiling the file if it is more recent that the opcodes in RAM.
Also, to answer your global vs user specific question. It all depends on exposure, you should cache anything with large amounts of exposure. But generally user-specific data will have less exposure than global data.

Related

(How) does PHP cache script and custom INI-files?

Currently I'm storing the configuration for my PHP scripts in variables and constants within another PHP script (e.g. config.php).
So each time a script is called, it includes the configuration script to gain access to the values of the variables/constants.
Since INI-files are easier to parse by other scripts, I thought about storing values for my configuration in such a file an read it using parse_ini_file().
In my notion PHP keeps script-files in memory, so including a script-file does (usually) not cause IO (Or does Zend do the caching? Or are the sources not cached at all?).
How is it with reading custom INI-files. I know that for .user.ini there is caching (see user_ini.cache_ttl), but does PHP also cache custom INI-files?, or does a call to parse_ini_file() always cause IO?
Summary
The time required to load configuration directives (which is not the same as the time needed by the app to perform those directives) is usually negligible - below one millisecond for most "reasonably sized" configurations. So don't worry - INI, PHP, or JSON are, performance wise, all equally good choices. Even if PHP were ten times faster than JSON, that would be like loading in 0.001s instead of 0.01s; very few will ever notice.
That said, there are considerations when deciding where to store config data.
.ini vs .php config storage
Time to load: mostly identical unless caching is involved (see below), and as I said, not really important.
ease of use: .ini is easier to read and modify for a human. This may be an advantage, or a disadvantage (if the latter, think integrity check).
data format: PHP can store more structured data than .ini files, unless really complicated workarounds are used. But consider the possibility of using JSON instead of INI.
More structured data means that you can more easily create a "super configuration" PHP or JSON holding the equivalent of several INI files, while keeping information well isolated.
automatic redundancy control: PHP file inclusion can be streamlined with require_once.
user modifications: there are visual INI and JSON editors that can allow a user to modify a INI or JSON file while keeping it, at least, syntactically valid. Not so for PHP (you would need to roll your own).
Caching
The PHP core does not do caching. Period. That said, you'll never use the PHP core alone: it will be loaded as a (fast)CGI, an Apache module, et cetera. Also you might not use a "barebones" installation but you could have (chances are that you will have) several modules installed.
Both the "loader" part and the "module" part might do caching; and their both doing this could lead to unnecessary duplications or conflicts, so it is worth checking this out:
the file (but this does not change between INI, JSON and PHP files) will be cached into the filesystem I/O subsystem layer and, unless memory is really at a premium, will be loaded from there (on a related note, this is one of the reasons why not all filesystems are equally good for all websites).
if you need the configuration in several files, and use require_once in all of them, the configuration will be loaded once only, as soon as it is needed. This is not caching, but it is a performance improvement nonetheless.
several modules exist (Zend, opcache, APC, ...) that will cache all PHP files, configuration included. They will not cache INI files, though.
the caching done by modules (e.g. opcache) can (a) ignore further modifications to the file system, which means that upon modifying a PHP file, you'll need to somehow reload or invalidate the cache; how to do this changes from module to module; (b) implement shortcuts that might conflict with either the file system data management or its file structure (famously, opcache can ignore the path part of a file, allowing for much faster performances unless you have two files with the same name in different directories, when it risks loading one instead of the other).
Performance enhancement: cache digested data instead of config directives
Quite often it will be the case that depending on some config directive, you will have to perform one of several not trivial operations. Then you will use the results for the actual output.
What slows down the workflow in this case is not reading whether, say, "config.layout" is "VERTICAL" or "HORIZONTAL", but actually generating the layout (or whatever else). In this case you might reap huge benefits by storing the generated object somewhere:
serialized inside a file (e.g. cache/config.layout.vertical.html.gz). You will probably need to deploy some kind of 'stale data check' if the layout changes, or some kind of cache invalidation procedure. (For layouts specifically, you could check out Twig, which also does parameterized template caching).
inside a keystore, such as Redis.
in a RDBMS database such as MySQL (even if that's overkill - you'd use it as a keystore, basically).
faster NoSQL alternatives such as MongoDB.
Additional options
You will probably want to read about client caching and headers, and possibly explore whatever options your hosting offers (load balancers, HTTP caches such as Varnish, etc.).
parse_ini_file() uses standard operations to convert the file into an array.

Is there a way to define constants that persist in memory when PHP loads?

Is there a way to define constants that boot into memory when the PHP process starts on the server? If so, can it be done with arrays, classes, and functions as well?
Before people start listing the different ways of declaring things that will be available across pages and scopes: I'm not asking this from a coding convenience, but rather a performance perspective.
It seems like a waste to keep loading things that never change, from pages or databases etc, on every script execution. Being a server-side process, I would think PHP has some way to read things into memory once and have them always available.
What you are looking for is an opcode cache. Opcode caches work by storing the compiled contents of PHP files in shared memory, then using that data to short-circuit the standard code parsing process when the file is included/required in the future.
The canonical opcode cache at this point is the PHP opcache extension, but a number of other opcode caches exist, including APC and XCache.
Opcode caches do not cache data from databases. There are other extensions which you can use to assist in this process, though, such as APCu which stores them in shared memory, or memcached which stores them in an external process. None of this is automatic, though, as caching data from a database requires some application knowledge to know what is useful to cache, and to handle cache invalidation when you update the database.
In general php is a single treaded environment and it does not actually run constantly (unlike java). Php starts working only when receives a command to do so. Then it parses the code into opcode and eventually executes it. And that technically happens on every request (or CLI command).
However, there are several ways how you can cache the opcode with not much efforts with APC: http://www.php.net/manual/en/book.apc.php

Is APC better cache option than MySQL?

Whenever I needed to cache some information I relied on timestamps and MySQL, storing the data into a database and fetching it that way. I just read about APC.
APC is so much easier but is it worth converting my previous cache methods to switch to APC besides just less SQL's going through and cleaner code?
If you already have a database running and doing most of your things the first step to improve your performance is to peroperly tune the database. MySQL, properly configured, is very fast.
Obviously at some point in time it isn't fast enough anymore and one needs further caches. When caching one thing to consider is that your data might not be consistent anymore. Meaning that you might update data in your primary store (the database) but others stll read an outdated cache entry
Now you've mentoned APC as a possible solution: APC is two related but different things:
An opcode cache for the PHP scrip
A shared memorz cache for PHP user data
An opcode cache works by storing the compiled PHP script in memory. So when requesting a site the PHP interpreter doesn't have to read the file from disk and analyze the code but can directly execute it. This gives a major boost and is always a good thing.
A shared memory cache takes any PHP variable (well, there are a few exceptions ...) and stores it in shared memory in the system, so all PHP processes on the same machine might read it. So if you store the result of a database query inside APC you save time as access to shared memory is very fast compared to querying a database (sending the query to a different machine, parsing it, executing it, sending the result back ...) but as said in the begginning you have to mind that the data might be outdated. And also mind that all data is stored in memory. So depending on the amount of avilable RAM there are limitations in what can be stored. Another big downside of this is that the data is stored in memory only. This means whenerver the system goes down the cache will be empty and everything in there will be lost.
To answer literally to the question, yes. Mysql is not a cache, APC is, and thus, is better.
Mysql is an storage option to implement a cache on top of it, but you are implementing the cache with those timestamps you mention and whatever logic you are doing with them. APC is a complete implementation of a cache, both for data and for code.
Performance wise, accessing the local APC cache will always be infinitely faster than accessing a mysql database. Keyword there is local, APC is not distributed (as far as I know), so if you want to share your cache, you'll need an external cache system, such as memcached.
Generally, APC will be much, much faster than MySQL, so it's well worth the time to look into it and consider switching from one system to the other. And, as you mention, you will be firing less SQL queries to the database.
More information can be found via Google, I came across the following:
http://www.mysqlperformanceblog.com/2006/08/09/cache-performance-comparison/

PHP ob_start vs opcode APC, explain differences and real world usage?

Premise: I'm not trying to reinvent the wheel, I'm just trying to understand.
Output caching can be implemented easily:
//GetFromMyCache returns the page if it finds the file otherwise returns FALSE
if( ($page = GetFromMyCache($page_id)) !== FALSE )
{
echo $page; //sending out page from cache
exit();
}
//since we reach this point in code, it means page was not in cache
ob_start(); //let's start caching
//we process the page getting data from DB
//saving processed page in cache and flushing it out
echo CachePageAndFlush(ob_get_contents());
explained well in another article, and also in another answer.
But then comes APC (that will be included in PHP6 by default).
Is APC a module that once installed on the server, existing PHP code will run faster without modification?
Is APC automatic?
Then, why are there functions like apc_add?
How do we cache entire pages using APC?
When APC is installed, do I still need to do any caching on my part?
If APC is going to save hosting providers money, why do they not install it? (I mean they should be racing to install it, but I don't see that happening.)
Does installing APC have disadvantages for these hosting providers?
APC is an opcode cache:
The Alternative PHP Cache (APC) is a free and open opcode cache for
PHP. Its goal is to provide a free, open, and robust framework for
caching and optimizing PHP intermediate code.
This is not the same as a template cache (what you are demonstrating), and it has little impact on output buffering. It is not the same thing.
Opcode caching means cache the PHP code after it has been interpreted. This could be any code fragment (not necessarily something that outputs HTML). For example, you could stick classes and the template engine itself in an opcode cache. This would dramatically speed up your code, as the PHP interpreter doesn't need to "interpret" your code again, it can simply load the "interpreted" version from the cache.
Please do not confuse output buffering with a cache. There are many levels of caching, for example, two of the most common that you may be familiar with.
Caching the session
A very basic version of this is a cookie that stores some settings. You only execute the code that "calculates" the settings once (when a user logs in), and for the rest of the session, you use the "cached" settings from the cookie.
Caching the rendered template
This is done when a page that needs to be generated once, but doesn't change very often. For example a "daily specials" page, which is a template. You only generate this once, and then serve the "rendered" page from cache.
None of these use APC
Is APC makes the PHP to run faster on its own?
Yes. In a way. The benefit hugely differs though.
When using APC do I still need to cache rendered HTML?
Bytecode is NOT like resulting HTML. It is the same program as a regular PHP script.
Even with APC enabled, PHP have to process data and render HTML.
I hope you understand the difference now.
APC cache provides both byte-code cache and memory-based storage to store user data.
So, you can also use it to store some user-defined data.
And store whole rendered pages as well (I don't understand your confusion here - what is that 'page' data type you are talking about? Isn't the ob result being just a regular string?).
However, caching of the resulting HTML is not that easy as you imagine.
Premature optimization is the root of all evil.
Start optimizing your site only when you have a reason.
why are Web Hosters waiting to install APC?
There are several reasons. But one is enough - bytecode cache won't make any profit for the usual PHP-based ugly homepage ecommerce site.
APC caches bytecodes. PHP turns source code you write into these when a file gets requested or included, and then gets rid of them. With APC the bytecode stays around.
ob_start turns on an output buffer. It can be used to cache one effect of the program code, which is the text it prints.
Use APC if you want your program to run faster and consume less CPU power. It has no effect on database throughput.
Cache ob_start output if you only want to run the program every now and then and just statically serve its last output. This saves database throughput, at the price of information freshness and personalization.
APC is good when each page request conveys new information, or information specific to the user.
Cache ob_start output if you are running some heavyweight calculations or data access and it's okay that everyone gets the same not-quite-fresh output.

PHP APC, educate me

I'm currently implementing memcached into my service but what keeps cropping up is the suggestion that I should also implement APC for caching of the actual code.
I have looked through the few tutorials there are, and the PHP documentation as well, but my main question is, how do I implement it on a large scale? PHP documentation talks about storing variables, but it isn't that detailed.
Forgive me for being uneducated in this area but I would like to know where in real sites this is implemented. Do I literally cache everything or only the parts that are used often, such as functions?
Thanks!
As you know PHP is an interpreted language, so everytime a request arrives to the server it need to open all required and included files, parse them and execute them. What APC offers is to skip the require/include and parsing steps (The files still have to be required, but are stored in memory so access is much much faster), so the scripts just have to be executed. On our website, we use a combination of APC and memcached. APC to speed up the above mentioned steps, and memcached to enable fast and distributed storing and accessing of both global variables (precomputed expensive function calls etc that can be shared by multiple clients for a certain amount of time) as well as session variables. This enables us to have multiple front end servers without losing any client state such as login status etc.
When it comes to what you should cache... well, that really depends on your application. If you have a need for multiple frontends somewhere down the line, I would try to go with memcached for such caching and storing, and use APC as an opcode cache.
APC is both an opcode cache and a general data cache. The latter works pretty much like memcached, whereas the opcode cache works by caching the parsed php-files, so that they won't have to be parsed on each request. That can generally speed up execution time up quite a bit.
You don't have to implement the opcode caching features of APC, you just enable them as a php module.
APC cache size and other configuration information is here.

Categories