目录
一、本地锁的问题" >一、本地锁的问题
二、什么是分布式锁" >二、什么是分布式锁
三、Redis 的 SETNX" >三、Redis 的 SETNX
四、青铜方案" >四、青铜方案
3.1 青铜原理" >3.1 青铜原理
3.2 青铜方案的缺陷" >3.2 青铜方案的缺陷
四、白银方案" >四、白银方案
6.1 生活中的例子" >6.1 生活中的例子
那如何规避这个风险呢?" >那如何规避这个风险呢?
四、白银方案🎜" >四、白银方案🎜
5.3 示例代码" >5.3 示例代码
4.4 白银方案的缺陷" >4.4 白银方案的缺陷
五、黄金方案" >五、黄金方案
5.1 原子指令" >5.1 原子指令
7.1 技术原理图" >7.1 技术原理图
5.4 黄金方案的缺陷" >5.4 黄金方案的缺陷
5.4.1 用户 A 抢占锁
5.4.2 用户 B 抢占锁
六、铂金方案" >六、铂金方案
7.2 代码示例" >7.2 代码示例
6.4 铂金方案的缺陷" >6.4 铂金方案的缺陷
七、钻石方案" >七、钻石方案
八、总结" >八、总结
首页 Java java教程 Redis 分布式锁|从青铜到钻石的五种演进方案

Redis 分布式锁|从青铜到钻石的五种演进方案

Aug 23, 2023 pm 02:54 PM
redis

本篇主要内容如下:

Redis 分布式锁|从青铜到钻石的五种演进方案

一、本地锁的问题

首先我们来回顾下本地锁的问题:

目前题目微服务被拆分成了四个微服务。前端请求进来时,会被转发到不同的微服务。假如前端接收了 10 W 个请求,每个微服务接收 2.5 W 个请求,假如缓存失效了,每个微服务在访问数据库时加锁,通过锁(synchronziedlock)来锁住自己的线程资源,从而防止缓存击穿synchronziedlock)来锁住自己的线程资源,从而防止缓存击穿

这是一种本地加锁的方式,在分布式这是一种本地加锁的方式,在分布式情况下会带来数据不一致的问题:比如服务 A 获取数据后,更新缓存 key =100,服务 B 不受服务 A 的锁限制,并发去更新缓存 key = 99,最后的结果可能是 99 或 100,但这是一种未知的状态,与期望结果不一致

。流程图如下所示:🎜
Redis 分布式锁|从青铜到钻石的五种演进方案

二、什么是分布式锁

基于上面本地锁的问题,我们需要一种支持分布式集群环境下的锁:查询 DB 时,只有一个线程能访问,其他线程都需要等待第一个线程释放锁资源后,才能继续执行。

生活中的案例:可以把锁看成房门外的一把,所有并发线程比作,他们都想进入房间,房间内只能有一个人进入。当有人进入后,将门反锁,其他人必须等待,直到进去的人出来。

Redis 分布式锁|从青铜到钻石的五种演进方案

我们来看下分布式锁的基本原理,如下图所示:

Redis 分布式锁|从青铜到钻石的五种演进方案

我们来分析下上图的分布式锁:

  • 1.前端将 10W 的高并发请求转发给四个题目微服务。
  • 2.每个微服务处理 2.5 W 个请求。
  • 3.每个处理请求的线程在执行业务之前,需要先抢占锁。可以理解为“占坑”。
  • 4.获取到锁的线程在执行完业务后,释放锁。可以理解为“释放坑位”。
  • 5.未获取到的线程需要等待锁释放。
  • 6.释放锁后,其他线程抢占锁。
  • 7.重复执行步骤 4、5、6。

大白话解释:所有请求的线程都去同一个地方“占坑”,如果有坑位,就执行业务逻辑,没有坑位,就需要其他线程释放“坑位”。这个坑位是所有线程可见的,可以把这个坑位放到 Redis 缓存或者数据库,这篇讲的就是如何用 Redis 做“分布式坑位”“占坑”,如果有坑位,就执行业务逻辑,没有坑位,就需要其他线程释放“坑位”。这个坑位是所有线程可见的,可以把这个坑位放到 Redis 缓存或者数据库,这篇讲的就是如何用 Redis 做“分布式坑位”

