*Redis SPOP 命令 移除并返回集合中的一个或多个随机成员
*语法
SPOP key [count]
*说明
随机移除(pop)并返回存储在 key 的 Set 集合中的指定数量成员。
如果未指定 count,则默认移除并返回 1 个 随机成员。
如果指定了 count:
- 当
count为正数时,返回最多count个随机成员,且不会重复(因为 Set 成员不重复)。 - 如果
count大于集合的基数(cardinality),则返回整个集合并清空它。 - 如果
count为负数,Redis 某些旧版本行为未定义;现代版本通常按绝对值处理或返回错误,建议始终使用正数count。
重要提示:
- SPOP 返回的成员是随机的(random),不保证任何特定顺序。
- SPOP 是原子操作,适合实现"抽奖池"、"任务分配池"等场景。
- 当不指定 count 时,返回的是字符串(scalar);指定 count 时返回的是数组(array)。
*返回值
- Bulk String — 不指定
count时:被移除的单个成员。如果集合为空或key不存在,返回nil。 - Array — 指定
count时:被移除的成员列表。如果集合为空或key不存在,返回空数组。
*时间复杂度
- O(N),其中
N是返回的成员数量。底层需要从 Set 中随机挑选并移除N个成员。
*版本兼容性
| Redis 版本 | 变更说明 |
|---|---|
| >= 1.0.0 | 初始支持,仅单成员移除 |
| >= 3.2.0 | 支持可选的 count 参数 |
*示例
*示例 1:移除单个随机成员
SADD myset "one" "two" "three" "four" "five"
# 返回:(integer) 5
# 随机移除一个成员
SPOP myset
# 返回:"three"(随机)
# 集合剩余成员
SCARD myset
# 返回:(integer) 4
*示例 2:移除多个随机成员
SADD lottery "prize_a" "prize_b" "prize_c" "prize_d" "prize_e"
# 返回:(integer) 5
# 随机抽出 2 个奖项
SPOP lottery 2
# 返回:1) "prize_b" 2) "prize_d"(顺序随机)
# 剩余奖项
SCARD lottery
# 返回:(integer) 3
*示例 3:从空集合或不存在的 key 中弹出
# key 不存在
SPOP empty_set
# 返回:(nil)
SPOP empty_set 3
# 返回:(empty array)
# 创建后清空
SADD temp "x"
# 返回:(integer) 1
SPOP temp
# 返回:"x"
SPOP temp
# 返回:(nil)
*示例 4:抽奖场景——随机抽出获奖者
# 所有参与抽奖的用户
SADD raffle_participants "alice" "bob" "charlie" "dave" "eve" "frank"
# 返回:(integer) 6
# 抽出 3 名获奖者(从参与者池中移除)
SPOP raffle_participants 3
# 返回:3 个随机用户名(顺序随机)
# 未中奖的用户仍然留在集合中
SCARD raffle_participants
# 返回:(integer) 3
*相关命令
- SRANDMEMBER — 随机返回成员(不移除)
- SMOVE — 将成员移动到另一个集合
- SREM — 指定移除成员