zoukankan      html  css  js  c++  java
  • 了解分布式锁

    分布式锁

    为什么需要分布式锁

    • 应用中需要避免多个线程在同一时间对同一个共享变量做修改
    • 在单机部署的项目中,为了避免上述现象,需要对变量或代码块做同步
    • 在分布式部署的项目中,为了避免上述现象,用同步是解决不了的(因为相同的项目部署在了多台服务器,同步只能解决单台服务器的问题),所以就需要分布式锁,保证在分布式部署的应用集群中,同一个方法在同一时间只能被一台机器上的一个线程执行

    分布式锁有几种实现方式

    主流的实现方式有三种
    1、利用数据库实现
    2、利用缓存(redis)实现
    3、利用zookeeper实现

    简述各种方式及优缺点

    1、利用数据库实现

    优点:简单、易理解
    缺点:高并发时,性能差,增加了数据库开销

    方法一:

    • 新建一张表,向该表中添加相同主键的一条记录, 哪个线程添加成功,即获得了分布式锁,
    • 然后执行相关逻辑,逻辑执行完之后,删除数据库表中的该数据,删除即代表解锁

    方法二、

    • 使用for update,数据表会在查询的时候添加排它锁,
    • 多个线程同时来执行时,只有一个会成功加锁,其余的线程都会阻塞,
    • 加锁成功的线程即获得分布式锁的线程,该线程执行相关逻辑,
    • 逻辑执行完之后,使用connection.commit解锁,此时阻塞的其他线程中会有一个加锁成功....

    2、使用redis缓存实现

    优点:效率高
    缺点:设置过期时间过长过短都不合适,需要根据实际情况权衡

    大概思路:

    • 向redis中添加key,并设置过期时间
    • 如果key已存在,则添加失败
    • 如果key不存在,则添加成功
    • 添加成功,即获得了分布式锁
    • 获得锁的线程执行业务逻辑,执行完之后,删除redis中的key(即解锁)

    3、通过zookeeper实现

    优点:有效的解决单点问题,不可重入问题,非阻塞问题以及锁无法释放的问题。实现起来较为简单
    缺点:因为每次在创建锁和释放锁的过程中,都要动态创建、销毁临时节点来实现锁功能。
    ZK中创建和删除节点只能通过Leader服务器来执行,然后将数据同步到所有的 Follower 机器上。

    大概思路:

    • 每一个锁都是zookeeper上的一个znode(普通节点)
    • 当多个线程来获取锁时,都会在该znode上创建有序临时子节点,每个有序临时子节点都有自己的序号
    • 只有序号最小的可以拥有锁,然后执行相关逻辑,执行完成之后删除子节点(即解锁),触发监听
    • 序号如果不是最小的,则没有获得锁,设置监听事件,监听序号比本身小的前一个节点,
    • 等待事件触发再次比较是否是最小的
  • 相关阅读:
    H5分栏(第一章)
    数据库操作集合
    sql 存储过程
    数据库事务
    Sql 分页三种方式
    GridView 后台分页
    GridView 分页 上一页 下一页 跳转 前端分页
    GridView 分页
    web前端开发分享-css,js入门篇(转)
    Intellij IDEA,WebStorm-keymap(转)
  • 原文地址:https://www.cnblogs.com/jis121/p/10899388.html
Copyright © 2011-2022 走看看