*Redis SPOP 命令 移除并返回集合中的一个或多个随机成员

*语法

SPOP key [count]

*说明

随机移除(pop)并返回存储在 keySet 集合中的指定数量成员。

如果未指定 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 — 指定移除成员