Redis List
链表的应用广泛,在获取最新的数据的场景比较多,如粉丝的关注列表、我的收藏列表、最新消息列表、排行榜、有时间轴的数据、微博的评论系统、消息传递、并行转串行...
- 评论系统
在看完一条微博后常常会有一番评论,每条评论的记录都是按照时间顺序排列。链表是一个很好的存储结构,在每次提交一条评论时,都向链表尾部添加一个新节点即可。
- 并行转串行
用户每时每刻都可以发出请求,而且请求的频率经常变化,后台程序不可能立即响应每个用户的请求,尤其是请求特别占资源的服务时。此时,需要有一个排队系统,根据用户的请求时间,将用户的请求放入到队列中,后台服务依此从队列中获取任务,处理完后将结果返回给队列。这其实也是一个生产者消费者模型,通过队列将并行的请求转换成串行的任务队列之后依次处理,当然后台服务也可以多核并行处理。
需求:获取最新数据
例如:获取最新10个登录用户的数据
传统做法:使用SQL查询SELECT * FROM user ORDER BY login_time DESC LIMIT 10
,若用户量比较大可对关键查询条件字段添加索引来解决,问题是索引也是需要消耗RDBMS的系统资源的。虽然是可以解决,但未久无法解决在数据量大以及数据库负载高的情况下,出现的种种弊端。
Redis做法:使用Redis的List来实现,实现思路是在Redis中的List中保留10条数据,用户登录时添加一条新数据同时删除一条旧数据。
# 向链表login_latest中添加10条最近登陆用户的ID
$ lpush login:latest 119342
$ lpush login:latest 123145
$ lpush login:latest 657271
...
# 获取链表的长度
$ llen login:latest
# 左侧头部添加一条数据同时右侧尾部删除第一条数据
$ lpush login:latest 983233
$ rpop login:latest
# 获取链表中的元素
$ lrange login:latest 0 9
需求:消息队列
当你要呈现页面给用户前有复杂而且耗时的运算操作,但这个操作并不影响页面呈现的数据,也不作为页面呈现的数据时。我们可以采用两种方式来解决:第一种运算完毕后呈现页面,第二种将要计算的数据抛到持久化的消息队列中,不做耗时运算的则直接呈现给用户。然后使用另一个程序对消息队列中的数据单独做运算。
Redis中List的lpush
和brpop
命令组合既可以实现阻塞队列,客户端生产者使用lrpush
从列表list
的左侧头部插入元素,多个客户端消费者使用brpop
阻塞式的抢占右侧尾部的元素,多个客户端保证了消费的负载均衡和高可用性。
链表
链表的应用场景
-
lpush
+lpop
=stack
先进后出的栈 -
lpush
+rpop
=queue
先进先出的队列 -
lpush
+ltrim
=capped collection
有限集合 -
lpush
+brpop
=message queue
消息队列
链表的应用场景
- 栈
栈(stack)是一种线性表,对栈的插入和删除操作都被限制在表的同一端进行,这一端称为栈顶,与之对应称为栈底。

栈的特点是先进后出(FILO)或后进先出(LIFO),通常栈可以使用顺序的方式存储数组,分配一块连续的存储区域来存放栈中的元素或条目,并使用一个变量指向当前栈顶。

- 队列


Redis中的List
Redis中的List实际上是一个string
类型的双向链表,因此既可以做栈也可以做队列来使用。不同的是栈是先进后出,队列是先进先出。

链表被广泛地用于实现Redis的各种功能,如列表键、发布与订阅、慢查询、监视器等。
Redis中单个List可容纳2^32-1
约40亿个元素
链表的特点
- 链表中的元素是有序的,可通过索引下标来获取某个元素或某个范围内的元素列表。
- 链表中的元素是可以重复的