I'm struggling to find any logic in the way APC clears up its old entries.
Especially with user entries, I notice the fragmentation quickly increasing to unexpected levels.
Although apc.ttl and apc.user_ttl are set at 3600, I notice a LOT of old entries in the APC cache which are not getting cleared. I have repeatedly increased the size of the memory for APC, but it only makes it last a little longer before reaching 100% fragmentation.
So, why could this be happening? Actually I would consider this a bug in APC, it's just not normal behaviour. I would expect some APC process to clear out old entries from time to time.
Also, could it lead to the conclusion that it would be better to use another caching system for PHP, and only use APC as an opcode cache (where the lack of cleaning is less of a problem)?
If you want to ensure old values are removed. You need to explicitly remove it.
I use a combination of APC and memcached in my applications. APC provides opcode caching as well as caches local data that is likely to remain unchanged (Like config files). All other objects are cached in memcached using some sort of a read through logic. (Gets cleared if data is changed)
When I do a new release, I restart APC (via apache or php if its a separate process). That will clear the APC cache and the config files will get reloaded shortly afterwards. I will restart memcached if the objects have changed significantly enough to cause issues if its loading old cache data.
Related
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/
So this is whats bothering me. I just installed APC cache and Im testing it.
When using APC Admin interface, in apc.php file, I can see all the info about APC etc.
When I go to System Cache Entries I can see that every script i invoke gets written there.
So does this means that APC Cache works out of the box? I can just install APC cache and it already speeds up my application by caching scripts? And if I want I can then cache variables to make it even faster?
Hope you get the question, its probably simple to someone with more experience with APC.
Its I know i can add some variables to cache, and then get them out and that will speed up my app. But is it true, that APC will speed up the app and cache scripts all by him self?
And is there any good documentation where I could learn more about APC?
Yeah, APC "just works". Anyone running PHP in production without APC/(other opcodecache) is missing out on the easiest performance improvement they can readily achieve.
A few caveats though.
If you are in development, you can still run APC, however, you probably want to enable stat calls. This means that APC will check the last modified of your files.
apc.stat = [1|0]
So if you don't have stat calls enabled, and you change a file and APC has already cached it, then it won't observe your changes, and you will continue using the cached opcode.
As you have mentioned, APC isn't just for opcode caching, it is also useful for user space caching. You have your system cache and your user cache.
You can store things against your user cache by just performing something like:
apc_store("fooKey", "barValue");
I'm primarily wondering what the speed difference is in accessing the object cache of APC v. memcached (NOT op-code cache). The primary advantage of memcached is that it is distributed and not restricted to the local machine. However, since it is over the network, there's is some sort of latency involved.
I was wondering whether the speed difference between accessing APC (on the machine) and memcached (on another server) is big enough to warrant having a staged caching scheme, where the program first tries APC, then memcached, and finally the database if all else fails.
Like most everything else: it depends.
If you have a lot of calculations and can store the results then caching will speed things up. If you're just basically storing rows from the database then in memory caching will help but memcached may not add a huge amount of difference vs. a database (assuming the db queries are all simple). On the other hand if you're doing complex queries, or a lot of programmatic work to create something, then caching makes much more sense.
To give you an example, I recently worked on a site that was written by a 3rd party contractor who did not do any performance work during design. It was slow as an ox because it had a lot of unoptimized includes and such. Adding APC basically improved the performance by 10x. Adding memached decreased load times by 10 - 20 ms.
If you're far enough along then do some performance testing (look up xdebug, or another tool) and see where your bottlenecks are, then plan accordingly.
Keep in mind that if you fill up your APC cache with other things then APC will have to re-calculate the op-code for your pages again. This can cause problems if the pages keep removing objects, then once the page runs the objects keep removing pages. Not fun.
Just be safe and don't be tempted to use APC for anything but config values which won't cause your pages to be removed to make space.
TL;DR Once APC gets full your site will slow down and your server will work much harder.
I am trying to move from the typical combination of APC (for opcode) and Memcache (for my userdata) to a purely apc based cache. Given my usage structure it makes sense and performance is higher.
But unlike before, where the apc cache was limited to a reasonable size and did not affect my data cache, I am now worried that the opcode cache might grow relatively large so that the sum of opcode cache an datacache exceeds the limit. As far as I understand, this would result in a flush of the total cache.
Is there a way to mimic the behaviour, as if apc was only an opcode cache and limit the opcode cache size to a reasonable limit, leaving the rest for user data?
Or should I try setting lower ttl values for the opcode cache, so it always gets flushed first?
It turned out, that my question is irrelevant. Due to the cache fragmentation problems, the cache is quickly marked as full. (see other posts on stackoverflow). As a consequence apc user cache should only be used selectively.
I am using memcache for cacheing objects, but would like to add in addition an opcode accelerator like APC. Since they both involve cacheing, I am not sure if they will be "stepping on each others toes", i.e. I am not sure if memcache is already an OP code accelerator.
Can someone clarify? I would like to use them both - bit for different things. memcache for cacheing my objects and APC for code acceleration
Memcache is more along the lines of a distributed object cache vs something like APC or XCache, which stores PHP bytecode in memory so you avoid having to parse it each time. Their main purposes are different.
For example, if you had a very CPU intensive database query that people often requested, you could cache the resulting object in memcache and then refer to it instead of re-running that query all the time.
APC & XCache do have similar object caching features, but you are limited to the host machine. What if you wanted 10 different servers to all have access to that one object without having to re-do the query for each server? You'd just direct them to your memcache server and away you go. You still get a benefit if you only have a single server because using memcache will help you scale in the future if you need to branch out to more boxes.
The main thing to consider is if you think your app is going to need to scale. Memcache has more overhead since you have to use a TCP connection to access it, versus just a function call for APC/Xcache shared objects.
However, Memcache has the following benefits:
Faster than the disk or re-running query.
Scales to multiple servers.
Works with many different languages, your objects are not locked into PHP + APC/Xcache only.
All processes/languages have access to the same objects, so you don't have to worry if your PHP child processes have an empty object cache or not. This may not be as big a deal if you're running PHP-FPM though.
In most cases, I would recommend caching your objects in memcache as it's not much harder & is more flexible for the future.
Keep in mind that this is only regarding caching objects. Memcache does NOT have any bytecode or PHP acceleration features, which is why I would run it side-by-side with APC or Xcache
yes you can use them both together at the same time.