5

I am using cakephp to run a multi-tenant application. There is only 1 instance of the app, the only difference being the database each app connects to. Other than that, the app is identical.

My setup:

  1. Apache 2.2
  2. Php 5.3
  3. cake 1.3.10
  4. Win 2k3 server

    I have the app deployed under apache's docroot (just 1 instance of the app is running). I recently switched from File to APC cache. The file prefixes for caching are the same for both apps. Using Apache Virtual Hosts to decide which app to go to. I am caching static html/js/css/gif but not php (via apache's mod_expires)

Problem:

I noticed that some of the cached values that were supposed to be available to APP 1 were showing in the dropdown for App 2.I was shocked to see this happen.

How can I add isolation in the APC cache layer between the apps ?

UPDATE: Problem happens even if I make a new copy of the app and put it in its own docroot!!!

UPDATE2

Scenario 1) 1 instance that has all perm/comb

If I have php code like

if(client=="client1") {
$options = array(opt1,opt2);
}else if(client=="client2") {
$options = array(opt3,opt4);
}

and this code is shared by both client 1 and client 2, how will APC caching affect this ?

Scenario 2) 2 instance each customized per client

client1.php
$options = array(opt1,opt2);

client2.php
$options = array(opt3,opt4);

how does this affect APC cache ? If I understand right, for Scenario 1, its possible to have client1 data mix with client 2 (very bad) For Scenario 2, as long as I use different cache keys , am I sure to never have a mixup?

aks
  • 255
  • 3
  • 15

2 Answers2

2

The why:

  1. APC does not know anything about vhosts, apps or other "apache" things.
  2. This means that any cache key is shared among all vhosts if apc is shared. (Which you usually want).
  3. APC does not have it's own isolation layer.

Workaround:

  1. Give each app they own prefix for cache keys. This allows them to access the keys individual user cache keys. (Easiest)
  2. Follow breiti's workflow with memcached if you need true isolation. (Probably the best solution)
  3. You can consider running for every individual virtual host a unique PHP.ini and a unique fcgiwrapper (see: http://chrisgilligan.com/wordpress/apc-cache-considerations-for-virtual-hosting-environments/). This however means a high increase in memory usage. (The if you really want it solution)
Arend
  • 3,741
  • 2
  • 27
  • 37
1

One way could be:

  • use memcached instead of APC for your users
  • bind your vhosts/domains to own IPs
  • start memcache instances for your vhost (i.e. vhost1 = port 12345, vhost2 = port 12346, …)
  • add iptable rules that drop every packet on the specific memcache port which does not match your vhost ip for that port)

Your problem seems to be, that php runs as fastcgi, so that every vhost will get the same php process to share their cache. You need to set up php to run just for every vhost (dont know for what you have to look for).

I would prefer the memcache method because:

  • memcache allows you to create a memcache cluster
  • its easy to seperate your application server from caching servers (for scaling thats a huge plus)
  • you seperate bytecache from user cache
  • correct configurated very secure (as its iptables is very reliable
breiti
  • 1,145
  • 9
  • 17