Redis Pop列表项,按项数 [英] Redis Pop list item By numbers of items
问题描述
我有一个分布式系统,在一个地方,我在Redis列表中插入大约10000个项目,然后调用我的多个应用程序钩子来处理项目。我需要的是具有一些项目的一些方法的ListLeftPop类型。它应该从redis列表中删除项目,并返回到我的调用应用程序。
I have a distributed system where In one place i insert around 10000 items in a redis list then Call my multiple applications hook to process items. what i need is to Have some ListLeftPop type of methhod with numbers of items. It should remove items from the redis List and return to my calling application.
我正在使用Stackexchange.Resis.extension
I am using Stackexchange.Resis.extension
我当前用于获取(不弹出)的方法是
My current method just for get (not pop) is
public static List<T> GetListItemRange<T>(string key, int start, int chunksize) where T : class
{
List<T> obj = default(List<T>);
try
{
if (Muxer != null && Muxer.IsConnected && Muxer.GetDatabase() != null)
{
var cacheClient = new StackExchangeRedisCacheClient(Muxer, new NewtonsoftSerializer());
var redisValues = cacheClient.Database.ListRange(key, start, (start + chunksize - 1));
if (redisValues.Length > 0)
{
obj = Array.ConvertAll(redisValues, value => JsonConvert.DeserializeObject<T>(value)).ToList();
}
}
}
catch (Exception ex)
{
Logger.Fatal(ex.Message, ex);
}
return obj;
}
对于Pop来说,让我找到一个摘录
For Pop and get i have find a snippet
var cacheClient = new StackExchangeRedisCacheClient(Muxer, new NewtonsoftSerializer());
var redisValues = cacheClient.ListGetFromRight<T>(key);
但这仅适用于单个项目
推荐答案
我假设您正在处理队列,在该队列中,您可以在一个位置插入1000个项目,然后在该位置的多个位置检索它们插入的位置。
I assume that you are working on a queue, where you insert 1000 items at a single place and retrieve them at multiple place in the order at which it is inserted.
您无法使用单个命令来实现它,但是可以使用2个命令来实现。您可以编写一个lua脚本使它们原子化。
You can't achieve it with a single command but you can do it with 2 commands. You can write a lua script to make them atomic.
Lrange: http://redis.io/commands/ lrange
Lrange list -100 -1
这将在列表中列出您的前100个元素。这里的偏移量是-100。
请注意,这将以插入时的相反顺序返回项目。因此,您需要反转循环以确保队列机制。
This will list you first 100 elements in the list. here the offset is -100. Note that this will return the items in the opposite order at which it is inserted. So you need to reverse the loop to ensure the queue mechanism.
Ltrim: http://redis.io/commands/ltrim
ltrim list 0 -101
这将修剪列表中的前100个元素。这里的101是n + 1,所以它必须是101。这里的偏移是101
This will trim the 1st 100 elements in the list. here 101 is n+1 so it must be 101. Here offset is 101
在lua块中写入它们可以确保您的原子性。
Writing them inside a lua block will ensure you the atomicity.
让我举一个简单的例子。
Let me give you a simple example.
您可以在一个位置插入100个元素。
You insert 100 elements in a single place.
lpush list 1 2 3 .. 100
您有多个客户端
试图访问此lua块。假设您的n值为5。第一个
客户端进入并插入了前5个元素。
You have multiple clients each trying to access this lua block. Say your n value is 5 here. 1st client gets in and gets first 5 elements inserted.
127.0.0.1:6379> lrange list -5 -1
1) "5"
2) "4"
3) "3"
4) "2"
5) "1"
您将它们保留在lua对象中并删除。
You keep them in your lua object and delete them.
127.0.0.1:6379> LTRIM list 0 -6
OK
将它们返回到您的代码,现在返回所需的结果是1 2 3 4 5但您得到的是5 4 3 21。因此您需要反转循环并执行操作。
return them to your code, now the result you want is 1 2 3 4 5 but what you have got is 5 4 3 2 1. So you need to reverse the loop and perform the operation.
下一个客户进入时,它将获得下一组值。
When the next client comes in it will get the next set of values.
127.0.0.1:6379> lrange list -5 -1
1) "10"
2) "9"
3) "8"
4) "7"
5) "6"
这样您就可以实现您的要求。希望这可以帮助。
In this way you can achieve your requirement. Hope this helps.
编辑:
Lua脚本:
local result = redis.call('lrange', 'list','-5','-1')
redis.call('ltrim','list','0','-6')
return result
这篇关于Redis Pop列表项,按项数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!