[Redis 分布式锁 ]

这篇具有很好参考价值的文章主要介绍了[Redis 分布式锁 ]。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

前言:  

使用场景:

基于 Redis 实现分布式锁的详细示例:

使用示例:

依赖:

Redis分布式锁控制并发访问:


前言:  

   记录一些小笔记 , 如果对你有帮助 那就更好了

使用场景:

Redis 实现分布式锁的使用场景包括:

  1. 防止重复操作:在分布式环境下,多个进程可能同时对同一个资源进行操作,为了避免重复操作,可以使用分布式锁来保证只有一个进程可以对资源进行操作。

  2. 控制并发访问:在高并发场景下,多个进程同时访问同一个资源可能会导致性能问题,为了控制并发访问,可以使用分布式锁来限制同时访问的进程数量。

  3. 保证数据一致性:在分布式事务场景下,需要保证多个操作的原子性,可以使用分布式锁来保证多个操作的顺序和一致性。

  4. 避免死锁:在分布式环境下,多个进程可能同时获取锁,为了避免死锁,可以使用分布式锁来保证只有一个进程可以持有锁。

总之,分布式锁是在分布式环境下保证数据一致性和避免并发问题的重要工具,适用于各种分布式应用场景。

基于 Redis 实现分布式锁的详细示例:

import redis.clients.jedis.Jedis;
import redis.clients.jedis.params.SetParams;

public class RedisDistributedLock {
    private static final String LOCK_KEY = "lock_key";
    private static final int LOCK_EXPIRE_TIME = 30000; // 锁过期时间,单位毫秒
    private static final int SLEEP_TIME = 100; // 获取锁失败后,等待重试的时间,单位毫秒

    private Jedis jedis;

    public RedisDistributedLock(Jedis jedis) {
        this.jedis = jedis;
    }

