You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否用纯Bash与redis-cli实现Redis作业队列?

纯Bash+Redis-cli实现作业队列的方案

1. 是否可以用纯Bash脚本+redis-cli实现?

完全可以。Redis-cli支持非交互模式直接执行命令,Bash脚本可以轻松调用redis-cli、处理命令输出、实现循环逻辑,你的需求(预定义作业列表、多节点取任务、存储处理结果)逻辑简单,不需要依赖其他编程语言,纯Bash+redis-cli完全能满足。

2. 多节点并发如何避免重复读取作业ID?

核心是利用Redis的原子命令——Redis是单线程执行命令的,这些命令的执行过程不会被打断,天然保证并发安全。推荐使用以下方案:

关键命令选择

  • RPOP job_queue:原子性地移除并返回列表job_queue的最后一个元素。如果队列已空,返回(nil)。
  • 或者LPOP job_queue:逻辑和RPOP一致,只是操作列表的头部元素,根据你的队列顺序需求选择即可。
  • 若需要让工作节点在队列空时阻塞等待(比如后续可能新增任务),可以用BRPOP job_queue 0(0表示永久阻塞,直到有元素),但你的场景是预定义作业列表,用RPOP/LPOP循环即可。

并发安全原理

多个工作节点同时调用RPOP时,Redis会依次处理每个命令,每个命令都会原子性地取出一个唯一的作业ID,不会出现同一ID被多个节点读取的情况,完全满足你的并发需求。

示例脚本

1. 初始化作业队列脚本(push_jobs.sh)

#!/bin/bash
# 预定义的作业ID列表
JOB_IDS=(1001 1002 1003 1004 1005)

# 将所有作业ID推入Redis列表(左侧推入,右侧弹出)
for id in "${JOB_IDS[@]}"; do
    redis-cli LPUSH job_queue "$id"
done

echo "所有作业ID已推入队列"

2. 工作节点脚本(worker.sh)

#!/bin/bash
REDIS_QUEUE="job_queue"
REDIS_RESULT_KEY="job_results"

while true; do
    # 原子性弹出作业ID
    JOB_ID=$(redis-cli RPOP "$REDIS_QUEUE")
    
    # 判断队列是否为空,为空则退出循环
    if [ -z "$JOB_ID" ] || [ "$JOB_ID" = "(nil)" ]; then
        echo "队列已空,工作节点退出"
        break
    fi

    echo "开始处理作业ID: $JOB_ID"
    # 替换为你的实际作业处理逻辑
    sleep 3  # 模拟处理耗时

    # 构造处理结果(JSON格式)
    RESULT='{"status": "completed", "job_id": '"$JOB_ID"', "message": "处理成功"}'
    # 将结果存入Redis哈希结构,用作业ID作为字段名
    redis-cli HSET "$REDIS_RESULT_KEY" "$JOB_ID" "$RESULT"

    echo "作业ID: $JOB_ID 处理完成,结果已保存"
done

使用方式

  1. 先执行初始化脚本:chmod +x push_jobs.sh && ./push_jobs.sh
  2. 启动多个工作节点:chmod +x worker.sh && ./worker.sh & ./worker.sh &(可启动任意多个)

多个工作节点会自动从队列中取不同的作业ID处理,不会重复;处理完成的结果会存在Redis的job_results哈希中,你可以用redis-cli HGETALL job_results查看所有结果。

内容的提问来源于stack exchange,提问作者thor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 18:40:25