三、Redis 的 SETNX

Redis 作为一个公共可访问的地方,正好可以作为“占坑”的地方。

用 Redis 实现分布式锁的几种方案,我们都是用 SETNX 命令(设置 key 等于某 value)。只是高阶方案传的参数个数不一样,以及考虑了异常情况。

我们来看下这个命令,SETNXset If not exist的简写。意思就是当 key 不存在时,设置 key 的值,存在时,什么都不做。

在 Redis 命令行中是这样执行的:

set <key> <value> NX
登录后复制

我们可以进到 redis 容器中来试下 SETNX

三、Redis 的 SETNX

Redis 作为一个公共可访问的地方,正好可以作为“占坑”的地方。

用 Redis 实现分布式锁的几种方案,我们都是用 SETNX 命令(设置 key 等于某 value)。只是高阶方案传的参数个数不一样,以及考虑了异常情况。🎜🎜我们来看下这个命令,SETNXset If not exist的简写。意思就是当 key 不存在时,设置 key 的值,存在时,什么都不做。🎜🎜在 Redis 命令行中是这样执行的:🎜
docker exec -it <容器 id> redis-cli
登录后复制
登录后复制
🎜我们可以进到 redis 容器中来试下 SETNX 命令。🎜🎜先进入容器:🎜
docker exec -it <容器 id> redis-cli
登录后复制
登录后复制

然后执行 SETNX 命令:将 wukong 这个 key 对应的 value 设置成 1111

set wukong 1111 NX
登录后复制

返回 OK,表示设置成功。重复执行该命令,返回 nil表示设置失败。

Redis 分布式锁|从青铜到钻石的五种演进方案

四、青铜方案

我们先用 Redis 的 SETNX 命令来实现最简单的分布式锁。

3.1 青铜原理

我们来看下流程图:

Redis 分布式锁|从青铜到钻石的五种演进方案
  • 多个并发线程都去 Redis 中申请锁,也就是执行 setnx 命令,假设线程 A 执行成功,说明当前线程 A 获得了。
  • 其他线程执行 setnx 命令都会是失败的,所以需要等待线程 A 释放锁。
  • 线程 A 执行完自己的业务后,删除锁。
  • 其他线程继续抢占锁,也就是执行 setnx 命令。因为线程 A 已经删除了锁,所以又有其他线程可以抢占到锁了。

代码示例如下,Java 中 setnx 命令对应的代码为 setIfAbsent

setIfAbsent 方法的第一个参数代表 key,第二个参数代表值。

// 1.先抢占锁
Boolean lock = redisTemplate.opsForValue().setIfAbsent("lock", "123");
if(lock) {
  // 2.抢占成功,执行业务
  List<TypeEntity> typeEntityListFromDb = getDataFromDB();
  // 3.解锁
  redisTemplate.delete("lock");
  return typeEntityListFromDb;
} else {
  // 4.休眠一段时间
  sleep(100);
  // 5.抢占失败,等待锁释放
  return getTypeEntityListByRedisDistributedLock();
}
登录后复制

一个小问题:那为什么需要休眠一段时间?

因为该程序存在递归调用,可能会导致栈空间溢出。

3.2 青铜方案的缺陷

青铜之所以叫青铜,是因为它是最初级的,肯定会带来很多问题。

设想一种家庭场景:晚上小空一个人开锁进入了房间,打开了电灯?,然后突然断电了,小空想开门出去,但是找不到门锁位置,那小明就进不去了,外面的人也进不来。断电了,小空想开门出去,但是找不到门锁位置,那小明就进不去了,外面的人也进不来。

Redis 分布式锁|从青铜到钻石的五种演进方案

从技术的角度看:setnx 占锁成功,业务代码出现异常或者服务器宕机,没有执行删除锁的逻辑,就造成了死锁

那如何规避这个风险呢?

设置锁的自动过期时间,过一段时间后,自动删除锁,这样其他线程就能获取到锁了。

四、白银方案

4.1 生活中的例子

上面提到的青铜方案会有死锁问题,那我们就用上面的规避风险的方案来设计下,也就是我们的白银方案。

