iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >分别使用Redis、MySQL、ZooKeeper构建分布式锁
  • 311
分享到

分别使用Redis、MySQL、ZooKeeper构建分布式锁

分布式redismysql 2023-09-16 20:09:25 311人浏览 薄情痞子
摘要

文章目录 前言一、分布式锁简介二、分布式锁要求三、实现方案四、数据库分布式锁1、悲观锁2、乐观锁 五、Zookeeper分布式锁1、引入Curator和ZooKeeper2、配置ZooKe

文章目录

前言

本文使用Java构建三种中间件分布式,下面介绍下三种分布式锁的优缺点,
使用MySQL构建分布式锁,因为数据库数据存储在磁盘中,所以io速率相对较慢,因此构建出来的分布式锁不适合用在高并发场景,对于一些对并发要求不高的系统中可以使用,进一步提高系统的安全稳定性,提升数据库容错
使用Redis构建分布式锁,都知道Redis处理数据是在内存中进行处理,执行效率很高,成为很多开发者设计分布式锁的不二之选,这里需要注意的时,redis在主从切换时,可能会出现锁丢失的情况,也是我们不可忽略的问题。
使用ZooKeeper构建分布式锁,总所周知,ZooKeeper是一个高可用的分布式协调服务,因此使用它来构建分布式锁,无疑性能是三者之中相对来说性能较好的,它可以很好的保证了数据的强一致性,但是使用ZooKeeper需要部署额外的服务,增加了系统复杂度
所以,没有最好的解决方案,只有最适合自己的解决方案。


一、分布式锁简介

分布式锁听名字就才得到,肯定时应用在分布式系统中,锁在Java技术中通常用来解决高并发访问共享资源的问题,那么分布式锁就是解决分布式系统中多个线程或者进程高并发访问共享资源的一种技术,
在分布式系统中,由于各个节点之间的网路通信延迟、故障等原因,可能会导致数据不一致的问题,分布式锁通过协调多个节点的行为,保证在任何时候只有一个节点可以访问资源,以避免数据的不一致性和冲突。


二、分布式锁要求

分布式锁通常需要满足以下几个要求:

  1. 互斥性:在任意时刻只能有一个客户端持有锁。
  2. 不会发生死锁:即使持有锁的客户端发生故障,也能保证锁最终会被释放。
  3. 具有容错性:分布式锁需要能够容忍节点故障等异常情况,保证系统的稳定性。

三、实现方案

在 Java 中,实现分布式锁的方案有多种,包括:

  1. 基于数据库实现的分布式锁:可以通过数据库的乐观锁或悲观锁实现分布式锁,但是由于数据库的 IO 操作比较慢,不适合高并发场景。
  2. 基于 ZooKeeper 实现的分布式锁:ZooKeeper 是一个高可用性的分布式协调服务,可以通过它来实现分布式锁。但是使用 ZooKeeper 需要部署额外的服务,增加了系统复杂度。
  3. 基于 Redis 实现的分布式锁:Redis 是一个高性能的内存数据库,支持分布式部署,可以通过Redis的原子操作实现分布式锁,而且具有高性能和高可用性。

四、数据库分布式锁

数据库的乐观锁或悲观锁都可以实现分布式锁,下面分别来看。

1、悲观锁

在数据库中使用 for update 关键字可以实现悲观锁,我们在 Mapper 中添加 for update 即可对数据加锁,实现代码如下:

<select id="selectByIdForUpdate" resultType="User">    SELECT * FROM user WHERE id = #{id} FOR UPDATEselect>

在 Service 中调用 Mapper 方法,即可获取到加锁的数据:

@Transactionalpublic void updateWithPessimisticLock(int id, String name) {    User user = userMapper.selectByIdForUpdate(id);    if (user != null) {        user.setName(name);        userMapper.update(user);    } else {        throw new RuntimeException("数据不存在");    }}

2、乐观锁

mybatis 中,可以通过给表添加一个版本号字段来实现乐观锁。在 Mapper 中,使用标签定义更新语句,同时使用 set 标签设置版本号的增量。