    public boolean lock() {
        while (true) {
            SetParams params = new SetParams();
            params.nx();
            params.px(LOCK_EXPIRE_TIME);
            String result = jedis.set(LOCK_KEY, "locked", params);
            if ("OK".equals(result)) {
                return true;
            }
            try {
                Thread.sleep(SLEEP_TIME);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }

    public void unlock() {
        jedis.del(LOCK_KEY);
    }
}

在上面的示例中,我们使用了 Redis 的 SETNX 命令来实现分布式锁。当 SETNX 命令返回 1 时,表示成功获取到锁,否则表示锁已被其他进程占用,需要等待一段时间后重试。为了避免死锁,我们还设置了锁的过期时间,当锁过期后,其他进程可以重新获取锁。

使用示例:

import redis.clients.jedis.Jedis;

public class Main {
    public static void main(String[] args) {
        Jedis jedis = new Jedis("localhost");
        RedisDistributedLock lock = new RedisDistributedLock(jedis);
        try {
            if (lock.lock()) {
                // 获取锁成功,执行业务逻辑
            } else {
                // 获取锁失败,处理异常情况
            }
        } finally {
            lock.unlock();
        }
    }
}

在实际应用中,我们需要根据具体的业务需求和系统架构来调整分布式锁的实现方式。例如,可以使用 Redis 的 Lua 脚本来实现原子性操作,或者使用 Redlock 算法来提高分布式锁的可靠性。

依赖:

上述代码需要依赖 Redis 的 Java 客户端库,例如 Jedis 或 Lettuce。以下是 Maven 依赖示例:

根据实际情况选择合适的 Redis 客户端库和版本。

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>3.6.0</version>
</dependency>

<dependency>
    <groupId>io.lettuce</groupId>
    <artifactId>lettuce-core</artifactId>
    <version>6.1.3.RELEASE</version>
</dependency>
 


Redis分布式锁控制并发访问:

Redis 分布式锁可以用来控制并发访问,避免多个进程同时访问同一个资源导致的性能问题。具体来说,可以使用 Redis 分布式锁来限制同时访问某个资源的进程数量,例如:

  1. 获取锁时,检查当前已经持有锁的进程数量,如果超过了限制数量,则等待一段时间后重试。

  2. 在释放锁时,检查是否还有其他进程在等待锁,如果有,则唤醒其中一个进程继续执行。

下面是一个使用 Redis 分布式锁控制并发访问的示例:

import redis.clients.jedis.Jedis;
import redis.clients.jedis.params.SetParams;

public class RedisConcurrencyControl {
    private static final String LOCK_KEY = "lock_key";
    private static final int LOCK_EXPIRE_TIME = 30000; // 锁过期时间,单位毫秒
    private static final int SLEEP_TIME = 100; // 获取锁失败后,等待重试的时间,单位毫秒
    private static final int MAX_CONCURRENCY = 10; // 最大并发数

    private Jedis jedis;

    public RedisConcurrencyControl(Jedis jedis) {
        this.jedis = jedis;
    }

    public boolean acquireLock() {
        while (true) {
            SetParams params = new SetParams();
            params.nx();
            params.px(LOCK_EXPIRE_TIME);
            String result = jedis.set(LOCK_KEY, "locked", params);
            if ("OK".equals(result)) {
                return true;
            }
            try {
                Thread.sleep(SLEEP_TIME);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }

    public void releaseLock() {
        jedis.del(LOCK_KEY);
        String waitingKey = LOCK_KEY + "_waiting";
        String waitingCount = jedis.get(waitingKey);
        if (waitingCount != null) {
            int count = Integer.parseInt(waitingCount);
            if (count > 0) {
                jedis.decr(waitingKey);
                jedis.publish(waitingKey, "1");
            } else {
                jedis.del(waitingKey);
            }
        }
    }

    public boolean tryEnter() {
        String waitingKey = LOCK_KEY + "_waiting";
        String waitingCount = jedis.get(waitingKey);
        if (waitingCount == null) {
            jedis.set(waitingKey, "1");
            jedis.expire(waitingKey, LOCK_EXPIRE_TIME);
            return true;
        } else {
            int count = Integer.parseInt(waitingCount);
            if (count < MAX_CONCURRENCY) {
                jedis.incr(waitingKey);
                jedis.expire(waitingKey, LOCK_EXPIRE_TIME);
                return true;
            } else {
                return false;
            }
        }
    }

    public void waitEnter() {
        String waitingKey = LOCK_KEY + "_waiting";
        jedis.subscribe(new JedisPubSub() {
            @Override
            public void onMessage(String channel, String message) {
                synchronized (RedisConcurrencyControl.this) {
                    RedisConcurrencyControl.this.notifyAll();
                }
            }
        }, waitingKey);
    }
}

在上面的示例中,我们使用 Redis 分布式锁来控制最大并发数。在进程尝试访问资源时,首先需要获取锁,如果获取锁失败,则等待一段时间后重试。如果获取锁成功,则检查当前已经持有锁的进程数量,如果超过了最大并发数,则将自己加入等待队列,并等待其他进程释放锁后唤醒自己。在释放锁时,需要检查等待队列中是否有其他进程在等待,如果有,则唤醒其中一个进程继续执行。

使用示例:

import redis.clients.jedis.Jedis;

public class Main {
    public static void main(String[] args) {
        Jedis jedis = new Jedis("localhost");
        RedisConcurrencyControl control = new RedisConcurrencyControl(jedis);
        try {
            if (control.acquireLock()) {
                if (control.tryEnter()) {
                    // 进程成功进入资源访问队列,执行业务逻辑
                } else {
                    // 进程无法进入资源访问队列,等待其他进程释放锁
                    control.waitEnter();
                }
            } else {
                // 获取锁失败,处理异常情况
           

Redis文档学习地址:  必须点个三连好吧, 步步高升 7. 分布式集合 - 7.1. 映射(Map) - 《Redisson 使用手册》 - 书栈网 · BookStack文章来源地址https://www.toymoban.com/news/detail-473243.html

到了这里,关于[Redis 分布式锁 ]的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 2、基于redis实现分布式锁

    借助于redis中的命令setnx(key, value),key不存在就新增,存在就什么都不做。同时有多个客户端发送setnx命令,只有一个客户端可以成功,返回1(true);其他的客户端返回0(false)。 多个客户端同时获取锁(setnx) 获取成功,执行业务逻辑,执行完成释放锁(del) 其他客户端等

    2024年02月15日
    浏览(66)
  • 基于 SpringBoot + Redis 实现分布式锁

    大家好,我是余数,这两天温习了下分布式锁,然后就顺便整理了这篇文章出来。 文末附有源码链接,需要的朋友可以自取。 至于什么是分布式锁,这里不做赘述,不了解的可以自行去查阅资料。 1. 使用 Redis 的 Setnx(SET if Not Exists) 命令加锁。 即锁不存在的时候才能加锁成功

    2024年02月05日
    浏览(55)
  • 基于Redis的分布式限流详解

    Redis除了能用作缓存外,还有很多其他用途,比如分布式锁,分布式限流,分布式唯一主键等,本文将和大家分享下基于Redis分布式限流的各种实现方案。 用最简单的话来说: 外部请求是不可控的,而我们系统的负载是有限的,如果没有限流机制,一旦外部请求超过系统承载

    2024年02月04日
    浏览(56)
  • 自定义注解,基于redis实现分布式锁

    1.1、注解的基础知识 实现自定义注解其实很简单,格式基本都差不多。也就参数可能变一变。 @Retention:取值决定了注解在什么时候生效,一般都是取运行时,也就是RetentionPolicy.RUNTIME。 @Target:决定了这个注解可以使用在哪些地方,可以取方法,字段,类等。 注解这就定义

    2024年02月08日
    浏览(38)
  • 基于Redis的分布式锁到底安全吗(下)

    原文链接跳转 - 张铁蕾 今天,我们就继续探讨这个话题的后半部分。本文中,我们将从antirez反驳Martin Kleppmann的观点开始讲起,然后会涉及到Hacker News上出现的一些讨论内容,接下来我们还会讨论到基于Zookeeper和Chubby的分布式锁是怎样的,并和Redlock进行一些对比。最后,我们

    2024年04月10日
    浏览(38)
  • 分享8个分布式Kafka的使用场景

    Kafka 最初是为海量日志处理而构建的。它保留消息直到过期,并让消费者按照自己的节奏提取消息。与它的前辈不同,Kafka 不仅仅是一个消息队列,它还是一个适用于各种情况的开源事件流平台。 下图显示了典型的 ELK(Elastic-Logstash-Kibana)堆栈。Kafka 有效地从每个实例收集日

    2024年02月08日
    浏览(43)
  • 【Redis从入门到进阶】第 7 讲:基于 Redis 实现分布式锁

    本文已收录于专栏 🍅《Redis从入门到进阶》🍅    本专栏开启,目的在于帮助大家更好的掌握学习 Redis ,同时也是为了记录我自己学习 Redis 的过程,将会从基础的数据类型开始记录,直到一些更多的应用,如缓存击穿还有分布式锁等。希望大家有问题也可以一起沟通,欢

    2023年04月26日
    浏览(42)
  • 使用redis实现分布式锁

    在一个分布式系统中,也会涉及多个节点访问同一个公共资源的情况,此时就需要通过锁来做互斥控制,避免出现类似于“线程安全”的问题,而java的synchronized这样的锁只能在当前进程中生效,在分布式的这种多个进程多个主机的场景无能为力,此时就需要分布式锁。 例如

    2024年02月07日
    浏览(57)
  • SpringCloud学习路线(11)——分布式搜索ElasticSeach场景使用

    一、DSL查询文档 (一)DSL查询分类 ES提供了基于JSON的DSL来定义查询。 1、常见查询类型: 查询所有: 查询出所有的数据,例如,match_all 全文检索(full text)查询: 利用分词器对用户输入内容分词,然后去倒排索引库中匹配。例如: match_query multi_match_query 精确查询: 根据精

    2024年02月16日
    浏览(40)
  • 使用注解实现REDIS分布式锁

    有些业务请求,属于耗时操作,需要加锁,防止后续的并发操作,同时对数据库的数据进行操作,需要避免对之前的业务造成影响。 使用 Redis 作为分布式锁,将锁的状态放到 Redis 统一维护,解决集群中单机 JVM 信息不互通的问题,规定操作顺序,保护用户的数据正确。 梳理

    2024年02月02日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包