Redis 分布式锁|从青铜到钻石的五种演进方案

还是生活中的例子:小空开锁成功后,给这款智能锁设置了一个沙漏倒计时⏳

Redis 分布式锁|从青铜到钻石的五种演进方案

从技术的角度看:setnx 占锁成功,业务代码出现异常或者服务器宕机,没有执行删除锁的逻辑,就造成了死锁

那如何规避这个风险呢?

设置锁的自动过期时间,过一段时间后,自动删除锁,这样其他线程就能获取到锁了。🎜

四、白银方案🎜

🎜🎜4.1 生活中的例子🎜🎜🎜上面提到的青铜方案会有死锁问题,那我们就用上面的规避风险的方案来设计下,也就是我们的白银方案。🎜
Redis 分布式锁|从青铜到钻石的五种演进方案
🎜还是生活中的例子:小空开锁成功后,给这款智能锁设置了一个沙漏倒计时⏳,沙漏完后,门锁自动打开。即使房间突然断电,过一段时间后,锁会自动打开,其他人就可以进来了。🎜🎜🎜4.2 技术原理图🎜🎜🎜和青铜方案不同的地方在于,在占锁成功后,设置锁的过期时间,这两步是分步执行的。如下图所示:🎜
Redis 分布式锁|从青铜到钻石的五种演进方案

4.3 示例代码

清理 redis key 的代码如下

// 在 10s 以后,自动清理 lock
redisTemplate.expire("lock", 10, TimeUnit.SECONDS);
登录后复制

完整代码如下:

// 1.先抢占锁
Boolean lock = redisTemplate.opsForValue().setIfAbsent("lock", "123");
if(lock) {
    // 2.在 10s 以后,自动清理 lock
    redisTemplate.expire("lock", 10, TimeUnit.SECONDS);
    // 3.抢占成功,执行业务
    List<TypeEntity> typeEntityListFromDb = getDataFromDB();
    // 4.解锁
    redisTemplate.delete("lock");
    return typeEntityListFromDb;
}
登录后复制

4.4 白银方案的缺陷

白银方案看似解决了线程异常或服务器宕机造成的锁未释放的问题,但还是存在其他问题:

因为占锁和设置过期时间是分两步执行的,所以如果在这两步之间发生了异常,则锁的过期时间根本就没有设置成功。

所以和青铜方案有一样的问题:锁永远不能过期

五、黄金方案

5.1 原子指令

上面的白银方案中,占锁和设置锁过期时间是分步两步执行的,这个时候,我们可以联想到什么:事务的原子性(Atom)。

原子性:多条命令要么都成功执行,要么都不执行。

将两步放在一步中执行:占锁+设置锁过期时间。

Redis 正好支持这种操作:

# 设置某个 key 的值并设置多少毫秒或秒 过期。
set <key> <value> PX <多少毫秒> NX
或
set <key> <value> EX <多少秒> NX
登录后复制

然后可以通过如下命令查看 key 的变化

ttl <key>
登录后复制

下面演示下如何设置 key 并设置过期时间。注意:执行命令之前需要先删除 key,可以通过客户端或命令删除。

# 设置 key=wukong,value=1111,过期时间=5000ms
set wukong 1111 PX 5000 NX
# 查看 key 的状态
ttl wukong
登录后复制

执行结果如下图所示:每运行一次 ttl 命令,就可以看到 wukong 的过期时间就会减少。最后会变为 -2(已过期)。

Redis 分布式锁|从青铜到钻石的五种演进方案

5.2 技术原理图

黄金方案和白银方案的不同之处:获取锁的时候,也需要设置锁的过期时间,这是一个原子操作,要么都成功执行,要么都不执行。如下图所示:

Redis 分布式锁|从青铜到钻石的五种演进方案

5.3 示例代码

设置 lock 的值等于 123,过期时间为 10 秒。如果 10 秒 以后,lock 还存在,则清理 lock。

setIfAbsent("lock", "123", 10, TimeUnit.SECONDS);
登录后复制

5.4 黄金方案的缺陷

我们还是举生活中的例子来看下黄金方案的缺陷。

