zoukankan      html  css  js  c++  java
  • 作为一个面试官,我想问问你Redis分布式锁怎么搞?

    最强面试题推荐:
    作为一个面试官,我想问问你Redis分布式锁怎么搞?

    总结一下加锁过程:首先选择一台机器,然后发送一段lua脚本,带有三个参数:一个是锁的名字(在代码里指定的)、一个是锁的时常(默认30秒)、一个是加锁的客户端id(每个客户端对应一个id)。然后脚本会判断是否有该名字的锁,如果没有就往数据结构中加入该锁的客户端id。

    锁互斥机制

    作为一个面试官,我想问问你Redis分布式锁怎么搞?

     

    很简单,上面第一个if判断会执行“exists myLock”,如果发现myLock这个锁key已经存在了,就会进行第二个if判断,判断一下myLock锁key的hash数据结构中,是否包含客户端2的ID,但是明显不是的,因为那里包含的是客户端1的ID。

    所以,客户端2会获取到pttl myLock返回的一个数字,这个数字代表了myLock这个锁key的剩余生存时间。比如还剩15000毫秒的生存时间。

    此时客户端2会进入一个while循环,不停的尝试加锁。直到客户端1释放myLock这个锁。

    锁时间自动延迟机制

    客户端1加锁的默认时长是30秒,如果超过了30秒,客户端1还想持有这把锁该怎么办呢?机制如下:

    只要客户端1一旦加锁成功,就会启动一个watch dog看门狗,他是一个后台线程,会每隔10秒检查一下,如果客户端1还持有锁key,那么就会不断的延长锁key的生存时间。

    可重入加锁机制

    如果客户端1已经持有这把锁了,还想加锁,该怎么办呢?比如代码逻辑如下:

    Rlock lock = redisson.getLock(“myLock”);
    lock.lock();
    // 一坨代码
    lock.lock();
    // 一坨代码
    lock.unlock();
    lock.unlock();

    这时我们来分析一下上面那段lua脚本。第一个if判断肯定不成立,“exists myLock”会显示锁key已经存在了。第二个if判断会成立,因为myLock的hash数据结构中包含的那个ID,就是客户端1的那个ID,也就是“
    8743c9c0-0795-4907-87fd-6c719a6b4586:1”

    此时就会执行可重入加锁的逻辑,他会用:incrby myLock
    8743c9c0-0795-4907-87fd-6c71a6b4586:1 1 通过这个命令,对客户端1的加锁次数,累加1。

    此时,myLock的数据结构变成了这样:

    myLock:
    {
        “8743c9c0-0795-4907-87fd-6c719a6b4586:1”:2
    }

    可以看出,后面那个数字表示该id的锁的加锁次数。

    锁释放机制

    如果执行lock.unlock(),就可以释放分布式锁,此时的业务逻辑也是非常简单的。其实说白了,就是每次都对myLock数据结构中的那个加锁次数减1。如果发现加锁次数是0了,说明这个客户端已经不再持有锁了,此时就会用:“del myLock”命令,从redis里删除这个key。然后呢,另外的客户端2就可以尝试完成加锁了。

    这就是Redis分布式锁基于开源Redisson框架的实现机制。

    Redis分布式锁的缺点

    这种分布式锁最大的缺点在于:如果对某个redis-master实例写入了myLock这个key的锁的value,此时会异步复制数据到redis-slave实例上。

    但是在这个过程中发生了redis-master宕机了,主备切换,redis-slave变成了redis-master。

    紧接着,客户端2就来尝试加锁,在新的redis-master上加了锁,而此时客户端1也认为自己加了锁,这就导致多个客户端对同一个分布式锁完成了加锁。

  • 相关阅读:
    查看Oracle字符集
    Oracle备份还原表须知
    Oracle级联删除,删除用户的同时,将所分配到的表空间同时删除
    python logging模块(1) Marathon
    pycharm中调试django程序 Marathon
    sqlite数据表的增删改查操作 Marathon
    ubuntu 18.04配置固定ip Marathon
    django项目报错request请求不能处理问题 Marathon
    systemd.service配置 Marathon
    shell脚本学习之6小时搞定(1)入门 Marathon
  • 原文地址:https://www.cnblogs.com/yuxiang1/p/13086677.html
Copyright © 2011-2022 走看看