广东顺德网站建设instagram wordpress
目录
Redis 缓存 (Caching)
目的
核心逻辑
存储形式总结
典型场景
Redis 分布式锁 (Distributed Lock)
目的
核心作用
核心逻辑
典型场景
核心区别总结
Redis 缓存 (Caching)
在Redis中,数据是以键值对的形式存储的,其中键总是字符串类型,而值可以是多种数据类型。
目的
加速数据访问,减少对慢速数据源(如数据库)的频繁查询,提升系统性能和吞吐量。
核心逻辑
-  
读操作:
-  
应用优先从 Redis 读取数据。
 -  
若 Redis 中无数据(缓存未命中),则查询数据库,并将结果写入 Redis。
 
 -  
 -  
写操作:
-  
更新数据库后,同步或异步更新/失效 Redis 中的缓存(如
DEL key或SET key new_value)。 
 -  
 
存储形式总结
| 数据类型 | 底层实现 | 最大元素数 | 特点 | 
|---|---|---|---|
| String | SDS 动态字符串 | 512 MB | 支持文本/二进制数据 | 
| Hash |  
  | 2³²-1 个字段 | 高效存储对象属性 | 
| List | 双向链表/ziplist | 2³²-1 个元素 | 保持插入顺序 | 
| Set | 哈希表或 intset | 2³²-1 个元素 | 自动去重 | 
| Sorted Set | 跳表 + 哈希表 | 2³²-1 个元素 | 按分数排序 | 
| Geospatial | Sorted Set | 同 Sorted Set | 支持地理坐标计算 | 
| Stream | rax 树 | 理论无上限 | 支持消费者组 | 
| Bitmap | String | 2³² 位 | 超高效布尔存储 | 
| 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/EXPIRE | SET NX PX/EVAL(Lua 解锁) | 
| 数据一致性 | 需处理缓存与数据库一致性(如双写策略) | 需确保锁的互斥性和安全性(如 Redlock) | 
-  
锁是协调机制,不存储业务数据;缓存是数据副本,两者不可互换。
 -  
缓存仅加速数据读取,无法控制并发写操作(如超卖问题仍需分布式锁或数据库事务)。
 
实际系统中二者常结合使用:
-  
读场景:用 Redis 缓存加速数据访问。
 -  
写场景:用 Redis 分布式锁保护共享资源,确保数据一致性。
 
| 适用场景 | 不适用场景 | 
|---|---|
| 库存扣减/秒杀系统 | 高频短操作(锁开销 > 业务开销) | 
| 分布式任务调度 | 强一致性要求极高的金融交易 | 
| 防止重复提交 | 单机应用(用 Monitor 即可) | 
| 跨服务共享资源协调 | 读多写少场景(用乐观锁更优) | 
