<?php namespace Plugin; use Hood\Cache as HoodCache; /** * 数据缓存的操作类 * * @name Cache * @package Plugin * @copyright yoho.inc * @version 1.0 (2015-10-10 11:23:47) * @author fei.hong <fei.hong@yoho.cn> */ class Cache { /** * 设置缓存 * * 备注: * 采用主从分布式缓存 * master 代表主缓存服务器 * slave 代表从缓存服务器 * * 作用: * 在后端的服务异常挂掉了并且主服务器缓存(master)的数据时间到期后, * 能获取从服务器缓存(slave)的数据,不影响前端页面的正常访问. * * @param string $key 键名 * @param mixed $value 需要缓存的数据 * @param int $expire 缓存有效期(单位秒, 0表示永久) * @return void */ public static function set($key, $value, $expire = 300) { try { // WINDOWS if (DIRECTORY_SEPARATOR === '\\') { HoodCache::Memcache('master')->set(self::makeKey($key, 'master'), $value, $expire); HoodCache::Memcache('slave')->set(self::makeKey($key, 'slave'), $value, 86400); // 二级缓存1天 } // LINUX else { HoodCache::Memcached('master')->set(self::makeKey($key, 'master'), $value, $expire); HoodCache::Memcached('slave')->set(self::makeKey($key, 'slave'), $value, 86400); // 二级缓存1天 } } catch (Exception $e) { // do nothing } } /** * 获取缓存 * * @param string $key 键名 * @param string $node master代表主服务器, slave代表从服务器 * @return mixed */ public static function get($key, $node = 'master') { $result = array(); try { // WINDOWS if (DIRECTORY_SEPARATOR === '\\') { $result = HoodCache::Memcache($node)->get(self::makeKey($key, $node)); } // LINUX else { $result = HoodCache::Memcached($node)->get(self::makeKey($key, $node)); } // 当接口异常,一级缓存没取到数据的情况 if ($node === 'slave') { $incrementKey = self::makeKey('_increment_' . $key, 'slave'); $incrementValue = intval(HoodCache::Memcached('slave')->get($incrementKey)); // 接口调用失败累计5次之后,回填二级缓存数据到一级缓存, 重置计数值为0 if (is_int($incrementValue) && $incrementValue > 5) { HoodCache::Memcached('master')->set(self::makeKey($key, 'master'), $result, 300); HoodCache::Memcached('slave')->set($incrementKey, 0, 3600); } // 接口调用失败次数累加 else { HoodCache::Memcached('slave')->increment($incrementKey, 1, 0, 3600); } } } catch (Exception $e) { $result = array(); } return $result; } /** * 清除缓存 * * @param string $key 键名 * @return void */ public static function delete($key) { // WINDOWS if (DIRECTORY_SEPARATOR === '\\') { HoodCache::Memcache('master')->delete(self::makeKey($key, 'master')); HoodCache::Memcache('slave')->delete(self::makeKey($key, 'slave')); } // LINUX else { HoodCache::Memcached('master')->delete(self::makeKey($key, 'master')); HoodCache::Memcached('slave')->delete(self::makeKey($key, 'slave')); } } /** * 累加 * * @param string $key * @param int $offset * @param int $initialValue * @param int $expiry * @return boolean */ public static function increment($key, $offset = 1, $initialValue = 0, $expiry = 0) { return HoodCache::Memcached('master')->increment(self::makeKey($key, 'master'), $offset, $initialValue, $expiry); } /** * 递减 * * @param string $key * @param int $offset * @return boolean */ public static function decrement($key, $offset = 1) { return HoodCache::Memcached('master')->decrement(self::makeKey($key, 'master'), $offset); } /** * 生成键名 * * @param string $key 键名 * @param string $prefix 前缀标识 * @return string */ public static function makeKey($key, $prefix) { return md5($prefix . '_' . $key); } }