专栏首页程序员开发者社区Redis 分布式锁应用

Redis 分布式锁应用

缓存

Redis 最常使用的场景是作为缓存,缓存用户信息,会话信息,还有一些热点信息。

淘汰策略

缓存内存是有限制的,当 Redis 内存超出物理内存限制时,内存的数据会开始和磁盘产生频繁的交换(swap)。交换会让 Redis 性能急剧下降。

Redis 提供了maxmemory 来限制内存期望的大小。

当实际内存超过 maxmemory 时,Redis 提供了几种可选策略。

  • noeviciction 不会继续服务写请求。读请求可以继续执行。这样会保证数据不会丢失,但是会让线上业务不能继续进行。这个是默认的淘汰策略。
  • volatile-lru 尝试淘汰设置了过期时间的 key, 最少使用的 key 优先被淘汰。没有设置过期时间的 key 不会被淘汰。这样可以保证持久化的数据不会被淘汰
  • volatile-ttl 和volatil-lru 一样,也是淘汰设置过期的 key , 但是淘汰策略不是 LRU ,而是 key 的剩余寿命 ttl 的值,ttl 值越小,越优先淘汰。
  • volatile-random 和 ttl lru 类似,前提条件是设置了过期时间, 是淘汰过期 key 集合中随机的 key。
  • allkeys-lru 区别 volatile-lru 是对全体的key 对象进行淘汰,包含没有设置过期时间的 key.
  • allkeys-random 和allkeys-lru 类似,不过淘汰策略是随机的 key

分布式锁

分布式锁的 本质上是在 Redis 中占一个位置,当别的进程来占用时,发现已经被占用,只能放弃或者稍后重试。

redis 占用操作一般使用 setnx (set if not exists)指令占用锁,然后使用 del 指令释放锁,但是可能会有问题。

172.31.1.135:7001> setnx lock:test true 
(integer) 1
172.31.1.135:7001> get lock:test
"true"
172.31.1.135:7001> 

但是这样存在温柔 setnx 之后,用户线程突然宕机了怎么办,永远无法解锁,这样就存在问题了。

下面给个正确使用实例:

    /**
     * 尝试获取分布式锁
     * @param jedis Redis客户端
     * @param lockKey 锁
     * @param requestId 请求标识
     * @param expireTime 超期时间
     * @return 是否获取成功
     */
    public static boolean tryGetDistributedLock(Jedis jedis, String lockKey, String requestId, int expireTime) {
        String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
        if (LOCK_SUCCESS.equals(result)) {
            return true;
        }
        return false;
    }

    /**
     * 释放分布式锁
     * @param jedis Redis客户端
     * @param lockKey 锁
     * @param requestId 请求标识
     * @return 是否释放成功
     */
    public static boolean releaseDistributedLock(Jedis jedis, String lockKey, String requestId) {
        String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
        Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));
        if (RELEASE_SUCCESS.equals(result)) {
            return true;
        }
        return false;
    }

欢迎关注:

本文分享自微信公众号 - 程序员开发者社区(gh_016ffe40d550),作者:猿星人

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-07-04

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Java 生成 PDF

    王小明_HIT
  • 一年多的GTD和自我管理之路

    本文是《一年多的GTD和自我管理之路(上)》的下篇。上篇分享了对GTD流程的一些理解和以OmniFocus为核心的自我管理系统。

    王小明_HIT
  • 区块链,比特币初步解析

    区块链, 比特币,这个去年比较火,基本上沾到比特币,必涨,不过最近大起大落,区块链,比特币到底是什么?

    王小明_HIT
  • 直挂云帆济沧海-区块链千日谈之227

    加密货币和区块链行业走过了波澜壮阔的2017,面对注定不再平凡的2018年,又有什么新年气象了呢?作为一种特殊的商品,加密货币的价格由市场和需求决定,发展的前景...

    企鹅号小编
  • silverlight属性改变事件通知

    工作中遇到silverlight本身没有提供的某些属性改变事件,但又需要在属性改变时得到通知,Google搬运stack overflow,原地址

    用户6362579
  • Ceph用户邮件列表Vol45-Issue4

    It is expected that the cluster log will be flooded with messages like: 2016-07-...

    用户2772802
  • Redis 中的事件驱动模型

    Redis 服务器通过 socket 实现与客户端(或其他redis服务器)的交互,文件事件就是服务器对 socket 操作的抽象。 Redis 服务器,通过监...

    用户2060079
  • ASP.NET常用的一些服务器控件

    文本框控件TextBox, TextMode:值SingleLine表示单行文本,MultiLine表示多行文本,等等。 ? textbox.jpg ...

    东风冷雪
  • Linux 6种日志查看方法,不会看日志会被鄙视的

    Linux查看日志的命令有多种: tail、cat、tac、head、echo等,本文只介绍几种常用的方法。

    程序员内点事
  • 技术选型系列 - Tair&Redis对比

    高广超

扫码关注云+社区

领取腾讯云代金券