5.4.1 用户 A 抢占锁

Redis 分布式锁|从青铜到钻石的五种演进方案
  • 用户 A 先抢占到了锁,并设置了这个锁 10 秒以后自动开锁,锁的编号为 123123
  • 10 秒以后,A 还在执行任务,此时锁被自动打开了。

5.4.2 用户 B 抢占锁

Redis 分布式锁|从青铜到钻石的五种演进方案
  • 用户 B 看到房间的锁打开了,于是抢占到了锁,设置锁的编号为 123,并设置了过期时间 10 秒
  • 因房间内只允许一个用户执行任务,所以用户 A 和 用户 B 执行任务产生了冲突
  • 用户 A 在 15 s 后,完成了任务,此时 用户 B 还在执行任务。
  • 用户 A 主动打开了编号为 123
  • 10 秒以后,A 还在执行任务,此时锁被自动打开了。
  • 5.4.2 用户 B 抢占锁
    Redis 分布式锁|从青铜到钻石的五种演进方案
用户 B 看到房间的锁打开了,于是抢占到了锁,设置锁的编号为 123,并设置了过期时间 10 秒

Redis 分布式锁|从青铜到钻石的五种演进方案因房间内只允许一个用户执行任务,所以用户 A 和 用户 B 执行任务产生了冲突
  • 用户 A 在 15 s 后,完成了任务,此时 用户 B 还在执行任务。🎜🎜🎜🎜用户 A 主动打开了编号为 123的锁。🎜🎜🎜🎜用户 B 还在执行任务,发现锁已经被打开了。🎜🎜🎜🎜用户 B 非常生气:🎜我还没执行完任务呢,锁怎么开了?🎜🎜🎜🎜🎜5.4.3 用户 C 抢占锁🎜🎜🎜🎜🎜🎜🎜用户 B 的锁被 A 主动打开后,A 离开房间,B 还在执行任务。
  • 用户 C 抢占到锁,C 开始执行任务。
  • 因房间内只允许一个用户执行任务,所以用户 B 和 用户 C 执行任务产生了冲突。

从上面的案例中我们可以知道,因为用户 A 处理任务所需要的时间大于锁自动清理(开锁)的时间,所以在自动开锁后,又有其他用户抢占到了锁。当用户 A 完成任务后,会把其他用户抢占到的锁给主动打开。

这里为什么会打开别人的锁?因为锁的编号都叫做 “123”,用户 A 只认锁编号,看见编号为 “123”的锁就开,结果把用户 B 的锁打开了,此时用户 B 还未执行完任务,当然生气了。

六、铂金方案

6.1 生活中的例子

上面的黄金方案的缺陷也很好解决,给每个锁设置不同的编号不就好了~

如下图所示,B 抢占的锁是蓝色的,和 A 抢占到绿色锁不一样。这样就不会被 A 打开了。

做了个动图,方便理解:

Redis 分布式锁|从青铜到钻石的五种演进方案
动图演示

静态图更高清,可以看看:

Redis 分布式锁|从青铜到钻石的五种演进方案

6.2 技术原理图

与黄金方案的不同之处:

  • 设置锁的过期时间时,还需要设置唯一编号。
  • 主动删除锁的时候,需要判断锁的编号是否和设置的一致,如果一致,则认为是自己设置的锁,可以进行主动删除。
Redis 分布式锁|从青铜到钻石的五种演进方案

6.3 代码示例

// 1.生成唯一 id
String uuid = UUID.randomUUID().toString();
// 2. 抢占锁
Boolean lock = redisTemplate.opsForValue().setIfAbsent("lock", uuid, 10, TimeUnit.SECONDS);
if(lock) {
    System.out.println("抢占成功:" + uuid);
    // 3.抢占成功,执行业务
    List<TypeEntity> typeEntityListFromDb = getDataFromDB();
    // 4.获取当前锁的值
    String lockValue = redisTemplate.opsForValue().get("lock");
    // 5.如果锁的值和设置的值相等,则清理自己的锁
    if(uuid.equals(lockValue)) {
        System.out.println("清理锁:" + lockValue);
        redisTemplate.delete("lock");
    }
    return typeEntityListFromDb;
} else {
    System.out.println("抢占失败,等待锁释放");
    // 4.休眠一段时间
    sleep(100);
    // 5.抢占失败,等待锁释放
    return getTypeEntityListByRedisDistributedLock();
}
登录后复制
  • 1.生成随机唯一 id,给锁加上唯一值。
  • 2.抢占锁,并设置过期时间为 10 s,且锁具有随机唯一 id。
  • 3.抢占成功,执行业务。
  • 4.执行完业务后,获取当前锁的值。
  • 5.如果锁的值和设置的值相等,则清理自己的锁。

