Redis List 无法保证消息不丢,因进程崩溃、断电或主从切换未完成时内存数据会丢失;AOF 默认每秒刷盘最多丢1秒数据,设为always则QPS暴跌70%以上;无ACK机制致RPOP后消费者崩溃消息即消失;BRPOP无超时重试且易假死;不支持消费者组与并行消费,需手动实现进度标记与ACK,高并发下易争抢失败;大Key导致O(N)操作卡主线程,LRANGE 0 -1易触发限流。

Redis List 无法保证消息不丢
当 Redis 进程崩溃、机器断电或主从切换未完成时,LPUSH/RPOP 写入内存但尚未落盘的数据会直接消失。即使开启 AOF,默认配置是每秒刷盘(appendfsync everysec),最多可能丢失 1 秒内所有消息;设为 always 则吞吐暴跌,QPS 可能跌掉 70% 以上。百万级队列要求“零丢失”或“至少一次”,List 原生无 ACK 机制,消费者 RPOP 后崩溃,消息就永远消失了。
阻塞命令 BRPOP 在高并发下容易假死
BRPOP 看似解决了空轮询问题,但它依赖客户端连接长期挂起。当消费者实例多、网络抖动频繁、或 Redis 连接数接近上限时,大量阻塞连接会卡住 Redis 的事件循环,导致新命令响应延迟飙升,甚至触发超时熔断。更关键的是:BRPOP 没有超时重试语义——一旦连接中断,消息就卡在队列里无人拉取,除非你额外实现心跳+重连+偏移恢复逻辑。
List 是单点链表,不支持消费者组与并行消费
百万级吞吐必然需要多个消费者并行处理。但 List 本身不区分谁消费了哪条消息,也没有内置的“已读/未读”状态标记。你得自己用 SET 记消费进度、用 EXPIRE 防滞留、用 WATCH + MULTI 做 ACK,这些操作在高并发下极易引发争抢和失败。而真正的消息队列(如 Kafka)靠分区 + 偏移量 + 提交机制天然支持横向扩缩容,List 只能靠分片(多个 key)硬扛,运维成本陡增。
大 Key 导致内存与性能雪崩
百万消息堆在一个 List 里,哪怕每个消息仅 1KB,也占 1GB 内存。Redis 对单个 List 的遍历、LLEN、LRANGE 操作都是 O(N),长度超 10 万后,LLEN 就可能卡住主线程几十毫秒;LRANGE 0 -1 更是灾难——它会把整个链表拷贝进输出缓冲区,极易触发 client-output-buffer-limit 限流甚至连接被踢。这不是容量问题,是结构缺陷:链表不适合海量有序数据的随机切片访问。


















