• redis 实现锁


    1. redis加锁分类

    redis能用的的加锁命令分表是INCR、SETNX、SET

    2. 第一种锁命令INCR

    这种加锁的思路是, key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作进行加一。
    然后其它用户在执行 INCR 操作进行加一时,如果返回的数大于 1 ,说明这个锁正在被使用当中。

        1、 客户端A请求 服务器 获取key的值为1表示获取了锁 

        2、 客户端B也去请求服务器获取key的值为2表示获取锁失败

        3、 客户端A执行代码完成,删除锁

        4、 客户端B在等待一段时间后在去请求的时候获取key的值为1表示获取锁成功

        5、 客户端B执行代码完成,删除锁

     $redis->incr($key);
     $redis->expire($key, $ttl); //设置生成时间为1秒

    3. 第二种锁SETNX

    这种加锁的思路是,如果 key 不存在,将 key 设置为 value

    如果 key 已存在,则 SETNX 不做任何动作

        1、 客户端A请求服务器设置key的值,如果设置成功就表示加锁成功

        2、 客户端B也去请求服务器设置key的值,如果返回失败,那么就代表加锁失败

        3、 客户端A执行代码完成,删除锁

        4、 客户端B在等待一段时间后在去请求设置key的值,设置成功

        5、 客户端B执行代码完成,删除锁   

      $redis->setNX($key, $value);
      $redis->expire($key, $ttl);

    4. 第三种锁SET

    上面两种方法都有一个问题,会发现,都需要设置 key 过期。那么为什么要设置key过期呢?如果请求执行因为某些原因意外退出了,导致创建了锁但是没有删除锁,那么这个锁将一直存在,以至于以后缓存再也得不到更新。于是乎我们需要给锁加一个过期时间以防不测。

    但是借助 Expire 来设置就不是原子性操作了。所以还可以通过事务来确保原子性,但是还是有些问题,所以官方就引用了另外一个,使用 SET 命令本身已经从版本 2.6.12 开始包含了设置过期时间的功能。

        1、 客户端A请求服务器设置key的值,如果设置成功就表示加锁成功

        2、 客户端B也去请求服务器设置key的值,如果返回失败,那么就代表加锁失败

        3、 客户端A执行代码完成,删除锁

        4、 客户端B在等待一段时间后在去请求设置key的值,设置成功

        5、 客户端B执行代码完成,删除锁

      $redis->set($key, $value, array('nx', 'ex' => $ttl)); //ex表示秒



    ====================

     我们不用记录cuid,只要把redis作为我们的锁就行。

    客服1和客服2同时接入,
    客服1请求锁成功,则进行接入,接入后删除锁,
    客服2请求锁不成功,就一直循环
    while 请求锁不成功:
        查找优先级最高的客户uid
        请求锁,
        接入客户


    ======================
    也可用来限制并发量
    https://cloud.tencent.com/developer/article/1376410
  • 相关阅读:
    Android项目几种常见的应用架构
    PreferenceCategory背景颜色设置
    xml中怎样换行?
    Windows 7启动Telnet
    android图片处理方法(转)
    android SDK下载失败和更新方法
    JBoss 5.1.0 GA:Error installing to Instantiated:name=AttachmentStore state=Described
    window常用的『运行』命令
    在linux中eclipse连接android手机开发程序
    [leetcode]Binary Tree Level Order Traversal
  • 原文地址:https://www.cnblogs.com/yjybupt/p/11737257.html
Copyright © 2020-2023  润新知