<update id="updateWithOptimisticLock">    UPDATE user SET    name = #{name},    version = version + 1    WHERE id = #{id} AND version = #{version}update>

在 Service 中调用 Mapper 方法,需要传入更新数据的版本号。如果更新失败,说明数据已经被其他事务修改,具体实现代码如下:

@Transactionalpublic void updateWithOptimisticLock(int id, String name, int version) {    User user = userMapper.selectById(id);    if (user != null) {        user.setName(name);        user.setVersion(version);        int rows = userMapper.updateWithOptimisticLock(user);        if (rows == 0) {            throw new RuntimeException("数据已被其他事务修改");        }    } else {        throw new RuntimeException("数据不存在");    }}

五、Zookeeper分布式锁

Spring Boot 中,可以使用 Curator 框架来实现 ZooKeeper 分布式锁,具体实现分为以下 3 步:

  1. 引入 Curator 和 ZooKeeper 客户端依赖;
  2. 配置 ZooKeeper 连接信息;
  3. 编写分布式锁实现类。

1、引入Curator和ZooKeeper

<dependency>    <groupId>org.apache.curatorgroupId>    <artifactId>curator-frameworkartifactId>    <version>latestversion>dependency><dependency>    <groupId>org.apache.curatorgroupId>    <artifactId>curator-recipesartifactId>    <version>latestversion>dependency><dependency>    <groupId>org.apache.zookeepergroupId>    <artifactId>zookeeperartifactId>    <version>latestversion>dependency>

2、配置ZooKeeper连接

在 application.yml 中添加 ZooKeeper 连接配置:

spring:  zookeeper:    connect-string: localhost:2181    namespace: demo

3、编写分布式实现类

@Componentpublic class DistributedLock {    @Autowired    private CuratorFramework curatorFramework;        public InterProceSSMutex acquire(String lockPath, long waitTime, long leaseTime, TimeUnit timeUnit) throws Exception {        InterProcessMutex lock = new InterProcessMutex(curatorFramework, lockPath);        if (!lock.acquire(waitTime, timeUnit)) {            throw new RuntimeException("获取分布式锁失败");        }        if (leaseTime > 0) {            lock.acquire(leaseTime, timeUnit);        }        return lock;    }        public void release(InterProcessMutex lock) throws Exception {        if (lock != null) {            lock.release();        }    }}

六、Redis分布式锁

我们可以使用 Redis 客户端 Redisson 实现分布式锁,它的实现步骤如下:

  1. 添加 Redisson 依赖
  2. 配置 Redisson 连接信息
  3. 编写分布式锁代码类

1、添加Redisson依赖

在pom.xml中添加如下配置

<dependency>    <groupId>org.redissongroupId>    <artifactId>redisson-spring-boot-starterartifactId>    <version>3.20.0version>dependency>

2、配置Redission连接

在 Spring Boot 项目的配置文件 application.yml 中添加 Redisson 配置:

spring:  data:    redis:      host: localhost      port: 6379      database: 0redisson:  codec: org.redisson.codec.JSONJacksonCodec  single-server-config:    address: "redis://${spring.data.redis.host}:${spring.redis.port}"    database: "${spring.data.redis.database}"    passWord: "${spring.data.redis.password}"

3、编写分布式锁代码类

import jakarta.annotation.Resource;import org.redisson.Redisson;import org.redisson.api.RLock;import org.springframework.stereotype.Service;import java.util.concurrent.TimeUnit;@Servicepublic class RedissonLockService {    @Resource    private Redisson redisson;        public boolean tryLock(String key, long timeout, TimeUnit unit) {        RLock lock = redisson.getLock(key);        try {            return lock.tryLock(timeout, unit);        } catch (InterruptedException e) {            Thread.currentThread().interrupt();            return false;        }    }        public void unlock(String key) {        RLock lock = redisson.getLock(key);        lock.unlock();    }}

七、Redis锁与ZooKeeper分布式锁的区别

