Cache.php 4.52 KB
<?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);
    }

}