Cache Namespaces
The memcache itself does not support namespaces, but we can use the mechanism of memcache itself to emulate namespaces. For example, if you want to clear a set of data, you need to use a namespace, to look at an example, the explanation is written in the comments:
Class action{public function Index () { global $MC _wr; Gets the namespace $ns _key = $MC _wr->get ("Foo_namespace_key"); If the namespace does not exist, set an if ($ns _key===false) $mc _wr->set ("Foo_namespace_key", Time ()); $otherParms = ' Select ' From user LIMIT 1 '; Generates a unique key based on the namespace $my _key = "Foo_". $ns _key. ' _ '. MD5 ($otherParms); Gets the cache $val under the current key = $MC _wr->get ($my _key); if (! $val) { $value = ' wangdekang_ '. Time (); Cache does not exist then set the cache for 600 seconds, 0 for random failure time, to add a random number of seconds to the expiration time, to prevent all of the instant cache failure $MC _wr->set ($my _key, $value, 0); } Echo $val; } public function Clear_ns () { global $MC _wr; Updates the namespace value, invalidates all values of the current namespace, memcache its own cache invalidation mechanism, and passes the LRU invalidation mechanism $mc _wr->set (' Foo_namespace_key ', Time ()) when the cache is not accessed;}
Memcache Cache Failure problem
In the case of large concurrency, when the cache fails, a large number of concurrent simultaneous access to the cache, and a flash to the DB and back to the cache, may pose a potential risk of overloading the system.
Workaround:
Method One
Add a mutex key before load db, the mutex key add succeeds and then do the load db, and if add fails then retry reading the original cache data after sleep. To prevent deadlocks, the mutex key also needs to set the expiration time. The pseudo code is as follows
if (memcache.get (key) = = NULL) {//3 min timeout to avoid mutex holder crash if (Memcache.add (Key_mutex, 3 * 60 * 1000) = = True) { value = Db.get (key); Memcache.set (key, value); Memcache.delete (Key_mutex); } else { sleep (50);
Method Two
Set 1 timeout values (TIMEOUT1) inside value, timeout1 than the actual memcache
Timeout (timeout2) is small. When read from the cache to TIMEOUT1 to discover that it has expired, extend the TIMEOUT1 immediately and reset to the cache. Then
Then load the data from the database and set it to the cache. The pseudo code is as follows
v = memcache.get (key), if (v = = null) {if (Memcache.add (Key_mutex, 3 * +) = = True) { value = Db.get (key); Memcache.set (key, value); Memcache.delete (Key_mutex); } else { sleep (); Retry (); }} else {if (V.timeout <= now ()) { if (Memcache.add (Key_mutex, 3 * *) = = true) { //Extend the timeout For other threads V.timeout + = 3 * * +; Memcache.set (Key, V, key_timeout * 2); Load the latest value from db v = db.get (key); V.timeout = key_timeout; Memcache.set (key, Value, Key_timeout * 2); Memcache.delete (Key_mutex); } else { sleep (); Retry (); } }}