Redis 和 ZooKeeper 都可以用来实现分布式锁,它们在实现分布式锁的机制和原理上有所不同,具体区别如下:

  1. 数据存储方式:Redis 将锁信息存储在内存中,而 ZooKeeper 将锁信息存储在 ZooKeeper 的节点上,因此 ZooKeeper 需要更多的磁盘空间。
  2. 锁的释放:Redis 的锁是通过设置锁的过期时间来自动释放的,而 ZooKeeper 的锁需要手动释放,如果锁的持有者出现宕机或网络中断等情况,需要等待锁的超时时间才能自动释放。
  3. 锁的竞争机制:Redis 使用的是单机锁,即所有请求都直接连接到同一台 Redis 服务器,容易发生单点故障;而 ZooKeeper 使用的是分布式锁,即所有请求都连接到 ZooKeeper 集群,具有较好的可用性和可扩展性。
  4. 一致性:Redis 的锁是非严格意义下的分布式锁,因为在多台机器上运行多个进程时,由于 Redis 的主从同步可能会存在数据不一致的问题;而 ZooKeeper 是强一致性的分布式系统,保证了数据的一致性。
  5. 性能:Redis 的性能比 ZooKeeper 更高,因为 Redis 将锁信息存储在内存中,而 ZooKeeper 需要进行磁盘读写操作。

总结,Redis 适合实现简单的分布式锁场景,而 ZooKeeper 适合实现复杂的分布式协调场景,也就是 ZooKeeper 适合强一致性的分布式系统。

知识点:强一致性是指系统中的所有节点在任何时刻看到的数据都是一致的。ZooKeeper
中的数据是有序的树形结构,每个节点都有唯一的路径标识符,所有节点都共享同一份数据,当任何一个节点对数据进行修改时,所有节点都会收到通知,更新数据,并确保数据的一致性。在
ZooKeeper 中,强一致性体现在数据的读写操作上。ZooKeeper 使用 ZAB(ZooKeeper Atomic
Broadcast)协议来保证数据的一致性,该协议确保了数据更新的顺序,所有的数据更新都需要经过集群中的大多数节点确认,保证了数据的一致性和可靠性。


备注

本文根据51CTO博主磊哥文章一步步操作实现之后,做的笔记
原文连接:https://www.51cto.com/article/766555.html

来源地址:https://blog.csdn.net/weixin_44479706/article/details/132849370

您可能感兴趣的文档:

--结束END--

本文标题: 分别使用Redis、MySQL、ZooKeeper构建分布式锁

