• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    解锁redis锁的正确姿势

    解锁redis锁的正确姿势

    redis是php的好朋友,在php写业务过程中,有时候会使用到锁的概念,同时只能有一个人可以操作某个行为。这个时候我们就要用到锁。锁的方式有好几种,php不能在内存中用锁,不能使用zookeeper加锁,使用数据库做锁又消耗比较大,这个时候我们一般会选用redis做锁机制。

    setnx

    锁在redis中最简单的数据结构就是string。最早的时候,上锁的操作一般使用setnx,这个命令是当:lock不存在的时候set一个val,或许你还会记得使用expire来增加锁的过期,解锁操作就是使用del命令,伪代码如下:

    if (Redis::setnx("my:lock", 1)) {
      Redis::expire("my:lock", 10);
      // ... do something
    
      Redis::del("my:lock")
    }
    
    

    这里其实是有问题的,问题就在于setnx和expire中间如果遇到crash等行为,可能这个lock就不会被释放了。于是进一步的优化方案可能是在lock中存储timestamp。判断timestamp的长短。

    set

    现在官方建议直接使用set来实现锁。我们可以使用set命令来替代setnx,就是下面这个样子

    if (Redis::set("my:lock", 1, "nx", "ex", 10)) {
      ... do something
    
      Redis::del("my:lock")
    }
    
    

    上面的代码把my:lock设置为1,当且仅当这个lock不存在的时候,设置完成之后设置过期时间为10。

    获取锁的机制是对了,但是删除锁的机制直接使用del是不对的。因为有可能导致误删别人的锁的情况。

    比如,这个锁我上了10s,但是我处理的时间比10s更长,到了10s,这个锁自动过期了,被别人取走了,并且对它重新上锁了。那么这个时候,我再调用Redis::del就是删除别人建立的锁了。

    官方对解锁的命令也有建议,建议使用lua脚本,先进行get,再进行del

    程序变成:

    $token = rand(1, 100000);
    
    function lock() {
      return Redis::set("my:lock", $token, "nx", "ex", 10);
    }
    
    function unlock() {
      $script = `
    if redis.call("get",KEYS[1]) == ARGV[1]
    then
      return redis.call("del",KEYS[1])
    else
      return 0
    end  
      `
      return Redis::eval($script, "my:lock", $token)
    }
    
    if (lock()) {
      // do something
    
      unlock();
    }
    
    

    这里的token是一个随机数,当lock的时候,往redis的my:lock中存的是这个token,unlock的时候,先get一下lock中的token,如果和我要删除的token是一致的,说明这个锁是之前我set的,否则的话,说明这个锁已经过期,是别人set的,我就不应该对它进行任何操作。

    所以:不要再使用setnx,直接使用set进行锁实现。

    以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

    您可能感兴趣的文章:
    • 详解Java如何实现基于Redis的分布式锁
    • Redis实现分布式锁的几种方法总结
    • redis实现加锁的几种方法示例详解
    • Redis上实现分布式锁以提高性能的方案研究
    • Redis数据库中实现分布式锁的方法
    • php结合redis实现高并发下的抢购、秒杀功能的实例
    • Redis高并发问题的解决方法
    • Redis瞬时高并发秒杀方案总结
    • 如何利用Redis锁解决高并发问题详解
    上一篇:Redis发布订阅和实现.NET客户端详解
    下一篇:Redis优化经验总结(必看篇)
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    解锁redis锁的正确姿势 解锁,redis,锁,的,正确,姿势,