从Redis的列表中自动弹出并删除多个项目

作者 : IT 大叔 本文共1132个字,预计阅读时间需要3分钟 发布时间: 2020-10-14

我们在做什么?

我们正尝试从Redis的列表中自动弹出并删除多个项目。

什么?

考虑一个列表:0 1 2 3 4 5
我想返回前3个项目的结果,然后删除那些项目。我还需要保证列表在返回结果和从列表中删除结果之间的时间不会改变。

一个例子

考虑以下示例:

> RPUSH mykey 0 1 2 3 4 5
(integer) 6
> LRANGE mykey 0 2
1) "0"
2) "1"
3) "2"
> LTRIM mykey 3 -1
OK
> LRANGE mykey 0 99
1) "3"
2) "4"
3) "5"

如果您是唯一操作列表的人,则此方法效果很好。但是,如果有人同时处理列表怎么办?

> RPUSH mykey 0 1 2 3 4 5
(integer) 6
> LRANGE mykey 0 2
1) "0"
2) "1"
3) "2"
> LTRIM mykey 3 -1
OK
> LRANGE mykey 0 99
(empty array)

哦哦 我们称为B的另一个消费者跑了LRANGE mykey 0 2并且得到了0 1 2。在它们之后,我们立即运行了相同的命令,并获得了相同的结果。消费者B现在运行LTRIM mykey 3 -1,我们也这样做。现在列表为空,但是两个消费者都只收到列表的前3个项目。决赛3名不见了。

我需要这两项交易LRANGELTRIM,是原子的。这意味着它们要么都执行,要么都不执行。在Redis中,我们可以使用transaction实现此目的。事务中的所有命令都被序列化并顺序执行。在Redis事务的执行过程中,永远不会发生另一个客户端发出的请求。这样可以确保将命令作为单个隔离操作执行。

如果您使用的是Redis CLI,则可以将代码更改为如下所示:

> MULTI
OK
> RPUSH mykey 0 1 2 3 4 5
QUEUED
> LTRIM mykey 3 -1
QUEUED
> EXEC
1) (integer) 6
2) OK

在Python中

由于没有人真正使用CLI,因此让我们在Python中进行操作。该脚本使用redis-py的Pipeline功能。管道是Redis基类的子类,它提供对在单个请求中缓冲到服务器的多个命令的支持。

>>> import redis
>>> my_key = 'pop_trim_test'
>>> r = redis.Redis(host='localhost', port=6379)
>>> r.rpush(my_key, *[x for x in range(10)])
>>> pipe = r.pipeline()
>>> pipe.lrange(my_key, 0, 3)
>>> pipe.ltrim(my_key, 4, -1)
>>> pipe.execute()
[[b'0', b'1', b'2', b'3'], True]

pipe.execute()依次返回管道命令的结果作为列表。因此,我们的结果lrange是列表中的第一项。

免责声明:
1. 本站资源转自互联网,源码资源分享仅供交流学习,下载后切勿用于商业用途,否则开发者追究责任与本站无关!
2. 本站使用「署名 4.0 国际」创作协议,可自由转载、引用,但需署名原版权作者且注明文章出处
3. 未登录无法下载,登录使用金币下载所有资源。
IT小站 » 从Redis的列表中自动弹出并删除多个项目

常见问题FAQ

没有金币/金币不足 怎么办?
本站已开通每日签到送金币,每日签到赠送五枚金币,金币可累积。
所有资源普通会员都能下载吗?
本站所有资源普通会员都可以下载,需要消耗金币下载的白金会员资源,通过每日签到,即可获取免费金币,金币可累积使用。

发表评论