There are a lot of different ways that people use memcached and PHP. The most common of which is probably your basic set and get to cache data from your database.
----------------
有许多方式使用memcache和PHP, 其中最常见方式的可能是set get 是从数据库里取数据缓存起来
- function get_my_data1() {
-
$cache_id = "mykey";
-
$data = $memcache_obj->get($cache_id);
-
if ( !$data ) {
-
$data = get_data_from_db_function();
-
$memcache_obj->set($cache_id, $data, $sec_to_cache_for);
-
}
-
return $data;
-
}
But what if the query that’s going to hit the database is pretty intensive and you don’t want more than one user to hit the db at a time? That’s easily handling via a semaphore lock.
----------------
但是要访问数据库的查询非常密集 并且 你不想同时有多个用户命中数据库. 可通过信号锁轻松实现.
- function get_my_data2() {
-
$cache_id = "mykey";
-
$data = $memcache_obj->get($cache_id);
-
if ( !$data ) {
-
// check to see if someone has already set the lock
-
// 检测是否有人已经设置了锁
-
$data_lock = $memcache_obj->get($cache_id . ‘_qry_lock’);
-
if ( $data_lock ) {
-
$lock_counter = 0;
-
// loop until you find that the lock has been released. that implies that the query has finished
-
// 循环 直到你发现锁已经被释放. 这意味着查询已经完成
-
do while ( $data_lock ) {
-
// you may only want to wait for a specified period of time.
-
// 你也许需要在一个指定的周期内等待 //
-
// one second is usually sufficient since your goal is to always have sub-second response time
-
// if you query takes more than 1 second, you should consider "warming" your cached data via a cron job
-
// 如果查询时间超过1s, 你应该创建一个计划任务 //
-
if ( $lock_counter > $max_time_to_wait ) {
-
$lock_failed = true;
-
break;
-
}
-
// you really want this to be a fraction of a second so the user waits as little as possible
-
// 你可以认为这是几分之一秒, 为了让用户尽可能少的等待 //
-
// for the simplicity of example, I’m using the sleep function.
-
// 本例中 使用sleep方法. 等待1s再次判断锁是否存在 //
-
sleep(1);
-
$data_lock = $memcache_obj->get($cache_id . ‘_qry_lock’);
-
}
-
// if the loop is completed, that either means the user waited for too long
- // 循环结束,用户等待太久或者是锁已经被移除, 尝试再次获得, 数据应该已经在缓存中存在 //
-
// or that the lock has been removed. try to get the cached data again; it should exist now
-
$data = $memcache_obj->get($cache_id);
-
if ( $data ) {
-
return $data;
-
}
-
}
-
// set a lock for 2 seconds
-
// 设定一个过期时间为2s的锁 //
-
$memcache_obj->set($cache_id . ‘_qry_lock’, true, 2);
-
// 从数据库获得数据存储到memcache中 //
-
$data = get_data_from_db_function();
-
$memcache_obj->set($cache_id, $data, $sec_to_cache_for);
-
// don’t forget to remove the lock
-
// 不要忘记移除锁
-
$memcache_obj->delete($cache_id . ‘_qry_lock’);
-
}
-
return $data;
-
}
Another good use of the semaphore locking is to set the expire time as
part of the cached data and have an extended expire time set in
memcache. This allows you to have more control over what happens when
the cached data becomes stale. You can make it so that one user
repopulates the cache while other users continue to get the existing
cache until the first user has finished.
----------------
- function get_my_data3() {
-
$cache_id = "mykey";
-
$data = $memcache_obj->get($cache_id);
-
// if there is cached data and the expire timestamp has already expired or is within the next 2 minutes
-
// then we want the user to freshen up the cached data
-
// 如果缓存数据过期,或者时间戳在接下来的两分钟内将要过期 那么我们就要更新缓存中的数据 //
-
if ( $data && ($data[‘cache_expires_timestamp’] – time()) < 120 ) {
-
// if the semaphore lock has already been set, just return the data like you normally would.
-
// 如果已经设定了锁, 那么只需要返回原有数据 //
-
if ( $memcache_obj->get($cache_id . ‘_expire_lock’) ) {
-
return $data;
-
}
-
// now we want to set the lock and have the user freshen the data.
-
// 现在我们要设定锁, 并且更新缓存中数据 //
-
$memcache_obj->set($cache_id . ‘_expire_lock’, true, 2);
-
// by unsetting the data it will cause the data gather logic below to execute.
-
// 释放$data
-
unset($data);
-
}
-
if ( !$data ) {
-
// be sure to include all of the semaphore logic from example 2
-
// set the _qry_lock for 2 seconds
-
$memcache_obj->set($cache_id . ‘_qry_lock’, true, 2);
-
$raw_data = get_data_from_db_function();
-
$data[‘cache_expires_timestamp’] = time() + $sec_to_cache_for;
-
$data[‘cached_data’] = $raw_data;
-
$memcache_obj->set($cache_id, $data, $sec_to_cache_for);
-
// remove the _qry_lock
-
$memcache_obj->delete($cache_id . ‘_qry_lock’);
-
// remove the _expires_lock
-
$memcache_obj->delete($cache_id . ‘_expires_lock’);
-
}
-
return $data;
-
}
When you mash these functions together, you end up with a system where
only one user every freshens the cache and/or hits the database with a
specific query at a time. There are a lot of other things that suddenly
become available once you start thinking of memcached beyond just
saving your db from hits. You have things like session handling, smarty
template caching, flags for per-server processing (e.g., clearing local
file cache), and even as a temporary database.
----------------
原文地址:
阅读(828) | 评论(0) | 转发(0) |