目录
redis 列表的简单操作和使用
redis列表类型内部是适用 双向列表(double linked list)
优点:首尾插入,查找操作是比较快的
缺点:在大量元素中查找中间某个元素就会比较慢,因为是通过索引迭代的去查找的
适用场景:一般是消息队列,栈,秒杀等
菜鸟教程redis列表简要讲解:Redis 列表(List) | 菜鸟教程
底层实现
quicklist实现
结合了压缩列表和双向链表的优势。它是一个由多个压缩列表作为节点组成的双向链表。
quicklist结构体定义:
typedef struct quicklist {
quicklistNode *head;
quicklistNode *tail;
unsigned long count; /* 所有列表包中所有条目的总数,占用16 bits,最大65536 */
unsigned long len; /* quicklistNode 的数量 */
signed int fill : QL_FILL_BITS; /* 单个节点的填充因子 */
unsigned int compress : QL_COMP_BITS; /* 不压缩的端节点深度;0=off */
unsigned int bookmark_count: QL_BM_BITS;
quicklistBookmark bookmarks[];
} quicklist;
快速列表的优点包括:
-
支持更大的数据量。
-
插入和删除操作在头部或尾部的高效性。
-
更好的内存管理。
缺点包括:
-
相比于单个压缩列表,内存使用稍高。
-
需要额外的指针来链接各个节点。
list操作的时间复杂度
-
LPUSH/RPUSH:在列表的头部或尾部插入元素的时间复杂度为 O(1)。
-
LPOP/RPOP:从列表的头部或尾部弹出元素的时间复杂度也为 O(1)。
-
LINDEX:获取指定索引的元素的时间复杂度为 O(n),其中 n 是索引距离头部的距离。
-
LRANGE:获取指定范围内的元素,时间复杂度为 O(s+m),其中 s 是起始索引到头部的距离,m 是要获取的元素数量。
-
LLEN: 程序获取链表中节点数量的复杂度为O(1), 直接使用list结构的len属性来对list持有的链表节点进行计数
更多实际使用场景
-
消息队列:
-
Redis列表可以用于实现简单的消息队列。生产者可以通过
LPUSH
命令将消息推入队列,而消费者则通过RPOP
命令从队列尾部取出消息。
-
-
任务队列:
-
在分布式系统中,可以使用Redis列表来处理任务队列。例如,可以使用
LPUSH
添加新任务,用BRPOP
(阻塞列表的尾部弹出)来处理任务,这样可以避免轮询
-
-
最新条目缓存:
-
可以使用列表来存储最近的条目,如最新的用户评论、日志条目等。通过
LPUSH
添加新条目,然后用LRANGE
获取最近的条目。
-
-
分页显示
-
在Web应用中,当需要分页显示数据时,可以使用Redis列表存储分页数据。例如,使用
LPUSH
添加数据,然后通过LRANGE
获取指定范围的条目进行显示。
-
-
排行榜
-
Redis列表可以用于实现简单的排行榜功能。例如,可以使用
LPUSH
和分数一起使用(通过将分数转换为字符串并与元素一起存储),然后使用LRANGE
基于分数进行排序和获取排行榜。
-
-
延迟队列
-
结合使用Redis的列表和有序集合(Sorted Set),可以实现延迟队列。例如,可以使用
ZADD
将消息及其延迟时间作为分数存储,然后使用ZRANGEBYSCORE
和ZREMRANGEBYSCORE
管理这些消息。
-
-
会话管理
-
在Web应用中,可以使用Redis列表来管理用户的会话信息。例如,可以使用列表存储用户的活动记录或最近的请求信息。
-
-
构建简单的缓存
-
对于需要快速访问的数据,可以将它们存储在Redis列表中。例如,可以使用
LPUSH
和LPOP
来实现一个简单的FIFO缓存。
-
-
构建简单的计数器:
-
虽然不是直接使用列表的典型方式,但可以通过对列表进行操作(如添加元素)来间接实现计数器功能。例如,可以使用
LPUSH
每次操作时增加计数。
-
-
构建简单的堆栈
-
类似于队列,Redis列表也可以被用作堆栈(后进先出)。使用
LPUSH
和LPOP
实现堆栈的压栈和出栈操作。
-