a13698822086 发表于 2018-11-4 13:53:22

Redis之利用锁机制来防止缓存过期产生的惊群现象

class KomaRedis{  
    private $redis; //redis对象
  
    private static $_instance = null;
  
    private function __construct($config = array())
  
    {
  
      if (empty($config)) {
  
            return false;
  
      }
  
      $this->redis = new Redis();
  
      $this->redis->connect($config['server'], $config['port']);
  
      return $this->redis;
  
    }
  
    /**
  
   * @param array $config
  
   * @return redis操作类对象
  
   */
  
    public static function getInstance($config = array())
  
    {
  
      if (!(self::$_instance instanceof self)) {
  
            self::$_instance = new self ($config);
  
      }
  
      return self::$_instance;
  
    }
  
    /**
  
   * 获取缓存
  
   * @param $key string $name
  
   * @return array,object,number,string,boolean
  
   * @desc 此方法使用了锁机制来防止防止缓存过期时所产生的惊群现象,保证只有一个进程不获取数据,可以更新,其他进程仍然获取过期数据
  
   */
  
    public function getByLock($key)
  
    {
  
      $sth = $this->redis->get($key);
  
      if ($sth === false) {
  
            return $sth;
  
      } else {
  
            $sth = json_decode($sth, TRUE);
  
            if (intval($sth['expire']) redis->incr($key . ".lock");
  
                if ($lock === 1) {
  
                  return false;
  
                } else {
  
                  return $sth['data'];
  
                }
  
            } else {
  
                return $sth['data'];
  
            }
  
      }
  
    }
  
    /**
  
   * 设置缓存
  
   * @param $key string $name 缓存键
  
   * @param $value $string ,array,object,number,boolean $value 缓存值
  
   * @param null $ttl $string ,number $ttl 过期时间,如果不设置,则使用默认时间,如果为 infinity 则为永久保存
  
   * @return bool
  
   * @desc 此方法存储的数据会自动加入一些其他数据来避免惊群现象,如需保存原始数据,请使用 set
  
   */
  
    public function setByLock($key, $value, $ttl = null)
  
    {
  
      if (is_numeric($ttl) && intval($ttl) > 0) {
  
            $ttl = intval($ttl);
  
            $exp = time() + $ttl;
  
            $arg = array("data" => $value, "expire" => $exp);
  
      } else {
  
            $ttl = 300;
  
            $exp = time() + $ttl;
  
      }
  
      empty($ttl) OR $ttl += 300; //增加redis缓存时间,使程序有足够的时间生成缓存
  
      $arg = array("data" => $value, "expire" => $exp);
  
      $rs = $this->redis->setex($key, $ttl, json_encode($arg, TRUE));
  
      $this->redis->del($key . ".lock");
  
      return $rs;
  
    }
  
    /**
  
   * 返回redis对象
  
   * redis有非常多的操作方法,我们只封装了一部分
  
   * 拿着这个对象就可以直接调用redis自身方法
  
   */
  
    public function redis()
  
    {
  
      return $this->redis;
  
    }
  
}


页: [1]
查看完整版本: Redis之利用锁机制来防止缓存过期产生的惊群现象