当前位置: 首页 > news >正文

Redis命令-List命令

一、前言:List 不只是“列表”,更是高性能工具

Redis 的List(列表)是一个双向链表结构,支持从两端高效插入和弹出(O(1) 时间复杂度)。
它不仅是简单的数据容器,更是构建以下系统的基石:

  • 轻量级消息队列
  • 用户最新动态/评论流
  • 任务调度缓冲池
  • 限流滑动窗口

本文将系统讲解Redis List 的核心命令,并深入实战应用场景与性能陷阱


二、List 核心命令速查表

命令作用时间复杂度
LPUSH key value [value ...]左端插入一个或多个元素O(1) 每个元素
RPUSH key value [value ...]右端插入一个或多个元素O(1) 每个元素
LPOP key [count]左端弹出一个或多个元素O(N),N=弹出数量
RPOP key [count]右端弹出一个或多个元素O(N)
BLPOP key [key ...] timeout阻塞式左弹出(超时返回 nil)O(1)
BRPOP key [key ...] timeout阻塞式右弹出O(1)
LRANGE key start stop获取指定范围元素(支持负数索引)O(S+N),S=起始偏移,N=返回元素数
LLEN key获取列表长度O(1)
LINDEX key index获取指定索引的元素O(N),N=索引位置
LSET key index value设置指定索引的值O(N)
LINSERT key BEFORE|AFTER pivot value在指定元素前后插入新元素O(N)
LTRIM key start stop修剪列表,只保留指定范围O(N),N=被删除元素数

💡关键特性

  • 左 = 头(head),右 = 尾(tail)
  • 支持阻塞操作(Bxxx),天然适配生产者-消费者模型

三、常用命令详解与示例

3.1 插入元素:LPUSH/RPUSH

# 从左侧插入(新元素在前) 127.0.0.1:6379> LPUSH news "头条新闻" "科技快讯" "体育速递" (integer) 3 # 查看列表(从左到右) 127.0.0.1:6379> LRANGE news 0 -1 1) "体育速递" 2) "科技快讯" 3) "头条新闻" # 从右侧插入(新元素在后) 127.0.0.1:6379> RPUSH news "财经要闻" 127.0.0.1:6379> LRANGE news 0 -1 1) "体育速递" 2) "科技快讯" 3) "头条新闻" 4) "财经要闻"

典型模式

  • LPUSH + LTRIM→ 实现最新 N 条记录
  • LPUSH + RPOP→ 实现栈(LIFO)
  • LPUSH + LPOP→ 实现队列(FIFO)

3.2 弹出元素:LPOP/RPOP/BLPOP

# 非阻塞弹出(无数据返回 nil) 127.0.0.1:6379> LPOP news "体育速递" # 阻塞弹出(等待最多 5 秒) 127.0.0.1:6379> BLPOP task_queue 5 (nil) # 5 秒内无数据,返回 nil # 多队列监听(优先级队列) 127.0.0.1:6379> BLPOP high_priority_queue low_priority_queue 0 # 只要任一队列有数据,立即返回

⚠️注意BLPOP/BRPOP在 Redis 中是原子操作,适合做可靠队列。


3.3 范围查询:LRANGE

# 获取前 10 条(最新动态) 127.0.0.1:6379> LRANGE user:1001:timeline 0 9 # 获取最后 5 条(倒序) 127.0.0.1:6379> LRANGE user:1001:timeline -5 -1 # 获取全部(慎用!大数据量会阻塞) 127.0.0.1:6379> LRANGE big_list 0 -1

🔍性能提示

  • LRANGE的时间复杂度与返回元素数量成正比
  • 避免对大列表执行LRANGE 0 -1

3.4 修剪列表:LTRIM(实现“最新 N 条”)

# 推送新动态,并只保留最近 100 条 127.0.0.1:6379> LPUSH user:1001:timeline "发布了新文章" 127.0.0.1:6379> LTRIM user:1001:timeline 0 99

这是实现“朋友圈最新 100 条”的标准做法!


四、List 的内部编码

Redis 对小 List 使用ziplist(压缩列表)编码,节省内存:

# redis.conf 默认配置 list-max-ziplist-size -2 # -2 表示每个节点不超过 8KB list-compress-depth 0 # 不压缩(可设为 1~3 启用 LZF 压缩)

当元素数量或大小超过阈值,自动转为linkedlist(快速链表)

💡建议

  • 短列表(如消息队列、时间线)性能极佳
  • 避免存储超大 List(如 > 10 万元素)

五、实战应用场景

场景 1:轻量级消息队列(生产者-消费者)

# 生产者(Python) import redis r = redis.Redis() r.lpush("task_queue", '{"action": "send_email", "to": "user@example.com"}') # 消费者(阻塞等待) while True: task = r.brpop("task_queue", timeout=5) if task: process(json.loads(task[1]))

优势:简单、可靠、支持多消费者
局限:不支持 ACK、重试、延迟消息(需用 Stream 或专业 MQ)


场景 2:用户最新动态(Timeline)

