Redis缓存和Redis分布式锁使用及说明

 更新时间:2026年05月25日 10:52:59   作者:陈同学呀  
这段描述融合了Redis缓存和Redis分布式锁两个核心关键词,详细介绍了它们在系统中的应用场景、核心逻辑及典型场景,特别强调了两者在数据一致性和生命周期上的区别,适合需要优化系统性能和解决分布式系统布冲突的读者

Redis 缓存 (Caching)

在Redis中,数据是以键值对的形式存储的,其中键总是字符串类型,而值可以是多种数据类型。

目的

加速数据访问,减少对慢速数据源(如数据库)的频繁查询,提升系统性能和吞吐量。

核心逻辑

读操作

  • 应用优先从 Redis 读取数据。

  • 若 Redis 中无数据(缓存未命中),则查询数据库,并将结果写入 Redis。

写操作

  • 更新数据库后,同步或异步更新/失效 Redis 中的缓存(如 DEL key 或 SET key new_value)。

存储形式总结

数据类型底层实现最大元素数特点
StringSDS 动态字符串512 MB支持文本/二进制数据
Hash
  • 哈希表或 ziplist
2³²-1 个字段高效存储对象属性
List双向链表/ziplist2³²-1 个元素保持插入顺序
Set哈希表或 intset2³²-1 个元素自动去重
Sorted Set跳表 + 哈希表2³²-1 个元素按分数排序
GeospatialSorted Set同 Sorted Set支持地理坐标计算
Streamrax 树理论无上限支持消费者组
BitmapString2³² 位超高效布尔存储
HyperLogLog专用结构理论无上限固定12KB内存存储巨大基数
// 设置过期时间
db.KeyExpire("temp_data", TimeSpan.FromMinutes(30));

// 滑动过期
db.StringSet("session:1001", data, TimeSpan.FromMinutes(20), when: When.Always);

典型场景

  • 高频读取的热点数据(如商品信息、用户资料)
  • 减轻数据库压力
  • 加速 API 响应

Redis 分布式锁 (Distributed Lock)

目的

协调分布式系统中多个进程/服务的并发操作,确保同一时刻只有一个客户端能执行关键逻辑(如资源修改),避免数据竞争。

核心作用

Redis 分布式锁用于解决分布式系统中的并发冲突问题,主要作用包括:

资源互斥访问

确保多个服务实例/进程同时操作共享资源(如数据库、文件)时,同一时刻只有一个客户端能执行关键代码。

例:避免库存超卖、重复支付、文件覆盖等问题。

协调分布式任务

保证定时任务、批处理操作在集群环境中只被执行一次。

防止并发副作用

避免多个请求同时修改同一数据导致状态不一致

核心逻辑

加锁

  • 客户端尝试在 Redis 中创建一个唯一键(如 lock:order_123),通过原子操作(如 SET key random_value NX PX 30000)确保互斥性。

执行业务逻辑

  • 只有成功获得锁的客户端才能执行后续操作(如扣减库存)。

解锁

  • 完成后删除该键(需通过 Lua 脚本验证值,避免误删其他客户端的锁)。

典型场景

  • 分布式系统下的资源互斥访问(如订单支付、库存扣减)

  • 防止重复任务调度(如定时任务只在一个节点执行)

// 示例:使用 Redlock 或 StackExchange.Redis 锁
var redisLock = _redis.AcquireLock("lock:order_123", TimeSpan.FromSeconds(30));
try
{
    if (redisLock.IsAcquired)
    {
        // 执行业务逻辑(如扣减库存)
        _stockService.ReduceStock(productId, 1);
    }
}
finally
{
    redisLock?.Release(); // 释放锁
}

类库中用到的包是RedLockNet:

//锁信息集合
var trayBarcodeLockInfos = new List<IRedLock>(); 
try
 {
   //获取锁
     var lockInfo = await _redLockLead.AcquireLockAsync(moveTrayBalance.TrayBarcode);

     _ = !lockInfo.IsAcquired ? throw new BusinessException(message: _localizer["_TrayBarcodeRequestExist", moveTrayBalance.TrayBarcode]) : false;

     trayBarcodeLockInfos.Add(lockInfo); //获取锁成功 将锁加入集合中

  //执行业务逻辑
  ··········

 }
 catch (BusinessException ex)
 {

 } 
finally
 {
    //释放锁
     foreach (var lockInfo in trayBarcodeLockInfos)
     {
         await _redLockLead.ReleaseLockAsync(lockInfo);
     }
 }

AcquireLockAsync() 获取锁 获取不到返回失败 

IsAcquired() 代表是否获取锁成功 

/// <summary>
/// 获取锁(获取不到立即返回失败)
/// </summary>
/// <param name="lockKey"></param>
/// <returns></returns>
public virtual async Task<IRedLock> AcquireLockAsync(string lockKey)
{
    var redLock = await _factoryProvider.RedLockFactoryInstance.CreateLockAsync(lockKey, _defaultKeyExpiry);
    return redLock;
}
/// <summary>
/// 获取锁(阻塞直到获取锁成功或者1h后仍获取不到,返回失败)
/// </summary>
/// <param name="lockKey"></param>
/// <returns></returns>
public virtual async Task<IRedLock> AcquireLockUntilSuccessAsync(string lockKey)
{
    var redLock = await _factoryProvider.RedLockFactoryInstance.CreateLockAsync(lockKey, _defaultKeyExpiry, _wait, _retry);
    return redLock;
}


