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.
Related
I have three servers for single domain
I'm using nginx as loadbalancer.
I want to share php sessions across these servers.
My application is heavily dependent on session. storing sessions in files is bad idea. i'm using memcached for this.
how exactly and efficiently should i configure memcached to read and write sessions and share between servers quickly.
or any other good alternative suggestion.
As I read your question, it looks like you installed Memcache on every server (and that's why you ask about "sharing between servers" ?).
What I would do is have a server where you ONLY have Memcached on it. Each web server would connect to your instance of Memcache. You can also have a pool of Memcache servers if needed and Memcache will take care of distributing your data and sessions correctly.
First, you may want to change the way sessions are handled in PHP (for each server) in order to read session's data in Memcache. Your php.ini file will need this:
[Session]
; Handler used to store/retrieve data.
session.save_handler = memcache[d] ; memcache or memcached
session.save_path = "127.0.0.1:11211"
See how Session Handlers work. Note that you can use memcache or memcached extension. They are not the same.
Here is the documentation for both extensions:
Memcache
Memcached
If you want more details about the right memcache to pick, I suggest you check this:
https://serverfault.com/questions/63383/memcache-vs-memcached
Note that storing sessions in Memcache can be problematic. If Memcache is stopped (for whatever reason) you will loose all data you have in it. You may want to consider storing your sessions in a database and also have them in Memcache to speedup the process.
You can build a custom Session Handler to do that and make sure it suits your needs. You can read more about The SessionHandler class.
Finally, if you are open to suggestion, I would also consider using Redis instead of Memcache as it offers more features and will enable you to reload data if shutdown correctly.
Besides the drawback of when you restart memcached all sessions are lost and users logged out, what are any other drawbacks for using memcached for storing PHP sessions data instead of files. Any security concerns? Is performance better using memcached instead of standard files on disk?
Although, many have been able to optimize database performance through the use of Memcached it may not be the best solution for every situation.
Some of the drawbacks of Memcached:
Size Requirement
Not much Documentation support
Volatility (If a Memcached server instance crashes, any object data stored within the session is gone)
Security (There is no authentication built into Memcached).
But still Memcached is a good choice in many apps because of following reasons:
Memcached can compensate for insufficient ACID properties and it never blocks.
Memcached is cross-platform
Cross-DBMS
Its Cheap
Lets look at the brighter side!
Not a security concern specific to using memcached for sessions, but rather something I often come along: You absolutely must make sure that your memcached instances are either using unix sockets, or - if they're bound to a part - their port is blocked. Otherwise, people can just telnet in and view, modify and delete (session) data.
Also, as the name implies, it is a caching solution, not a storage solution. As such, if you decide to use memcached for session storage, you ought to have it either database backed or file-storage backed, so if there is a cache miss (entry deleted due to time out, manual removal, flush or because the assigned memory was full and it got pruned), it can check a more persistent type of storage before saying "nope, it isn't there".
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.
My setup:
4 webservers
Static content server (NFS mount)
2 db servers
2 "do magic" servers
An additional 8 machines designated multi-purpose.
I'm writing a wrapper for three caching mechanisms so that they can be used in a somewhat normalized manner: Filesystem, Memcached and APC. I'm trying to come up with examples for use (and what to actually put in each cache).
File System
Handles content that we generate and then statically serve. RSS feeds, old report data, user specific pages, etc... This is all cached to the static server.
Memcached
PHP session data, MySQL query results, generally things that need to be available across our systems. We have 8 machines that can be included in the server pool.
APC
I have no idea. The two "do magic" servers are not part of any distributed system, so it seems likely that they could cache query results in APC and work from there. Past that, I can't think of anything.
Query Caching
Given the nature of our SQL use, query caching reduces performance. I've disabled this.
In general, what types of data should be stored where? Does this setup even make sense?
Is there any use for an APC data cache in a distributed system (I can't think of one)?
Is there something that I'm missing that would make things easier or more efficient?
Edit: I've figured out what Pascal was saying, finally. I had it stuck in my head that I would only be moving a portion of my config / whatever to APC, and still loading the rest of the file from disk. Any other suggestions?
I'm using the same kind of caching mecanism for some projects ; and we are using APC + memcached as caching systems.
There are two/three main differences between APC and memcached, when it comes to caching data :
APC access is a bit faster (something like 5 times faster than memcached, if I remember correctly), as it's only local -- i.e. no network involved.
Using APC, your cache is duplicated on each server ; using memcached, there is no duplication accross servers
whic means that memcached ensures that all servers have the same version of the data ; while data stored in APC can be different on each server
We generally use :
APC for data that has to be accessed very often, is quick to generate, and :
either is not modified often
or it doesn't matter if it's not identical on all servers
memcached for data that takes more time to generate, and/or is less used.
Or for data for which modifications must be visible immediatly (i.e. when there is a write to the DB, the cached entry is regenerated too)
For instance, we could :
Use APC to store configuration variables :
Don't change often
Are accessed very often
Are small
Use memcached for content of articles (for a CMS application, for example) :
Not that small, and there are a lot of them, which means it might need more memory than we have on one server alone
Pretty hard/heavy to generate
A couple of sidenotes :
If several servers try to write to the same file that's shared via NFS, there can be problems, as there is no locking mecanism on NFS (as far as I remember)
APC can be used to cache data, yes -- but the most important reason to use it is it's opcode caching feature (can save a large amount of CPU on the PHP servers)
Entries in memcached are limited in size : you cannot store an entry that's bigger than 1M (I've sometimes run into that problem -- rarely, but it's not good when it happens ^^ )
I want to store information (sessions and a lot of strings) in RAM and I don't know if I should use a tmpfs or a memcached server. Someone did some benchmark and knows which one is faster? It's needed for some ajax scripts that requests informations every 1-5 seconds per user who is logged in, like a webchat in PHP. So PHP has to connect to memcache quite often.
The advantage of using tmpfs whould be that I can create a lot of files and have a structur (dirs), while I only have a key-value system in memcached, but there i could use arrays or objects to store information.
CPU load whould be interesting, too, if there is any difference.
Thanks.
Just a couple points
tmpfs or ramdisk are more mature than memcached (been around longer but both are stable
tmpfs is scalable (you can resize or increase as needed without loosing the contents of tmpfs
memcahced is great if you need memory on another machine or if you need to share that information between machines.
local file/socket/pipe performance is ALWAYS faster than a network socket and accessing a file in tmpfs is the same as any other file so it does not require any 3rd party libraries.
If you don't expect you data to our grow the memory on your server use tmpfs.
If you must share the data between servers or want to store more data that whats fits into the RAM on your local server use memcahed.
I don't really know about speed, but here are a couple of things to consider about memcached :
memcached is based on a cluster-type architecture : you can add as many physical servers as you want, install a memcached daemon on it, and you have more memory in your cluster
which means there is virtually no limit to the amount of data you can cache, using memcached : just add a couple of servers if you need more memory
on the other hand, with tmpfs, you're limited by the amount of RAM available on each server
memcached is a caching mecanism ; it's not made to store data ; which means :
when there is not enough memory left to store a new item, the old items are removed from the cache
each item has a lifetime ; when it's expired, the item is deleted from the cache
memcached is shared : you can have several PHP servers accessing a single memcached cluster
There are many existing libraries based on memcached, or created to access memcached
including some session mecanism for PHP
and several caching libraries
neither memcached nor tmpfs are made for persistence -- if you need your data to persist (i.e. still be available even after a reboot), you need to use something like a database.
In the end, not sure about tmpfs, but I would probably use memcached, at least when it comes to :
sessions
caching
Why ? Because it's :
mature -- used a lot, there are many libraries, ...
and scalable
Both ramdisk and memcached are blazing fast.
I don't think speed will have any importance, if you are using MySQL on your problem.
I personally would prefer Redis instead of memcached.
Here are pros / cons:
memcached may delete a key if there is no ram. Redis and files will never do so.
some software such Joomla fail to install if sessions are not in files (e.g. memcached / redis)
both memcache and redis will be able to serve several php servers, so you will not be able to use stick sessions in a cluster.
memcached is faster, then it is redis, then it is ramdisk, then is memcachedb, then is mysql, then is filesystem sessions.
ramdisk mimics normal php sessions behavior and does not need anything to be installed.
if ramdisk fails to mount, php will fallback to filesystem and still will works (assuming the server boots)
if memcached or redis stop working, the php give nasty error and not starts at all.
Hope this helps.
Write access to the session data must be atomic or protected by a per-session lock, else it will get corrupted. For file-based sessions it's solved by locking the file, don't know how memcached deals with it.
Using a separate ext4 partition is not that bad as You think - VFS will cache your file I/O in RAM, so You might not need anything different.
You can fine-tune ext4 (on a partition) to cache your writes, so You could get RAM-like performance and persistance for larger-than RAM sizes.
For example you get writeback cache and 60 seconds window (delayed commit) with this:
mount /dev/sda4 -t ext4 -o rw,data=writeback,nobh,commit=60
It will work fast and it won't run out-of-RAM, it will use all available RAM because the filesystem cache is dynamic.
Try it with coping say 4MB file multiple times over second file (overwriting it) you`ll get very fast writes.
Actually you can use memcacheDB for what you need.