Setup is a Linux box running apache with apc. TwoLevels-Cache is planned as apc + file. Does Zend two level cache save everything to second level even the data kept in first level?
I was wondering what happens if I restart my server. Will the data in the first level apc cache be lost or can it be retrieved from second level file cache?
From the look of the code, the answer is "it depends". Data will be stored in both caches if the priority is high enough and the fast cache is not full or filling fast. Otherwise it will only be stored in the 'slow' cache.
However I'm sure that the APC cache would be empty after a reboot. There wouldn't be any sensible way for PHP to detect this and warm that cache back up for you, and no real reason for it to. Your app should not rely on cache data being present, and should regenerate it if it is missing.
Related
I have a web tier in AWS running Nginx+PHP-fpm using memcache on ElastiCache for sessions. Over the last 6 months or so we've been experiencing a very strange issue where every so often perhaps 6 weeks or so the ElastiCache node runs out of memory and starts evicting keys which leads to some users being loosing session, being logged out and of course frustrated and loosing their place in the app.
I've tried several things. One being leveraging the php-memcached module in ini:
session.save_handler = memcached
session.save_path = "<aws elasticache dns:port>"
And yes I verified that the save_path url I'm actually using is correct and receiving network connections. I've also verified through CloudWatch metrics that the cache node is indeed receiving network connections and data.
This configuration did not work, so I replaced it with a Zend framework session manager and save handler. I verified through phpinfo() that session.save_handler was set to user and also verified that the browser is getting the right cookie that I configured in Zend session.
Still, we're having the same problem as illustrated in the following CloudWatch screenshot:
The vertical spikes in memory are I believe due to memcache clearing expired keys which seems to happen every 24 hours. The very last (far right) spike is where I rebooted the node. The strange thing is that everytime it clears keys, it doesn't clear enough. We end up with an ultimately downward trend in available memory which at some point causes memory to run out and memcache to start evicting keys.
I'm at a loss as to what could be the problem and what to try next in an effort to debug. Any thoughts? Thanks!
This isn't a bug, just how Memcached is supposed to work. By the very nature of being a cache, the data should be (relatively) ephemeral. If you're current node doesn't have enough memory to support all the values you are trying to store it has no choice but to evict keys. If you're only storing sessions and you're filling up an entire cache instance, you're best option would be to upgrade the size of your cache node (thats a lot of sessions!), or in AWSs case, add another node.
If you're storing other data on the cache node as well, set intelligent expiration times for those items so they expire and free space up periodically.
Update: I'll also add, if you're comfortable using cookies, having a time-limited cookie to recreate dropped sessions is a nice fill-in as well. Basic "Keep my logged in" code should suffice
I'm working with a couple of Web Servers behind a Load Balancer and I can enable Sticky Sessions to hold a user to the one specific Web Servers - this will work.
I have been reading about PHP Sessions & MemCache. I must say what I've read is a touch confusing as some pages say its a good idea and others the opposite.
Questions:
is it possible to keep php sessions in memcache?
is it better to use sticky sessions over memcache?
what are the problems with php sessions in memcache - note: I can get enough cache (amazon so its expandable).
1: YES. And I strongly recommend storing PHP sessions in Memcached. Here's why:
Memcached is great for storing small chunks of data that are frequently accessed by the database and filesystem.
Memcached was designed specifically for sessions. It was originally the brainchild of the lead developer of livejournal.com and later used to also cache the content of users' posts. The benefit was immediate: most of the action was taking place in memory. Page load times greatly improved.
Thankfully, PHP and Apache have an easy implementation to handle sessions with Memcached. Simply install with a few shell commands
example for Debian:
sudo apt-get -t stable install php7.4-memcached
and
change your php.ini settings to something similar to:
(taken from https://www.php.net/manual/en/memcached.sessions.php)
session.save_handler = memcached
; change server:port to fit your needs...
session.save_path = "localhost:11211"
The key is the session.save_path
It will no longer point to a relative file path on your server.
APC was mentioned - APC for the caching of .php files used by the program. APC and Memcached will reduce IO significantly and leave Apache/Nginx free to server resources, such as images, faster.
2: No
3: The fundamental disadvantage of using Memcached is data volatility
Session data is not persistent in Memcached. So if and when the server crashes, all data in memory is lost. Everyone will have to log in again.
And then you have memory consumption...
Remember: the sessions are stored in the memory. If your website handles a large number of concurrent users, you may have to shell out a little extra money for a larger memory allocation.
1. Yes, it is possible to keep PHP sessions in memcached.
The memcache extension even comes with a session handler that takes very little configuration to get up and running. http://php.net/manual/en/memcached.sessions.php
2. Memcache/Sticky Sessions
I don't really know which is "better". I feel this is going to be one of those "it depends" answers. It likely depends on your reasons for load balancing. If a small number of users cause lots of load each, or if it's a large number causing a small load each.
3. Cons of Memcache
There are probably 2 main cons to using memcache for sessions storage.
Firstly, it is volatile. This means, if one of your memcached instances is restarted/crashes etc. any sessions stored in that instance are lost. While if they were using traditional file based sessions, they will be still there when the server returns.
Secondly and probably more relevant, memcached doesn't guarantee persistance, it is only meant to be a cache. Data can be purged from memcached at any time, for any reason. While, in reality, the only reasons data should be purged is if the cache is nearing its size limits. The least recently accessed data will be expelled. Again, this might not be an issue, as the user is probably gone if their session is stale, but it depends on your needs.
If you want to use "memcacheD" extension not "memcache" (there are two different extensions) for session control, you should pay attention to modify php.ini.
Most web resources from Google is based on memcache because it's earlier version than memcacheD. They will say as following:
session.save_handler = memcache
session.save_path = "tcp://localhost:11211"
But it's not valid when it comes to memcacheD.
You should modify php.ini like that:
session.save_handler = memcached
session.save_path = "localhost:11211"
There is no protocol indentifier.
From: http://php.net/manual/en/memcached.sessions.php#99646
As my point of view its not recommended storing sessions in Memcached.If a session disappears, often the user is logged out,If a portion of a cache disappears or either due to a hardware crash it should not cause your users noticable pain.According to the memcached site, “memcached is a high-performance, distributed memory object caching system, generic in nature, but intended for use in speeding up dynamic web applications by alleviating database load.” So while developing your application, remember that you must have a fall-back mechanism to retrieve the data once it is not found in the Memcached server.
I'm using PHP APC on production servers of a web service with 10M's hits/day successfuly for a long time.
I'm considering offloading much more data to the APC local cache.
Theoretically it looks to me that since APC call is mainly a local memory access. It should not become an issue to call it 10,000s of times/sec. As far as I can tell its limits can be in the memory size but as long as the server has free CPU it should not have performance or corruption issues at high rates.
Is there any limit I'm not aware of that might prevent me from using APC's local object cache in very high rate on app server (ubuntu).
Update:
Apparently according to the answers below my question wasn't clear. I'm not looking for alternaive caching options (memcache,redis etc..). My question is whether there is any concern or limit in using local APC in very high rates and read concurrency.
I'm personally a big fan of using memcached for this kind of storage. It has several advantages:
It's a program that focuses entirely on the storage, and development of memcached will always focus on that. APC is primarily a cache for code, which just happens to offer some access to user storage.
When you reload or restart Apache (or whatever webserver you use), APC's cache gets emptied. When you use a standalone solution such as memcached, you can control when the cache gets emptied. This is really something that was very important in my case, as I sometimes have to make changes to Apache's configuration and really don't want to clear the cache when I do, as it creates a large CPU spike (loading data into the cache again).
It has the possibility to create a distributed cache, making it more scalable. When you have to add a second server because your website becomes large, you don't want two caches which cache the same stuff. memcached scales well, while APC's cache doesn't.
There are many other advantages of using memcached over APC's user cache, but for me these were the primary three reasons to not use APC's user cache. I do use APC, of course, just not the user cache.
I wrote a rather small skeleton for my web apps and thought that I would also add a small cache for it.
It is rather simple:
If the current page exists as a file in the cache and the file isn't too old, read it out and exit instead of rebuilding the page
If the current page isn't cached/outdated recalc the page and save it
However, the bad thing about it is:
My performance tests with a page that receives 40 relatively long posts via a MySQL query said that with using the cache, it took even longer to handle a single request (1000 tests each)
How can that happen?
How can doing a MySQL query, looping through the results the first time, passing the results to the template and then looping through the results for the second time be faster than a filemtime() check and a readout?
Should I just remove the complete raw-PHP cache and relieve on the availability of some PHP cache like memcached or so?
Premature optimization is the root of all evil. If you don't need a cache, don't use a cache.
That being said, if you are content to not serve up dynamic content per request, you might want to look into using a caching proxy such as varnish and cutting out PHP and the webserver entirely. There's quite a bit of overhead to get to even your first line of PHP, and serving static files through PHP is a little dirty.
If you just want to cache elements, something like memcached or APC's cache is the way to go. APC has the advantage of being more readily available (you should have APC installed on your servers for the opcode cache if you care at all about performance) and memcached has the option of letting you have a cache that's accessible by multiple webservers (and/or multiple caches)
I don't think so, there seems to be some other problem depending on your implementation. Here are couple of great resources more about it:
http://www.mnot.net/cache_docs/
http://blog.digitalstruct.com/2008/02/27/php-performance-series-caching-techniques/
Possible -
If you are using apc and mysql query cache (default on) , then your php code is already executed and stored as opcode in apc and if you hit the same query repeatedly then the mysql query cache will cache the database results too. In this case most of the data comes from memory so your file read could be slower. The real benefit of this approach is that you will be saving the number of mysql connections but may not be performance.
Using a caching proxy like squid should be the ideal solution in your case so that the page is served directly from cache till it expires. Another optimization for the above situation would be to just cache the mysql output in memcache which would be better than hitting mysql and query cache is small in size. Lastly if you indeed want to cache the mark up generated, you could use output buffering (ob_start) and store the output directly in memcache.
I think not.
The slowest part of the application is probably the database traffic.
If you include an HTML / PHP cached file it should be faster.
We having been using multiple webservers for our cakephp application,
problem is there are two cache directories, server 2 is clearing his cache before doing any insertion in his database. But server 1 doesn't know the about the database has been changed , so server 1 cached is not cleared
When new web request comes to server 2 , he creates new cache files and return good results. BUT when it comes to server 1 , he show same old results :( .
I wonder is there any way we can share the cache directory among various physical servers, without compromising with performance.
We may increase the web servers, so please recommend good long term solution for this
Thanks for reading
I would look into using Memcache as for your caching mechanism. You can set up the Memcache daemon (memcached) on one server and then connect both servers to the one cache. See the core.php for set up details. Of course you will also have to install the memcache php ext and the daemon, but it will be worth it.
Easiest way would be setting up the cache directory to be served from an nfs (file) server. You wouldn't have to change anything else.
For performance i'd also stick to Memcache as bucho said, but it will likely require you to change your application code.