Say I have a caching system that i can use for storing sessions:
// example i have a cache class
$memcached->add('key','value');
// then i can get the session from
$memcached->get('key');
What are the advantages and disadvantages of using caching (e.g. memcached, maybe Redis can fit in, or other things) for sessions rather than using PHP's built-in sessions?
I want to start by clarifying. When you're using PHP session storage, the sessions are being stored in a file (usually in /tmp). Each session becomes it's own file.
When you use memcached or redis to store sessions, nothing in your PHP code changes.
You can simply configure php to use redis or memcache to store the sessions instead (configured via session save handler in php.ini).
Pros:
session storage/retrieval becomes much much faster
cons:
you need to configure php.ini (or implement the session save handler yourself)
now, I would actually recommend using redis instead of memcache, simply because the sessions will become permanent, so if you need to reboot the server, all your users wont get logged out.
For redis:
https://github.com/owlient/phpredis (see "session handler" lower on the page)
You should be able to have PHP store session data in Apache's runtime memory by setting session.save_handler to mm. However, to do this you need to compile PHP with the memory management module (--with-mm), which I don't think is available for Windows.
If you want to use memcached or some other caching mechanism, then it'd probably be best to implement user-defined storage handlers using session_set_save_handler so you don't have to rewrite your session management code.
If you do that, then I don't think there are any obvious disadvantages to storing session data in that way. The obvious advantage is speed.
Edit:
I came across this page which discusses, aside from speed, the main advantages/disadvantages of using memcached for storing sessions, namely:
It's easy to share sessions across multiple webservers without using sticky sessions.
However, memcached makes no promises of keeping the data up until expiration—only that the data will not be available after expiration. So if memcached is low on ram, hasn't been used lately, or the server goes down at all, the session data will be lost.
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.
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 am using sessions in PHP to track if a user is logged in. I do not use it to store any other data about the user; essentially it is like checking a hash table to see if the user has authenticated.
Would there be some advantage to using redis instead of native PHP sessions?
I'm curious about performance, scalability, and security (not really concerned with code complexity).
Using something like Redis for storing sessions is a great way to get more performance out of load balanced servers.
For example on Amazon Web Services, the load balancers have what's called 'sticky sessions'. What this means is that when a user first connects to your web app, e.g. when logging in to it, the load balancer will choose one of your app servers and this user will continue to be served from this server until they exit your application. This is because the sessions used by PHP, for example, will be stored on the app server that they first start using.
Now, if you use Redis on a separate server, then configure your PHP on each of your app servers to store it's sessions in Redis, you can turn this 'sticky sessions' off. This would mean that any of your servers can access the sessions and, therefore, the user be served from a different server with every request to your app. This ultimately makes for more efficient use of your load balancing set-up.
You want the session save handler to be fast. This is due to the fact that a PHP session will block all other concurrent requests from the same user until the first request is finished.
There are a variety of handlers you could use for PHP sessions across multiple servers: File w/ NFS, MySQL Database, Memcache, and Redis.
The database method (using InnoDB) was the slowest in my experience followed by File w/ NFS. Locking and write contention are the main factors. Memcache and Redis provide similar performance and are by far the better alternatives since all operations are in RAM. Redis is my choice because you can enable disk persistence, and Memcache is only memory based.
I explain Redis Sessions in PHP with Kohana if you want more detail. Here is our dashboard for managing Redis keys:
I don't really think you need to worry much about sessions unless you get MASSIVE ammounts of traffic, PHP handle sessions nicely, and if you store only that little data, it should be fine even with a lot of requests, and about performance it should be close, as redis is not native to PHP.
With 10k users, if each user uses like 1kb data of sessions, it would consume 10,000kb or 10~mb, which is not much; PHP is smart enough to use a good enough data structure to hold and quickly write and read those values. The problem is if the session data is too big, or for some reason the server consumes too many resources reading the session data, but that's normally if it's the data is too big.
I am writing a brand new website and I'd like to make sure that it scales out easily if I ever get to the point where I must host the site on multiple machines with a load balancer.
The user of the website can be authenticated. In other words, I need to maintain some state information. My first reflex was to use Session variables but then I am going to be limited to a single machine. I know that there are ways to store the session variables outside (in a DB, redis, memcached) but is that the only options?
What are the alternative to session variable? How Facebook and other big web sites are doing this?
P.S. I am not looking for another session handler (DB, redis, etc.). I'd like to know if there a way to completely get rid of session variables.
Ever heard of session_set_save_handler? It allows you to use mechanisms other than the default PHP session handler (the one that writes sess_xxxxxxxxxxxx files in tmp directory).
You can write your own session handler that uses a database. This could be a time consuming task; so you can stick with the default PHP session handlers for the time being and transparently switch to database when you are ready. You probably won't have to rewrite any code except implementing and plugging in your version of the six session handling functions.
You can look into caching, i.e using Zend cache or APC cache, for example.
My application can store up to dozens or even low hundreds of KB of data in the session. I'm currently storing PHP sessions in MySQL blobs, and traffic volume is now putting session-related queries on the database around 25-75 per second. It's causing some problems.
Is there a centralized storage option for PHP sessions of this size that will perform well? I'd prefer to avoid sticky sessions at the load-balancer level if possible for other performance reasons. I can try to reduce the session size, but regardless I'm going to need this information on most requests, so I'm going to have to stash it somewhere.
Scache is ideal for that. You can probably split your session data to smaller parts, some might even be cacheable to all sessions and so on. Scache has api for all that.
There's nothing bad in big session data, it's bad only if you store it to $_SESSION.
memcached is always a favorite option.
The memcache PHP extension helpfully comes with a session handler that will store sessions with memcached.
Zend's own session cluster daemon:
http://www.zend.com/en/products/server-cluster-manager/high-availability