I'm developing a site with Symfony2.4 which stores some "semi-static" info in the database (such as addresses, telephones, social media URL's, etc...) to allow the client modify that data through backend.
The site works fine but I think it should be some way to reduce the accesses to the database for retrieving those data for every request (because is printed in all pages).
Is there any way to cache that data? Is a good practice store it in a user session the first time it enters the site?
Thanks.
You should use APC for instance.
Assuming you have php-apc extension installed and enabled (you can check it in phpinfo) this is all you need to do:
in your config_prod.yml (you don't want results to be cached in dev environment)
doctrine:
orm:
metadata_cache_driver: apc
result_cache_driver: apc
query_cache_driver: apc
and then in your query:
$queryBuilder
(...)
->useQueryCache(true)
->useResultCache(true)
(...)
First time you make this query it will fetch data from database. Next time it will fetch data from cache. You can also set lifetime of cache: example
EDIT: Above link is to symfony 1.x documentation, however usage of useQueryCache and useResultCache are the same in symfony 1.x and Symfony2.x.
For bigger doc on Symfony2 Doctrine configuration check this link as #Francesco Casula mentioned
Related
How can i manage sessions between 2 or more web servers are using to manage Load balancing ?
The points that i found are
Use database session CDbHttpSession
Use cache session CCacheHttpSession
Use Security manager CSecurityManager
As Yii project Lead Qiang said , There is only one thing you need to be careful, that is the validationKey of CSecurityManager. By default, this key is automatically/randomly generated the first time and is stored under runtime directory. In multiple server environment, you should explicitly configure this property so that all servers share the same key. This key is used widely to generate hash keys for various security-related measures.
You have a couple of options:
1) If your load balancer supports it, you can enable session persistence so that the user always is sent to the same server as the one they originally hit. The benefit of this is that it's easy to setup if you don't want to change any code. The downside is that if one of your servers goes down you lose all your sessions on that node.
2) Setup a shared memcache (not memcached) session between node1 and node2. The relevant settings being.
php.ini
session.save_handler memcache
session.save_path tcp://<ip1>, tcp://<ip2>
memcache.ini
memcache.allow_failover 1
memcache.default_port 11211
memcache.hash_strategy standard
memcache.max_failover_attempts 20
It's a little tricky to setup, but once you get it working you have full redundancy between both servers if one were to go down.
3) Setup a third node to manage sessions and configure php session.save_path to be that server's ip. The benefit of this is that sessions are now managed by a third server. The downside being you lose redundancy, if that server goes down you lose sessions.
this is the best answer that i got . But I cant Use APC !!
Is there any other methods ?
I have a db table (doctrine entity) that I use to store some editable settings for my app, like page title, maintenance mode (on/off), and some other things..
I can load the settings normally using the entity manager and repositories, but I think that's not the best solution...
My questions are:
- can I load the settings only once at some kernel event and then access them the same way I access any other setting saved in yml config files..
how can I cache the database settings, so I would only do one DB query, and then in future page requests, it would use the cached values, instead of doing a DB query for each page request? (of course, everytime I change something in the settings, I would need to purge that cache, so the new settings could take effect)
LiipDoctrineCacheBundle provides a service wrapper around Doctrine's common Cache (documentation) that allows you to use several cache drivers like filesystem, apc, memcache, ...
I would recommend loading your generic container-parameters/settings (like maintainance mode,...) from database in a bundle-extension or a compiler-pass.
route-specific settings (like page title, ...) could be loaded in a kernel event listener. You can find a list of kernel events here.
update/invalidate their cache using a doctrine postUpdate/postPersist/postRemove listener.
We are developing a high end web application with php/mysql and would like to explore more into memcached usage.
From the tutorials we understand that we need to write to memcached server along with writing to mysql tables. But we are confused how to use this if we are loading a list of data with a pagination. In that page we might need to filter data based on different fields. In this scenario, can we rely on memcached along without using mysql database. If not, how can memcached help to scale php application.
first of all, memcached does not persist your data to the disk, so relying on it to keep your data is not a good practice
memcached helps to scale your php application by minimizing the load from your db by serving results from queries or even better minimizing the load off the web server by storing the entire html if you can (there are actually many good use cases for memcached)
consider the follwing flow:
1. client browsing to your page
2. php application requests the data from memcached by a key (the key can be the sql query, the url ... it depends)
3. if memcached has the data use it
4. if not the php application should query the data from mysql
5. after the data is retrieved save it in memcached so next request it will be available in 2
to handle updates, make sure to define ttl to each item you store in the memcached (of course there are also other ways to invalidate the cache)
I am using
https://github.com/symfony/symfony/blob/master/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/MongoDbSessionHandler.php
as my session handler for my PHP app.
Our app is expecting high volume traffic, so we are experimenting with sharding the Mongo that store session.
I have set up my shard according the the document, and things are all fine before I shard the collection (I can see session document being created in the session collection).
As soon as I enabled sharding on session using sharding key sess_id, then no session document gets created (i.e. count never change), and I see these lines in the mongos log whenever I visit my PHP page:
resetting shard version of mydb.session on my.hsard.ip.address:port, version is zero
I have tried to shard my other collection and it works fine, so that tells me my sharding setup is correct.
Anybody have a clue of what might be wrong? I'm using Mongo 2.2.3.
Found the cause.
It was because the write function in MongoDbSessionHandler.php that comes with symfony version we are using will not work with sharding.
The MongoDbSessionHandler.php we are using implements write like this:
$mongo->update({shardkey:1}, {shardkey:1, data:2}, {upsert:true})
which is not allowed, because you cannot change the shard key.
Solution is to simply use the latest version of MongoDbSessionHandler.php in the github.
This is an issue I've started to experiment a few months ago and I've been trying to fix without success since.
Symptoms: At random intervals of time symfony loses the session info and logs out the users. It seems somehow to be connected with the load of the site. When the load is higher it seems that the users are logged out more often, could happen even fast as 30 seconds.
Environment: Since this started I've changed a lot of the setup, including the php version, web server, session storage, symfony version. Here is the current setup:
Ubuntu 10.04, php 5.4.0, symfony 1.4.17, nginx 1.0.15 with FPM. Here is how the session storage is configured in factories.yml:
user:
class: myUser
param:
timeout: 86400
use_flash: true
storage:
class: sfCacheSessionStorage
param:
cache:
class: sfMemcacheCache
param:
lifetime: 86400
host: 192.168.1.3
serializer: IGBINARY
mode: compiled
port: 11211
I got to mention that I've also used redis for session storage and still had the problem.
I really have no idea what to try next. Anybody else experienced something similar? At this stage any hint would be much appreciated.
Update:
Ater months of searches and countless trials and errors I think it could be a concurrency problem. Our site is quite heavy on AJAX requests and I have learned that it can lead to issues with the sessions unless proper locking mechanisms are implemented in the session handler.
First I have eliminated symfony from the equation, I've set it to use php sessions. With the default file session storage I never lose any sessions. Then I have configured php to use the memcache session storage. Surely enough we have started to see lost sessions. I am 100% positive that memcached is not running out of memory, I have installed an admin tool and the memcached server is barely using 2% of the 8GB allocated to it (no waste, the memory is allocated as needed).
Then I have added a second memcached server and configured the session handler to use redundancy. This helped a lot, I rarely have any lost sessions. For now this is an acceptable compromise.
For some reason, memcache seems to miss every now and again and create a new session which causes the user to be logged out.
As suggested by Jestep, you should prove this by taking memcache out of the equation to see if the problem goes away.
If so, then the problem is either the way you are talking to memcache or memcache itself.
Actually the setup we have been using for the last few months is symfony configured to use the normal php sessions (not any of the cache classes) and then php is setup to use the memcache extention (there is another one called memcached) to store the session on 2 redundant memcache servers. If I take out one of the memcache servers we immediately start to see lost sessions.
This was the only setup that really did the job.