// Java (Lettuce) String userId = "1001"; String timelineKey = "user:" + userId + ":timeline"; // 发布新动态 redis.lpush(timelineKey, "用户发布了新照片"); redis.ltrim(timelineKey, 0, 99); // 只保留 100 条 // 获取最新 10 条 List<String> latest = redis.lrange(timelineKey, 0, 9);

📌注意:此方案适合单用户时间线,不适合全局热门 feed(需用排序集合 ZSet)


场景 3:滑动窗口限流

# 每秒最多 5 次请求 EVAL " local now = tonumber(ARGV[1]) local window = now - 1000 -- 1秒窗口 redis.call('LPUSH', KEYS[1], now) redis.call('LTRIM', KEYS[1], 0, 4) -- 只保留5个时间戳 local count = redis.call('LLEN', KEYS[1]) local oldest = redis.call('LINDEX', KEYS[1], -1) if oldest and tonumber(oldest) < window then return {count, 'expired'} else return {count, 'allowed'} end " 1 user:1001:rate_limit 1700000000000

六、常见误区与最佳实践

❌ 误区 1:用 List 存储超大集合

  • 问题LRANGE 0 -1阻塞主线程
  • 建议:大集合改用SetSorted Set

❌ 误区 2:频繁使用LINDEX/LSET

  • 问题:O(N) 复杂度,性能差
  • 建议:如需随机访问,考虑用HashString 分片

✅ 最佳实践

  1. 队列命名规范:如queue:order:pending
  2. 设置 TTL:防止死队列堆积(EXPIRE queue 86400
  3. 监控长度:通过LLEN+ 告警防止内存爆炸
  4. 避免大 Value:单个元素建议 < 1KB

七、List vs 其他类型选型建议

需求推荐类型
FIFO 队列List(LPUSH + RPOP)
最新 N 条记录List(LPUSH + LTRIM)
唯一性集合Set
排序/排行榜Sorted Set
对象存储Hash
高可靠消息队列Stream(Redis 5.0+)

📌List 适合简单、高性能、顺序敏感的场景


八、结语

感谢您的阅读!如果你有任何疑问或想要分享的经验,请在评论区留言交流!

http://www.jsqmd.com/news/483577/

相关文章:

  • 拇指大小的射频功率计设计与宽量程实现原理
  • 免费IP类API接口全解析:从归属地到行业应用
  • 2026 智能体开发全指南:主流框架盘点、实战代码与选型策略(2026智能体开发系列·第1篇)
  • 探索者STM32F4开发板硬件资源深度解析与实战应用指南
  • GD32 ADC 定时器触发+DMA搬运:构建高效数据采集链的实战指南
  • 地理空间可视化崩溃频发,R 4.5中rgdal弃用后5步无缝迁移至sf+wk+geoarrow(含完整迁移检查清单)
  • 2026精选课题-基于springboot汽车配件管理系统的设计与实现
  • Dify评估引擎升级全景图:从v0.12到v1.5,3类模型判据权重重构、5项延迟优化指标及企业级审计日志规范
  • uniapp集成腾讯播放器实现App端视频播放功能实战
  • 2.1 网络编程 异步网络库zvnet
  • Audio Pixel Studio部署教程(Serverless版):Vercel/Cloudflare Pages托管
  • 别再调戏ChatGPT了!OpenClaw正式“破壳”:那个有手的AI,真的来了
  • DeepSeek-OCR部署避坑:首次唤醒慢问题诊断与SSD缓存优化方案
  • 分离式游戏机硬件平台:GD32F470多模无线交互设计
  • RAG生成阶段优化:解决幻觉、多轮对话与引用标注,小白程序员必备收藏!
  • 从抖振到平滑:基于饱和函数sat(s)的准滑动模态滑模控制SIMULINK实践
  • 第四章 第一性原理 vs 类比思维:人类两种终极思考模式
  • 【常亮24天】立创开源:基于STC32F12K54的低功耗迷你桌面时钟4.0版硬件与软件全解析
  • RockyLinux 10.1深度解析:软重启赋能高效运维,后量子加密守护数据新纪元
  • nlp_gte_sentence-embedding_chinese-large实现Python爬虫数据智能处理:自动化采集与清洗
  • 35岁程序员转型指南:避开年龄危机,拥抱AI高薪新赛道
  • 从零开始:Unsloth环境搭建与模型微调完整教程
  • 数据清洗面试问答指南(面试官 vs 实习生)
  • 鸿蒙物联WiFi开关:机械式墙壁开关的非侵入式智能改造方案
  • 第六章 第一性原理:商业世界的本质、价值与决策底层逻辑
  • Global Mapper三维地形与建筑可视化实战指南
  • COMSOL模拟边坡降雨不饱和条件下强度折减的影响研究
  • ESP32-S3语音交互终端:低成本教育级硬件设计
  • 2026 AI浪潮下,程序员的职业突围与机遇,年薪154W!真心建议大家冲一冲新兴领域
  • 深入解析display lldp neighbor与display mac-address的工作原理及网络管理应用