I have a CodeIgniter project. I want to use Memcache, but I don't want to create a new
connection every time index.php is loaded (which is on every page load). How can I set up Apache / CodeIgniter so that I always have access to a memcache connection, without having to re-establish it all the time?
Sorry, the thing about php/apache is, it sets up and tears down the entire environment every time. There is no application level persistence, other than external to the php/apache env (i.e. file, database, or memcache). You have to set up the new connection every time you want to use it. Of course, PHP makes up for this by doing it all blisteringly fast, and that is the tradeoff the developers of the PHP runtime choose to make.
Related
My problem is that my Symfony application running on a remote machine with Apache/2.4.6 (CentOS) PHP/5.6.31 MySQL 5.7.19 does not handle concurrent requests. Meaning that when asking for two different pages at the same time. First one has to finish before second one can be rendered.
I have a another site on the same server written in plain Php which has no problem rendering as many pages as possible at the same time (it uses deprecated mysql connection not pdo like Doctrine).
That said I have done the following test:
I have inserted a sleep(3); at my DefaultController. I requested that page and simultaneously requested a different one. See the two profilers below:
Page with sleep (called 1st):
Page without sleep (called 2nd).
Page 1 normal load time is 782ms
Page 2 normal load time is 108ms
As you can see Symfony's Http Firewall is taking all of the time of the second page to load.
My guess (might be stupid) is that 1st action holds the database connection and only until it has finished with it does it let it go for other requests to use it. And especially something having to do with Doctrine's use of PDO connection.
By the way I have already read help and articles like:
- What is the Symfony firewall doing that takes so long?
- Why is constructing PDO connection slow?
- https://www.drupal.org/node/1064342
P.S. I have tried using both app.php and app_dev.php in apache configs nothing changed. Sticked to app_dev.php so I can have the profiler. And local development using Symfony's build in server has the same result
You can not have 2 concurrent requests for the same open session in PHP. When you use a firewall, Symfony locks the user session and until you release it manually or the request is served.
To release the session lock use this:
$session->save();
Note there will be some drawbacks and iimplications. After you save the session, you will not be able to update it (change attributes) until the next request arrives.
Session management: https://symfony.com/doc/current/components/http_foundation/sessions.html
Session interface: http://api.symfony.com/4.0/Symfony/Component/HttpFoundation/Session/SessionInterface.html#method_save
Note 2. If you have multiple concurrent users with different sessions PHP will serve concurrently those requests.
I have a PHP system that i'd like to port to be on more than one server if the need arises. Currently I store the user's current session information just in the default manner PHP does (assuming in memory). Can I get an example of what I need to put in a table in my MySQL database as well as some example of implementation?
The default session storage system is actually on the file system. Some system caching may be used to pull it from memory.
Now in order to go into a multi-server setup, your servers need to basically share nothing with each other. To that goal, sessions need to be stored outside of the server they are created and accessed on.
Storing sessions in the database is one option, but it increases the load on your database and you have to be careful with locking in some cases. Default session handling has locking which allows only one thread to access a given session at a time, a database handler may not do that. If you are only reading session data, this is likely not going to be a problem, but if you are changing it, it could be.
The memcached extensions allow for session data replication to memcached nodes. I prefer this route as it allows you to keep sessions in memory and avoids adding extra db load (which is often more difficult to scale)
We're moving our memcached to a different server cluster and I need to either replicate the existing memcached data or do something like shadow writing where I slowly populate both memcached's simultaneously until they match. What are my options here?
Two ideas pop to mind:
Create a warm-up script that can identify every resource that needs to be put into the new Memcached and put it there. Then switch the production env. to the new Memcached server IP.
Create a new Memcached pool, change your scripts to always write to both pools. Wait for a few hours until the scripts inadvertently write all the data to both pools. Then switch the production env. to the new Memcached pool and disable the dual write scripts and the old pool.
Rationale:
The first case is useful if you're caching images / full html pages / sql resultsets that you can easily write a script to fetch and for which you can predict all of the possible parameters - conveniently they should be a few parameters not many.
The second case is useful if you're caching data which is very dependent on application flow and on unpredictable parameters.
There are some commercial solutions for Memcached replication as well as Memcached backups. I don't know any by name and perhaps there are some open source solutions as well.
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.
All,
I have a PHP5 web application written with Zend Framework and MVC. This application is installed on 2 servers with the same setup. Server X has php5/MySql/Apache and Server Y also have the same. We don't have a common DB server between both the servers.
My application works when accessed individually via https on Server X and Server Y. But when we turn on load balancing and have both servers up, the sessions get lost.
How can I make sure my sessions persist across servers? Should I maintain my db on a third server and write sessions to it? IF so, what's the easiest and most secure way to do it?
Thanks
memcached is a popular way to solve this problem. You just need to get it up and running (easy) and update your php.ini file to tell it to use memcached as the session storage.
In php.ini you would modify:
session.save_handler = memcache
session.save_path = ""
For the general idea: PHP Sessions in Memcached.
There are any number of tutorials on setting up the Zend session handler to work with memcached. Take your pick.
Should I maintain my db on a third
server and write sessions to it?
Yes, one way to handle it is to have a 3rd machine running the database that both webservers use for the application. I've done that for several projects in the past and its worked well. The question with that approach is... is the bottleneck at the webservers or the database. If its at the database, you wont see much improvement by throwing load balancing of the web servers into the mix. You may need to instead think of mirroring schemes for the database.
Another option is to use the sticky sessions feature on your load balancer. What this will do is keep users on certain servers. So when user 1 comes to the site, they will be directed to server X. Every subsequent request will also be directed to server X. This allows you to not worry about persisting sessions between servers, as each user will continue to be directed to the server they have their session on.
The one downside of this is that when you take a web server out of the pool, half the users with a session will be logged out. So the effectiveness of this solution depends on how often you take servers out of the pool.