Redis

Redis List

2019-03-20  本文已影响0人  JunChow520

链表的应用广泛,在获取最新的数据的场景比较多,如粉丝的关注列表、我的收藏列表、最新消息列表、排行榜、有时间轴的数据、微博的评论系统、消息传递、并行转串行...

在看完一条微博后常常会有一番评论,每条评论的记录都是按照时间顺序排列。链表是一个很好的存储结构,在每次提交一条评论时,都向链表尾部添加一个新节点即可。

用户每时每刻都可以发出请求,而且请求的频率经常变化,后台程序不可能立即响应每个用户的请求,尤其是请求特别占资源的服务时。此时,需要有一个排队系统,根据用户的请求时间,将用户的请求放入到队列中,后台服务依此从队列中获取任务,处理完后将结果返回给队列。这其实也是一个生产者消费者模型,通过队列将并行的请求转换成串行的任务队列之后依次处理,当然后台服务也可以多核并行处理。

需求:获取最新数据

例如:获取最新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的lpushbrpop命令组合既可以实现阻塞队列,客户端生产者使用lrpush从列表list的左侧头部插入元素,多个客户端消费者使用brpop阻塞式的抢占右侧尾部的元素,多个客户端保证了消费的负载均衡和高可用性。

链表

链表的应用场景

链表的应用场景

栈(stack)是一种线性表,对栈的插入和删除操作都被限制在表的同一端进行,这一端称为栈顶,与之对应称为栈底。

先进后出的栈

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

出栈入栈 队列结构 出对入队

Redis中的List

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

双向链表

链表被广泛地用于实现Redis的各种功能,如列表键、发布与订阅、慢查询、监视器等。

Redis中单个List可容纳2^32-1约40亿个元素

链表的特点

上一篇 下一篇

猜你喜欢

热点阅读