Opened 6 years ago

Last modified 2 years ago

#206 new enhancement

Shared Cache (? Daemon ?)

Reported by: a.rieser@… Owned by: moo
Priority: major Milestone: undecided
Component: cacher Version:
Keywords: Cc:
Application: PHP Version:
Other Exts: SAPI: FastCGI
Probability: Blocked By:
Blocking:

Description (last modified by moo)

I don't know how hard it is to implement the feature I'm going to describe now. Maybe I can help out with some work. I am basically expecting a discussion, as this seems to be a really innovative and good idea:

As we have joining forces everywhere around open source software projects, there are a lot of great frameworks being created. Some of them offer the possibility to have a kind of core, that can be shared between different applications/installations. Im a [http:/typo3.org/ TYPO3] guy, so imagine something like one core and many dummy packages (= installations, that are attached via symlinks). I think this or something similar can be found in several other projects. The point is: This is great with an opcode cacher if you use it with mod_php or in an one process fastcgi environment, because of the central cache even low traffic installations can benefit from the cached core files.

When it comes to shared hosting you probably want to have some more security and consider using methods like suexec or simply individual user permissions for your fastcgi environment. So the core files are readonly and shared, every vhost owns an installation which it can't escape. But we have to build redundant caches for each vhost, which makes it impossible to do efficient caching as you may have to limit the cache sizes etc.

And then we have this great xcache feature called "Readonly Cacher Protection", so that the cache can't be touched by anyone else but xcache.

So maybe it would make sense to have something additional to those redundant caches that delivers a "shared cache". In this Case this cache would hold the cached core files.

Im talking about a concept with two caches in xcache, a private one and a shared. In an configuration directive we could define special directories which will not go to the private cache, but instead being written to the shared. In case of searching the cache both caches have to be considered.

Reading might not be the problem (but world-readable is a bad thing), but the different permissions will be tricky at least in case of clearing the cache. So maybe to solve this, there has to be a daemon around that

  • owns the shared cache
  • knows which directories should be cached there
  • is searchable from the different fastcgi driven xcaches
  • delivers shared cache content and in case of a miss for a file that has to stay in his hands:
  • tells his fastcgi driven friends to store this miss at his place
  • accepts new content and saves it
  • will invalidate it when needed

So what do you think about that concept?

Change History (3)

comment:1 Changed 6 years ago by moo

  • Description modified (diff)

suexec/suphp are cgi and hurt performance already, i wonder if there's a way to overcome this. i'm not sure how much overhead they have, but yes, having XCache could still help in any case.

correct me if i get it wrong

  • shared cache, readonly by suexec-php/suphp under any user
  • private cache, accessable by current suexec-php/suphp user, reuable later even if last child for this user exits

XCache under suexec-php/suphp can request a XCache daemon to cache new php files to shared cache.

but how can XCache (told by someone?) know which should be in shared cache and which should be in private cache.

btw, XCache is able to cache files with same inode in 1 copy, and can also recognize "same content" file by using md5 algorithm in XCache 2.0. too bad that FILE is broken in either case

comment:2 Changed 5 years ago by a.rieser

First: Sorry for reregistering, but trac acted really crazy!
Warning: <acct_mgr.web_ui.MessageWrapper? object at 0x5dd2950>
WTF?!?

Second: Sorry for reposting the stuff that already went to the list some month ago...

Third: Thx for correcting my text-formatting...


Comment(by moo):
suexec/suphp are cgi and hurt performance already, i wonder if there's a
way to overcome this. i'm not sure how much overhead they have, but yes,
having XCache could still help in any case.

My favourite are individual user permissions in a FastCGI environment to offer some additional security - but the problem is the same.

correct me if i get it wrong

  • shared cache, readonly by suexec-php/suphp under any user
  • private cache, accessable by current suexec-php/suphp user, reuable later even if last child for this user exits XCache under suexec-php/suphp can request a XCache daemon to cache new php files to shared cache. but how can XCache (told by someone?) know which should be in shared cache and which should be in private cache.

With "reusable later even if last child for this user exits" you brought up a second issue that can be addressed with this feature.
So there are two issues, that can be solved:

  • yours: with a cache that is shared between several FastCGI Backends of one user, we could get rid of the problem with independant caching if there is more than one backend for each user around, which is a good idea for improved stability and scalability.
  • mine: with a cache that is shared (readonly!) between several FastCGI Backends of different users, we could get rid of the problem with independant caching when using the same framework several times for different users, where typically most of the caches contain the same stuff

How to achieve this? The trick is the daemon:

  • owns the shared cache -> * shared cache, readonly by suexec-php/suphp under any user -> yes!
  • knows which directories should be cached there -> he knows if a file has to be cached at his place -> so just ask him and go on if he can't help you!
  • is searchable from the different fastcgi driven xcaches -> self explanatory
  • delivers shared cache content and in case of a miss for a file that has