6.4 铂金方案的缺陷

上面的方案看似很完美,但还是存在问题:第 4 步和第 5 步并不是原子性的。

Redis 分布式锁|从青铜到钻石的五种演进方案
  • 时刻:0s。线程 A 抢占到了锁。

  • 时刻:9.5s。线程 A 向 Redis 查询当前 key 的值。

  • 时刻:10s。锁自动过期。

  • 时刻:11s。线程 B 抢占到锁。

  • 时刻:12s。线程 A 在查询途中耗时长,终于拿多锁的值。

  • 时刻:13s。线程 A 还是拿自己设置的锁的值和返回的值进行比较,值是相等的,清理锁,但是这个锁其实是线程 B 抢占的锁。

那如何规避这个风险呢?钻石方案登场。

七、钻石方案

上面的线程 A 查询锁和删除锁的逻辑不是原子性的,所以将查询锁和删除锁这两步作为原子指令操作就可以了。

7.1 技术原理图

如下图所示,红色圈出来的部分是钻石方案的不同之处。用脚本进行删除,达到原子操作。

Redis 分布式锁|从青铜到钻石的五种演进方案

7.2 代码示例

那如何用脚本进行删除呢?

我们先来看一下这段 Redis 专属脚本:

if redis.call("get",KEYS[1]) == ARGV[1]
then
    return redis.call("del",KEYS[1])
else
    return 0
end
登录后复制

这段脚本和铂金方案的获取key,删除key的方式很像。先获取 KEYS[1] 的 value,判断 KEYS[1] 的 value 是否和 ARGV[1] 的值相等,如果相等,则删除 KEYS[1]。

那么这段脚本怎么在 Java 项目中执行呢?

分两步:先定义脚本;用 redisTemplate.execute 方法执行脚本。

// 脚本解锁
String script = "if redis.call(&#39;get&#39;,KEYS[1]) == ARGV[1] then return redis.call(&#39;del&#39;,KEYS[1]) else return 0 end";
redisTemplate.execute(new DefaultRedisScript<Long>(script, Long.class), Arrays.asList("lock"), uuid);
登录后复制

上面的代码中,KEYS[1] 对应“lock”,ARGV[1] 对应 “uuid”,含义就是如果 lock 的 value 等于 uuid 则删除 lock。

而这段 Redis 脚本是由 Redis 内嵌的 Lua 环境执行的,所以又称作 Lua 脚本。

那钻石方案是不是就完美了呢?有没有更好的方案呢?

下篇,我们再来介绍另外一种分布式锁的王者方案:Redisson。

八、总结

本篇通过本地锁的问题引申出分布式锁的问题。然后介绍了五种分布式锁的方案,由浅入深讲解了不同方案的改进之处。

从上面几种方案的不断演进的过程中,知道了系统中哪些地方可能存在异常情况,以及该如何更好地进行处理。

举一反三,这种不断演进的思维模式也可以运用到其他技术中。

下面总结下上面五种方案的缺陷和改进之处。

青铜方案

  • 缺陷:业务代码出现异常或者服务器宕机,没有执行主动删除锁的逻辑,就造成了死锁。
  • 改进:设置锁的自动过期时间,过一段时间后,自动删除锁,这样其他线程就能获取到锁了。

白银方案

  • 缺陷:占锁和设置锁过期时间是分步两步执行的,不是原子操作。
  • 改进:占锁和设置锁过期时间保证原子操作。

黄金方案

  • 缺陷:主动删除锁时,因锁的值都是相同的,将其他客户端占用的锁删除了。
  • 改进:每次占用的锁,随机设为较大的值,主动删除锁时,比较锁的值和自己设置的值是否相等。

