专栏名称: 蚂蚁金服ProtoTeam
数据前端团队
目录
相关文章推荐
51好读  ›  专栏  ›  蚂蚁金服ProtoTeam

浅谈Redis分布式锁实现

蚂蚁金服ProtoTeam  · 掘金  · 前端  · 2017-12-08 02:19

正文

请到「今天看啥」查看全文


class RedisTool {        const LOCK_SUCCESS = 'OK';        const IF_NOT_EXIST = 'NX';        const MILLISECONDS_EXPIRE_TIME = 'PX';        const RELEASE_SUCCESS = 1;    /**
     * 尝试获取锁
     * @param $redis       redis客户端
     * @param $key         锁
     * @param $requestId   请求id
     * @param $expireTime  过期时间
     * @return bool        是否获取成功
     */
    public static function tryGetLock($redis, $key, $requestId, $expireTime) {
        $result = $redis->set(            $key,             $requestId,             self::MILLISECONDS_EXPIRE_TIME,             $expireTime,             self::IF_NOT_EXIST        );                return self::LOCK_SUCCESS === (string)$result;
    }
}

定义一些Redis的操作符作为常量, 加锁的代码其实很简单, 一行代码即可. 简单解释下这个set方法的五个参数:

  • 第一个key是锁的名字, 这个由具体业务逻辑控制, 保证唯一即可

  • 第二个是请求ID, 可能不好理解. 这样做的目的主要是为了保证加解锁的唯一性. 这样我们就可以知道该锁是哪个客户端加的.

  • 第三个参数是一个标识符, 标识时间戳以毫秒为最小单位

  • 具体的过期时间

  • 这个参数是NX, 表示当key不存在时我们才进行set操作

PS. 请求的唯一性ID生成方式很多, 可以参考下这个chronos. 该库涉及到Thrift的RPC调用, 可能上手会比较麻烦, 下回给出一个简单的PHP实现.

简单解释下上面的那段代码, 设置NX保证了只能有一个客户端获取到锁, 满足互斥性; 加入了过期时间, 保证在客户端崩溃后不会造成死锁; 请求ID的作用是用来标识客户端, 这样客户端在解锁的时候可以进行校验是否同一个客户端.







请到「今天看啥」查看全文