to stay in his hands:

  • tells his fastcgi driven friends to store this miss at his place
  • accepts new content and saves it
  • will invalidate it when needed

Sorry, for quoting that again. But the answers are already there - to make it clearer i try to find other words for it.
Maybe describing the whole process again is better. This time I try to describe a solution for both issues above.

Imagine two PHP-FastCGI-driven vhosts under different users. (/my/users/1/ and /my/users/2/) Both should work with e.g. 4 php backends. (-> would typically result in independant caching)
As we use the same framework (e.g. TYPO3) for both vhosts we could improve caching even further, with putting all core stuff in a shared cache for both vhosts. (-> currently impossible)

My idea to solve this would be three independent daemons arround.

daemon1
shared between different php backends of user 1

  • configure the daemon, /my/users/1/ has to be cached in this shared cache
  • start the daemon

daemon2
shared between different php backends of user 2

  • configure the daemon, /my/users/2/ has to be cached in this shared cache
  • start the daemon

daemon3
shared between our two different users:

  • configure the daemon, /my/path/cores/ has to be cached in shared cache
  • start the daemon
  • configure your FastCGI-Environment to work with Xcache
  • there has to be a setting like "cache_engine="adress:daemon3; adress:daemon0; local" which tells xcache where to look for cache entries

configuration in this case would be something like:
user1: "cache_engine="adress:daemon3; adress:daemon1; local"
user2: "cache_engine="adress:daemon3; adress:daemon2; local"

-> local could be a fallback...

Yeah, there are some more things to solve, but that's not too hard i guess:
What about cache access restriction? -> some ideas:
daemon1 could run under the same "user1" and could ensure that he delivers only to php processes under the same user;
if the interface is tcp, why not via firewall?
[...]

So how could this work:

  • any request to vhost of user1 will lead to files beeing accessed in /my/users/1/ and /my/path/cores/
  • any request to vhost of user2 will lead to files beeing accessed in /my/users/2/ and /my/path/cores/
  • caches are empty right now
  • child process 1 of user1.backend0 tries to fetch stuff from daemon3 (because that's the first place configured via "cache_engine") while processing the file in /my/path/cores/corefile1.php
  • daemon3 tells that this is n/a, it additionally tells that the file has to be cached in his cache and asks xcache to do the work and store the results at his place
  • user1.backend0.child1 does the work and sends the cache content to daemon3
  • daemon3 stores it
  • child process 2 of user1.backend0 tries to fetch stuff from daemon3 (because that's the first place configured via "cache_engine") while processing a file in /my/users/1/file1.php
  • daemon3 tells that this is n/a
  • child process 2 of user1.backend0 then tries to fetch stuff from daemon1 (because that's the second place configured via "cache_engine")
  • daemon1 tells that this is n/a, it additionally tells that the file has to be cached in his cache and asks xcache to do the work and store the results at his place
  • user1.backend0.child2 does the work and sends the cache content to daemon2
  • daemon2 stores it
  • child process 3 of user1.backend1 tries to fetch stuff from daemon3 (because that's the first place configured via "cache_engine") while processing the file in /my/path/cores/corefile1.php
  • daemon3 does send the cache content
  • user1.backend1.child3 is happy because user1.backend0.child1 already did the work for him

This one is intended to work too:

  • child process 4 of user2.backend0 tries to fetch stuff from daemon3 (because that's the first place configured via "cache_engine") while processing the file in /my/path/cores/corefile1.php
  • daemon3 does send the cache content
  • user2.backend0.child4 is happy because user1.backend0.child1 already did the work for him
  • child process 5 of user1.backend1 tries to fetch stuff from daemon3 (because that's the first place configured via "cache_engine") while processing a file in /my/users/1/file1.php
  • daemon3 tells that this is n/a
  • child process 5 of user1.backend1 then tries to fetch stuff from daemon1 (because that's the second place configured via "cache_engine")
  • daemon1 does send the cache content
  • user1.backend1.child5 is happy because user1.backend0.child2 already did the work for him

Hopefully this will help you to understand my idea.

The good news is, that the same type of daemon could be used (I mean the same software) and the daemon itself doesn't have to be too smart.
The bad news is: It's a daemon ;-) So this is far away from the current xcache development.

A look at memcached could bring some light in the dark. Maybe it could even be used here:
http://www.danga.com/memcached/

I think this cache daemon would be great, because currently there is no solution for these issues available. What do you think?
Where are the drawbacks?
What is hard to implement?
Where can be helped out?

btw, XCache is able to cache files with same inode in 1 copy, and can also
recognize "same content" file by using md5 algorithm in XCache 2.0. too
bad that FILE is broken in either case

Nice to know, but I think this will not solve these issues or am I getting something wrong?

comment:3 Changed 2 years ago by moo

  • Milestone set to undecided
Note: See TracTickets for help on using tickets.