列表
以有序的方式储存多个可重复的值
LPUSH key value [value …]
将一个或以上数量的值依次推入到列表的左端,命令返回新值被推入之后,列表目前包含的项数量。
RPUSH key value [value …]
将一个或以上数量的值依次推入到列表的右端,命令返回新值被推入之后,列表目前包含的项数量。
LPOP key
移除并返回列表最左端的项
RPOP
移除并返回列表最右端的项
LLEN key
返回列表键key的长度,也即是,返回列表包含的列表项数量。
LINDEX key index
返回列表键key中,指定索引index上的列表项。index索引可以是正数或者负数。
LRANGE key start stop
返回列表键key中,从索引start至索引stop范围内的所有列表项。两个索引参数都可以是正数或者负数。
Twitter使用Redis的列表来储存用户时间线
列表的每一项都包含一个消息id,通过这个id可以查找到消息本身。每当有新的消息要添加到用户的时间线里面时,程序就会把该消息的id推入到用户的时间线列表里面。每当有人访问用户的时间线时,程序就会访问时间线列表,并根据列表中储存的ID来获取用户时间线上的消息。通过时间线列表中的不同范围,程序可以获取到不同时期的消息,越接近表头的消息就越新,越接近表尾的消息就越旧。
API | 说明 | 操作 |
---|---|---|
Timeline(user_name, client) | 指向用户的时间线。 | |
Timeline.push(message_id) | 将消息推入至用户时间线 | 调用LPUSH命令(列表左方为新消息,右方为旧消息)。 |
Timeline.fetch_recent(n) | 获取最新的n条消息。 | 调用LRANGE命令。 |
Timeline.fetch_from_index(start_index, n) | 获取从start_index索引开始的n条消息 | 调用LRANGE命令。 |
插入和删除操作
LSET key index value
将列表键key索引index上的列表项设置为value,设置成功时命令返回OK。如果index参数超过了列表的索引范围,那么命令返回一个错误。
LINSERT key BEFORE|AFTER pivot value
根据命令调用时传递的是BEFORE选项还是AFTER选项,将值value插入到指定列表项pivot的之前或者之后。当pivot不存在列表key时,不执行任何操作。
LREM key count value
根据参数count的值,移除列表中与参数value相等的列表项:
- 如果count>0, 那么从表头开始向表尾搜索,移除最多count个值为value的列表项
- 如果count<0, 那么从表尾开始向表头搜索,移除最多abs(count)个值为value的列表项。
- 如果count=0, 那么移除列表中所有值为value的列表项。
LTRIM key start stop
对一个列表进行修剪(trim),让列表只保留指定索引范围内的列表项,而将不在范围内的其他列表项全部删除。两个索引都可以是正数或者负数。
定长先进先出队列
API | 说明 | 操作 |
---|---|---|
FixedFIFO(key, max_length, client) | key设置队列储存在哪个键,max_length设置队列的最大长度 | |
FixedFIFO.enqueue(item) | 将给定值推入到队列 | 调用LPUSH命令来推入值,电泳LRTIM命令来保持队列的最大长度。 |
FixedFIFO.dequeue() | 弹出列表中最旧的值。 | 调用RPOP命令。 |
FixedFIFO.get_all_items() | 返回队列包含的所有值 | 调用LRANGE命令。 |
FixedFIFO.length() | 返回队列的长度。 | 调用LLEN命令。 |
阻塞式弹出操作
API | 说明 |
---|---|
BLPOP key [key …] timeout | LPOP命令的阻塞版本:命令会以从左到右的顺序,访问给定的各个列表,并弹出首个非空列表最左端的项;如果所有给定列表都为空。那么客户端将被阻塞,直到等待超时,或者有可弹出的项出现为止:设置timeout参数为0表示永远阻塞。 |
BRPOP key [key …] timeout | RPOP命令的阻塞版本:命令会以从左到右的顺序,访问给定的各个列表,并弹出首个非空列表最左端的项;如果所有给定列表都为空。那么客户端将被阻塞,直到等待超时,或者有可弹出的项出现为止:设置timeout参数为0表示永远阻塞。 |
如果有多个客户端同时因为某个列表而被阻塞,那么当有新值被推入到这个列表时,服务器会按照先到先服务原则,优先向最早被阻塞的客户端返回新值。
当用户发布Twitter消息,所有关注者都应该收到消息,但是当关注者数量过大时,推送操作需要花费大量时间才能完成,发送消息的用户需要等待很久才能获得响应。
发送者<---发送消息--->web服务器---推入--->消息队列<---取出消息推送给关注者---消息服务器
好处:
- web服务器可以在保存好用户发布的消息,并将消息推入到队列之后,立即返回,这样web服务器就可以以最快的速度对用户进行响应。
- web服务器不会被消息推送操作影响,这有助于提升效率和简化程序逻辑。
- 因为推送操作由专门的消息服务器负责,所以我们可以针对性地进行优化。
消息队列实现
API | 说明 | 操作 |
---|---|---|
MessageQueue(key, client) | 将给定键设置为消息队列。 | |
MessageQueue.enqueue(item) | 将给定值推入到队列里面。 | 调用LPUSH命令。 |
MessageQueue.dequeue(timeout) | 在给定的时限内,等待队列弹出一个最旧的项。 | 调用BRPOP命令。 |
MessageQueue.get_all_items() | 返回队列中的所有项 | 调用LRANGE命令。 |
MessageQueue.length() | 返回队列的长度。 | 调用LLEN命令 |