Re: Rush conditions after APC TTLs expire

From: Date: Thu, 17 Dec 2009 17:36:29 +0000
Subject: Re: Rush conditions after APC TTLs expire
References: 1  Groups: php.pecl.dev 
Request: Send a blank email to pecl-dev+get-6922@lists.php.net to get a copy of this message
That doesn't seem like a very robust mechanism. The normal way to update user cache items on high-load sites is to simply ensure that only a single process does it. People do this either by having a special endpoint that a cron job hits occasionally making sure it is never user-triggered, or alternatively, use apc_add() to add the pid of the process that is currently updating. Since apc_add() is atomic you can do something along the lines of: $pid = getmypid(); apc_add("update_lock",$pid); if(apc_fetch("update_lock"==$pid)) { // Got update lock ... } -Rasmus Richard wrote: > When using APC with a user set TTL it seems that between the end of the > TTL and the new item being re-cached all requests for this item will > cause the object to be generated. > > This behaviour seems unavoidable based on the APC design and most of the > time is is probably not an issue however if you have really high numbers > of requests it can make the APC cache ineffective as a means to protect > a backend resource. > > I know there are a lot of other cache systems like memcached that are > better for this kind of problem but I wanted to see how people feel about > the idea expressed in the attached patch. > > It adds two global config items > - apc.ttl_preempt - percentage between 0 and 100 (defaults to 0/off) > - apc.ttl_preempt_count - >0 (defaults to 1) > > ttl_preempt represents the percentage of the user set TTL after witch to > allow ttl_preempt_count users to update the cache whilst all others use > the old object. > > For example if you have apc.ttl_preempt set to 50 and > apc.ttl_preempt_count set to 1, a variable in cache with a TTL of 30 > that is more then 15 seconds old will return that it's not in the cache > for one request while others still get the cached version. Once this > request has updated the cache all request will get the new version and > the age of the cached item will be back to zero. > > This avoids the sudden rush effect at the end of a TTL on a cached item > since it will be unlikely during high load to reach the TTL before a > preempted replacement has happened. > > ttl_preempt_count would be set to numbers larger then one if you expect > some request to fail to populate the cache, I would expect if to be > unusual to need this in most cases. > > This works better for longer TTLs and will only protect the resource if > the amount of time left in the TTL is greater then the length of time it > takes to generate the cache item. It would also probably be better to > allow setting the preempt values for each cache item rather then globally. > > I am not familiar with the APC code so apologies for how rough the patch > is, happy to work more on it if the idea is liked. > > Richard. >

« previous php.pecl.dev (#6922) next »