铂金方案

  • 缺陷:获取锁、比较锁的值、删除锁,这三步是非原子性的。中途又可能锁自动过期了,又被其他客户端抢占了锁,导致删锁时把其他客户端占用的锁删了。
  • 改进:使用 Lua 脚本进行获取锁、比较锁、删除锁的原子操作。

钻石方案

  • 缺陷:非专业的分布式锁方案。
  • 改进:Redission 分布式锁。

王者方案,下篇见~

以上是Redis 分布式锁|从青铜到钻石的五种演进方案的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它们
4 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

redis集群模式怎么搭建 redis集群模式怎么搭建 Apr 10, 2025 pm 10:15 PM

Redis集群模式通过分片将Redis实例部署到多个服务器,提高可扩展性和可用性。搭建步骤如下:创建奇数个Redis实例,端口不同;创建3个sentinel实例,监控Redis实例并进行故障转移;配置sentinel配置文件,添加监控Redis实例信息和故障转移设置;配置Redis实例配置文件,启用集群模式并指定集群信息文件路径;创建nodes.conf文件,包含各Redis实例的信息;启动集群,执行create命令创建集群并指定副本数量;登录集群执行CLUSTER INFO命令验证集群状态;使

redis指令怎么用 redis指令怎么用 Apr 10, 2025 pm 08:45 PM

使用 Redis 指令需要以下步骤:打开 Redis 客户端。输入指令(动词 键 值)。提供所需参数(因指令而异)。按 Enter 执行指令。Redis 返回响应,指示操作结果(通常为 OK 或 -ERR)。

redis怎么读源码 redis怎么读源码 Apr 10, 2025 pm 08:27 PM

理解 Redis 源码的最佳方法是逐步进行:熟悉 Redis 基础知识。选择一个特定的模块或功能作为起点。从模块或功能的入口点开始,逐行查看代码。通过函数调用链查看代码。熟悉 Redis 使用的底层数据结构。识别 Redis 使用的算法。

redis数据怎么清空 redis数据怎么清空 Apr 10, 2025 pm 10:06 PM

如何清空 Redis 数据:使用 FLUSHALL 命令清除所有键值。使用 FLUSHDB 命令清除当前选定数据库的键值。使用 SELECT 切换数据库,再使用 FLUSHDB 清除多个数据库。使用 DEL 命令删除特定键。使用 redis-cli 工具清空数据。

redis怎么使用单线程 redis怎么使用单线程 Apr 10, 2025 pm 07:12 PM

Redis 使用单线程架构,以提供高性能、简单性和一致性。它利用 I/O 多路复用、事件循环、非阻塞 I/O 和共享内存来提高并发性,但同时存在并发性受限、单点故障和不适合写密集型工作负载的局限性。

redis怎么查看所有的key redis怎么查看所有的key Apr 10, 2025 pm 07:15 PM

要查看 Redis 中的所有键,共有三种方法:使用 KEYS 命令返回所有匹配指定模式的键;使用 SCAN 命令迭代键并返回一组键;使用 INFO 命令获取键的总数。

redis怎么读取队列 redis怎么读取队列 Apr 10, 2025 pm 10:12 PM

要从 Redis 读取队列,需要获取队列名称、使用 LPOP 命令读取元素,并处理空队列。具体步骤如下:获取队列名称:以 "queue:" 前缀命名,如 "queue:my-queue"。使用 LPOP 命令:从队列头部弹出元素并返回其值,如 LPOP queue:my-queue。处理空队列:如果队列为空,LPOP 返回 nil,可先检查队列是否存在再读取元素。

redis怎么启动服务器 redis怎么启动服务器 Apr 10, 2025 pm 08:12 PM

启动 Redis 服务器的步骤包括:根据操作系统安装 Redis。通过 redis-server(Linux/macOS)或 redis-server.exe(Windows)启动 Redis 服务。使用 redis-cli ping(Linux/macOS)或 redis-cli.exe ping(Windows)命令检查服务状态。使用 Redis 客户端,如 redis-cli、Python 或 Node.js,访问服务器。

See all articles