本文链接: https://www.lsjlt.com/news/410311.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 分别使用Redis、MySQL、ZooKeeper构建分布式锁
    文章目录 前言一、分布式锁简介二、分布式锁要求三、实现方案四、数据库分布式锁1、悲观锁2、乐观锁 五、Zookeeper分布式锁1、引入Curator和ZooKeeper2、配置ZooKe...
    99+
    2023-09-16
    分布式 redis mysql
  • 使用Zookeeper实现分布式锁
    目录什么是临时顺序节点?Znode分为四种类型1.持久节点 (PERSISTENT)2.持久节点顺序节点(PERSISTENT_SEQUENTIAL)3.临时节点(EPHEMERAL...
    99+
    2022-11-13
    Zookeeper分布式锁 分布式锁 使用分布式锁
  • redis和zookeeper中怎么实现分布式锁
    redis和zookeeper中怎么实现分布式锁,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。   一、基于redis的分布...
    99+
    2024-04-02
  • 浅谈分布式锁的几种使用方式(redis、zookeeper、数据库)
    Q:一个业务服务器,一个数据库,操作:查询用户当前余额,扣除当前余额的3%作为手续费 synchronized lock dblock Q:两个业务服务器,一个数据库,操作:查询用户当前余额...
    99+
    2024-04-02
  • 分析ZooKeeper分布式锁的实现
    目录一、分布式锁方案比较二、ZooKeeper实现分布式锁2.1、方案一2.2、方案二一、分布式锁方案比较 方案 ...
    99+
    2024-04-02
  • 怎么使用redis分布式锁
    本篇内容介绍了“怎么使用redis分布式锁”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1. redis在实际的应用中不仅可以用来缓存数据,...
    99+
    2023-06-25
  • redis分布式锁怎么使用
    使用Redis分布式锁的一般步骤如下: 获取锁:在Redis中使用SET命令尝试设置一个带有过期时间的键值对作为锁。可以使用命令...
    99+
    2023-10-21
    redis
  • 详解redis分布式锁(优化redis分布式锁的过程及Redisson使用)
    目录1. redis在实际的应用中2.如何使用redis的功能进行实现分布式锁2.1 redis分布式锁思想2.1.1设计思想:2.1.2 根据上面的设计思想进行代码实现2.2 使用...
    99+
    2024-04-02
  • ZooKeeper分布式锁的实现方式
    本篇内容介绍了“ZooKeeper分布式锁的实现方式”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!目录一、分布式锁方案比较二、ZooKeep...
    99+
    2023-06-20
  • Zookeeper如何实现分布式锁
    这篇“Zookeeper如何实现分布式锁”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Zookeeper如何实现分布式锁”文...
    99+
    2023-06-27
  • zookeeper分布式锁如何实现
    这篇文章主要介绍“zookeeper分布式锁如何实现”,在日常操作中,相信很多人在zookeeper分布式锁如何实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”zookeeper分布式锁如何实现”的疑惑有所...
    99+
    2023-06-27
  • Redis分布式锁介绍与使用
    目录分布式锁业务逻辑分析Redis命令代码实现分布式锁误删问题问题原因分析代码实现Lua脚本首先,使用idea模拟搭建一个tomcat服务器集群,并使用Nginx对集群中的服务器实现...
    99+
    2024-04-02
  • redis分布式锁与zk分布式锁的对比分析
    目录Redis实现分布式锁原理能实现的锁类型注意事项 zk实现分布式锁原理能实现的锁类型两种锁的对比在分布式环境下,传统的jvm级别的锁会失效,那么分布式锁就是非常有必要的一个技术,一般我们可以通过redis,...
    99+
    2022-11-18
    redis分布式锁 分布式锁 zk分布式锁
  • 怎么用springboot+zookeeper实现分布式锁
    本篇内容主要讲解“怎么用springboot+zookeeper实现分布式锁”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么用springboot+zookeeper实现分布式锁”吧!Inte...
    99+
    2023-06-29
  • Zookeeper的分布式锁的实现方式
    这篇文章主要讲解了“Zookeeper的分布式锁的实现方式”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Zookeeper的分布式锁的实现方式”吧!1. 背景最近在学习 Zookeeper,...
    99+
    2023-06-05
  • InterProcessMutex实现zookeeper分布式锁原理
    原理简介: zookeeper实现分布式锁的原理就是多个节点同时在一个指定的节点下面创建临时会话顺序节点,谁创建的节点序号最小,谁就获得了锁,并且其他节点就会监听序号比自己小的节点,...
    99+
    2024-04-02
  • Java如何实现ZooKeeper分布式锁
    这篇文章主要介绍了Java如何实现ZooKeeper分布式锁,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。什么是分布式锁在我们进行单机应用开发,涉及并发同步的时候,我们往往采...
    99+
    2023-06-29
  • ZooKeeper中怎么处理分布式锁
    在ZooKeeper中处理分布式锁通常使用临时有序节点来实现。具体步骤如下: 在ZooKeeper的指定节点下创建一个顺序临时节点...
    99+
    2024-04-02
  • 如何使用Redis实现分布式锁
    这篇文章将为大家详细讲解有关如何使用Redis实现分布式锁,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。加锁部分解锁部分主要原理是使用了 redis 的 s...
    99+
    2024-04-02
  • Redis——》实现分布式锁
    推荐链接:     总结——》【Java】     总结——》【Mysql】     总结——》【Redis】     总结——》【Kafka】     总结——》【Spring】     总结—...
    99+
    2023-09-03
    redis 分布式 过期 lua
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作