ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Redis List 数据类型

Redis List 数据类型 Redis List 数据类型List 本质是按插入顺序排列的字符串双向链表。一、基础概念List 到底是什么1. 核心特性有序性元素严格按照插入顺序排列支持正向索引从左到右 0,1,2…和负向索引从右到左 -1,-2…-1代表最后一个元素。可重复同一个值可以多次插入没有去重能力。双向高效操作列表头部左端/left和尾部右端/right的插入、删除操作都是O(1)时间复杂度性能极高。随机访问慢按下标查找中间元素、在中间位置插入删除是O(n)列表越大性能越差。元素类型只能存字符串单个元素最大 512MB。✅ 实际开发定位优先用它做「两端操作的有序集合」绝对不要用它做随机查找。二、核心命令详解附开发使用频率1. 两端插入高频核心LPUSH左端头部插入元素语法LPUSH key value [value ...]作用从列表最左边插入一个或多个元素返回插入后的列表总长度示例# 插入3个元素从左依次插入最终顺序是 1003,1002,1001 LPUSH user:1:history 1001 1002 1003常用度★★★★★开发提示批量插入比循环单次插入性能高几倍尽量一次传多个值。RPUSH右端尾部插入元素语法RPUSH key value [value ...]作用从列表最右边插入一个或多个元素返回插入后的列表总长度示例# 插入3个任务最终顺序是 task1,task2,task3 RPUSH order:pay:queue task1 task2 task3常用度★★★★★2. 两端弹出删除并返回元素LPOP左端弹出元素语法LPOP key [count]作用移除并返回列表最左边的元素列表为空返回 nilRedis 6.2 支持 count 参数一次弹出多个示例LPOP order:pay:queue # 返回 task1列表变为 [task2, task3]常用度★★★★★RPOP右端弹出元素语法RPOP key [count]作用移除并返回列表最右边的元素常用度★★★★★3. 查询类命令LLEN获取列表长度语法LLEN key作用返回列表元素总数O(1) 复杂度Redis 内部维护了长度字段直接读取示例LLEN order:pay:queue # 返回 2常用度★★★★★LRANGE获取指定范围元素语法LRANGE key start stop作用获取索引[start, stop]闭区间内的所有元素是最常用的列表查询命令示例# 获取全部元素生产环境禁止对大列表使用 LRANGE order:pay:queue 0 -1 # 获取前2个元素第1页每页10条就是 0 9 LRANGE order:pay:queue 0 1常用度★★★★★开发提示-1代表最后一个元素-2代表倒数第二个stop 超出列表长度不会报错自动取到末尾。LINDEX获取指定索引元素语法LINDEX key index作用返回指定下标位置的元素O(n) 复杂度需要从头遍历到目标位置常用度★★☆☆☆开发提示大列表严禁频繁使用列表越长性能越差。4. 删除 与 裁剪LREM删除指定值的元素语法LREM key count valuecount 0从左往右删除 count 个匹配值count 0从右往左删除 |count| 个匹配值count 0删除所有匹配值示例# 从左往右删除2个值为 1001 的元素 LREM user:1:history 2 1001常用度★★★☆☆开发提示需要遍历列表匹配O(n) 复杂度大列表慎用。LTRIM裁剪列表定长列表神器语法LTRIM key start stop作用只保留[start, stop]范围内的元素其余全部删除示例# 只保留最近20条浏览记录超出的全部删除 LTRIM user:1:history 0 19常用度★★★★☆和 LPUSH 配合实现最新 N 条记录比如浏览历史、最新评论性能接近 O(1)。新增浏览商品id 1001放到列表头部LPUSH user:100:view1001裁剪只保留下标0~4也就是最新5条LTRIM user:100:view045. 阻塞式弹出消息队列核心BLPOP / BRPOP阻塞版弹出语法BRPOP key [key ...] timeout作用列表为空时阻塞等待直到有元素插入或超时有元素时立即弹出返回timeout 单位是秒设为 0 表示永久阻塞支持同时监听多个 key哪个列表先有元素就返回哪个多个消费者同时监听时先到先得不会重复消费示例# 阻塞等待支付队列任务最多等30秒超时返回nil BRPOP order:pay:queue 30常用度★★★★☆开发提示实现简单消息队列的核心命令比轮询查询性能高得多。RPOPLPUSH / BRPOPLPUSH原子移动元素语法RPOPLPUSH source destination作用原子操作从 source 列表右端弹出元素插入到 destination 列表左端返回该元素常用度★★★☆☆开发场景实现「可靠消息队列」——把消息从「待处理队列」移到「处理中队列」防止消费者宕机导致消息丢失。三、底层实现原理理解性能的关键Redis 3.2 之后List 的底层编码统一为quicklist快速列表替代了早期的 ziplist linkedlist 两套编码。1. quicklist 是什么本质是「双向链表 每个链表节点是一个压缩列表ziplist」的混合结构链表的每个节点叫quicklistNode每个节点内部是一段连续内存的 ziplist存多个元素节点之间用双向指针连接保证头尾插入删除 O(1)节点内部用压缩列表存储减少内存碎片提升空间利用率2. 对开发的意义头尾操作永远是 O(1)不管列表多大LPUSH/RPUSH/LPOP/RPOP 都极快放心使用。中间操作是 O(n)LINDEX、LSET、LINSERT、中间位置 LREM 都需要遍历列表越大越慢。小列表内存极省元素少时整个列表就是一个 ziplist连续内存占用非常小。可配置优化通过list-max-ziplist-size可以调整每个 ziplist 的大小平衡空间和性能。四、实际开发中的经典应用场景这部分是开发最关心的内容每个场景都讲清楚「实现方式 优缺点 适用边界」。场景1轻量级消息队列这是 List 最广泛的用途之一适合非核心异步任务。实现方式生产者LPUSH把任务投递到队列消费者BRPOP阻塞等待获取任务# 生产者投递支付回调任务 LPUSH order:pay:callback order_1001 order_1002 # 消费者永久阻塞等待任务 BRPOP order:pay:callback 0进阶可靠队列避免消息丢失用RPOPLPUSH做消息中转消费前原子移动到「处理中队列」消费成功后从处理中队列删除消费失败可以从重试队列恢复# 原子操作待处理 → 处理中 RPOPLPUSH order:pay:callback order:pay:processing # 消费成功后删除 LREM order:pay:processing 1 order_1001适用与不适用✅ 适用日志上报、短信发送、站内信、非核心数据同步等可容忍少量丢失的场景❌ 不适用订单支付、库存扣减等核心业务需要广播、延迟消息、死信队列的场景开发提示核心业务请用 RabbitMQ、Kafka 等专业 MQRedis List 只做轻量补充。场景2最新N条记录 / 时间线比如用户浏览历史、文章最新评论、朋友圈动态、操作日志。实现方式新记录用LPUSH插入头部配合LTRIM固定长度天然按时间倒序排列。# 用户浏览商品新增记录 LPUSH user:100:browse_history product_501 # 只保留最近20条超出自动删除 LTRIM user:100:browse_history 0 19 # 查看浏览历史 LRANGE user:100:browse_history 0 -1优势插入和裁剪都是接近 O(1)性能极高天然按时间倒序不用额外排序内存占用小开发提示列表里只存 ID不要存大对象详情数据根据 ID 去数据库或缓存查。场景3栈 / 双端队列栈先进后出LPUSH LPOP或者RPUSH RPOP队列先进先出LPUSH RPOP或者RPUSH LPOP双端队列两端都可进出灵活适配业务场景4浅分页列表比如商品评论、公告列表按时间倒序分页第1页LRANGE comment:100 0 9第2页LRANGE comment:100 10 19开发提示只适合小数据量、分页不深的场景。深分页的 LRANGE 需要遍历到起始位置性能会下降大数据量分页建议用 Sorted Set 或数据库。五、生产环境避坑指南禁止大列表单个 List 建议不超过 1 万条元素过大的列表会占用大量内存操作时容易阻塞 Redis。数据量大请分 key 或换其他数据结构。禁止全量查询大列表绝对不要对大列表执行LRANGE key 0 -1会导致 Redis 长时间阻塞。尽量不操作中间元素LINDEX、LSET、LINSERT、中间位置LREM都是 O(n)业务上尽量只操作两端。阻塞命令设置超时BRPOP不要无脑设 0 永久阻塞设置合理超时时间避免连接泄漏配合连接池使用。批量插入减少 IO用LPUSH/RPUSH一次传多个值比循环单次插入减少大量网络开销。定长用 LTRIM 不用 LREMLTRIM性能远高于循环删除做最新列表优先用裁剪。
返回列表