public async Task<IRedLock> CreateLockAsync(string resource, TimeSpan expiryTime, TimeSpan waitTime, TimeSpan retryTime, CancellationToken? cancellationToken = null)
{
    return await RedLock.CreateAsync(loggerFactory.CreateLogger<RedLock>(), redisCaches, resource, expiryTime, waitTime, retryTime, configuration.RetryConfiguration, cancellationToken ?? CancellationToken.None).ConfigureAwait(continueOnCapturedContext: false);
}

默认为每10秒尝试一次,在尝试了一小时后还获取不到锁的话,就返回失败

/// <summary>
/// 释放锁
/// </summary>
/// <param name="redLock"></param>
/// <returns></returns>
public virtual async Task ReleaseLockAsync(IRedLock redLock)
{
    await redLock.DisposeAsync();
}

核心区别总结

特性Redis 缓存Redis 分布式锁
核心目标提升读取性能,降低数据库压力解决分布式系统并发冲突
数据性质存储业务数据(如用户信息)存储锁状态(临时性、非业务数据)
读写模式高频读、低频写短期占用、立即释放
生命周期可长期存在(有过期时间)临时存在(任务结束即释放)
关键命令GET/SET/DEL/EXPIRESET NX PX/EVAL(Lua 解锁)
数据一致性需处理缓存与数据库一致性(如双写策略)需确保锁的互斥性和安全性(如 Redlock)
  • 锁是协调机制,不存储业务数据;缓存是数据副本,两者不可互换。

  • 缓存仅加速数据读取,无法控制并发写操作(如超卖问题仍需分布式锁或数据库事务)。

实际系统中二者常结合使用

  • 读场景:用 Redis 缓存加速数据访问。

  • 写场景:用 Redis 分布式锁保护共享资源,确保数据一致性。

适用场景不适用场景
库存扣减/秒杀系统高频短操作(锁开销 > 业务开销)
分布式任务调度强一致性要求极高的金融交易
防止重复提交单机应用(用 Monitor 即可)
跨服务共享资源协调读多写少场景(用乐观锁更优)

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • dubbo服务使用redis注册中心的系列异常解决

    dubbo服务使用redis注册中心的系列异常解决

    这篇文章主要为大家介绍了dubbo服务在使用redis注册中心遇到的一系列异常的解决,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
    2022-03-03
  • Redis 的过期策略与键的过期时间设置方法

    Redis 的过期策略与键的过期时间设置方法

    Redis通过惰性删除和定期删除策略管理内存,提供多种命令设置键的过期时间,并通过过期字典高效处理过期键,合理设置过期时间、监控过期键数量和避免大量键同时过期是最佳实践,本文介绍Redis 的过期策略与键的过期时间设置,感兴趣的朋友一起看看吧
    2025-03-03
  • Redisson如何解决Redis分布式锁提前释放问题

    Redisson如何解决Redis分布式锁提前释放问题

    本文主要介绍了Redisson如何解决Redis分布式锁提前释放问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-05-05
  • CentOS系统下Redis安装和自启动配置的步骤

    CentOS系统下Redis安装和自启动配置的步骤

    相信大家都知道Redis是一个C实现的基于内存、可持久化的键值对数据库,在分布式服务中常作为缓存服务。所以这篇文章将详细介绍在CentOS系统下如何从零开始安装到配置启动服务。有需要的可以参考借鉴。
    2016-09-09
  • 大数据量下Redis分片的5种策略分享

    大数据量下Redis分片的5种策略分享

    随着业务规模的增长,单一Redis实例面临着内存容量、网络带宽和计算能力的瓶颈,分片成为扩展Redis的关键策略,它将数据分散到多个Redis节点上,每个节点负责整个数据集的一个子集,本文将分享5种Redis分片策略,需要的朋友可以参考下
    2025-05-05
  • 使用JMeter插件Redis Data Set如何实现高性能数据驱动测试

    使用JMeter插件Redis Data Set如何实现高性能数据驱动测试

    RedisDataSet插件是JMeter的一个插件,可以实现从Redis中动态加载数据,并将其用作测试参数,本文详细介绍如何在JMeter中使用RedisDataSet插件,帮助你实现高效的数据驱动测试
    2025-01-01
  • linux 常见的标识与Redis数据库详解

    linux 常见的标识与Redis数据库详解

    这篇文章主要介绍了linux 常见的标识与Redis数据库,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-10-10
  • Redis缓存雪崩、缓存击穿、缓存穿透详解

    Redis缓存雪崩、缓存击穿、缓存穿透详解

    本文介绍了缓存雪崩、击穿、穿透三种问题:雪崩因大量缓存同时失效导致数据库压力激增,需差异化TTL、多级缓存及熔断机制;击穿由热点key失效引发,可用互斥锁、逻辑过期或预加载;穿透则因非法查询穿透缓存,需布隆过滤器、空对象或参数校验
    2025-07-07
  • caffeine_redis自定义二级缓存

    caffeine_redis自定义二级缓存

    这篇文章详细介绍了caffeine_redis 自定义二级缓存,文中有相关的背景前提与出现的问题,感兴趣的同学可以参考一下
    2023-04-04
  • RedisTemplate常用方法大全(面试必备)

    RedisTemplate常用方法大全(面试必备)

    RedisTemplate是SpringData Redis提供的一个类,本文主要介绍了RedisTemplate常用方法大全,具有一定的参考价值,感兴趣的可以了解一下
    2024-05-05

最新评论