使用memcached做数据库点击数统计缓冲
原理:
- 先从数据库读取最新的点击数,更新到缓存中。
- 点击动作产生时,在缓冲做自增操作。
- 把被点击的ID写入缓存中,以表名为组。表明缓存中有该ID的点击数,需要进行入库操作。
- 定时更新缓存数据到数据库。
- 如发现入库周期内,点击数无更新,则放弃入库,并山删除表名组中的ID。
且看代码:
/**
* 更新点击数
*
* @param string $table
* @param int $id
*/
function click($table, $id) {
$config = ZFactory::getConfig();
$key_prefix = $config[‘click’][‘key_prefix’];
$cache = ZFactory::getCache();
$key = $key_prefix . ‘_’ . $table . ‘’ . $id; // 点击数键
$click = $cache->get($key); // 获取点击数
if (!$click) {
// read from table
$id = intval($id);
$db = ZFactory::getDb();
$table = $db->escape_string($table);
$sql = “SELECT click_count FROM `log_clicked` WHERE click_id=’$id’ AND click_type=’$table’”;
$db->query($sql);
$result = $db->fetch_object();
$click = $result ? $result->click_count : 0;
$cache->set($key, $click);
// 维护一个ID列表
$list_key = $key_prefix . ‘’ . $table; // 列表键
$list = $cache->get($list_key); // 获取列表
if (!$list) $list = array($id);
else $list[] = $id;
$cache->set($list_key, $list);
}
return $cache->increment($key);
}
/**
* 把缓存中的数据持久化到数据库
*
*/
function click2db() {
$config = ZFactory::getConfig();
$key_prefix = $config[‘click’][‘key_prefix’];
$tables = $config[‘click’][‘tables’];
$cache = ZFactory::getCache();
foreach ($tables as $table) {
$ids_key = $key_prefix . ‘’ . $table;
$ids = $cache->get($ids_key);
if (count($ids))
foreach ($ids as $k=>$id) {
$id = intval($id);
// 缓存内的点击数
$key = $key_prefix . ‘_’ . $table . ‘’ . $id;
$click = $cache->get($key);
// 读取数据库里的点击数
$db = ZFactory::getDb();
$table = $db->escape_string($table);
$sql = “SELECT click_count FROM `log_clicked` WHERE click_id=’$id’ AND click_type=’$table’”;
$db->query($sql);
$result = $db->fetch_object();
$dbclick = $result ? $result->click_count : 0;
// 如果周期内没有人点击
if ($dbclick > $click) {
// 从缓存中摘除该ID
unset($ids[$k]);
} else {
// 把点击数写入数据库
$sql = “UPDATE `log_clicked` SET click_count=’$click’ WHERE click_id=’$id’ AND click_type=’$table’”;
$db->query($sql);
}
} // foreach ($ids as $k=>$id)
// 把ID列表写回缓存中
$cache->set($ids_key, $ids);
} // foreach ($tables as $table)
}