c# - Redis 弹出列表项 按项目数

标签 c# caching redis stackexchange.redis .net-4.5.2

我有一个分布式系统,在一个地方我在 Redis 列表中插入了大约 10000 个项目,然后调用我的多个应用程序 Hook 来处理项目。我需要的是有一些带有项目数量的 ListLeftPop 类型的方法。它应该从 redis 列表中删除项目并返回到我的调用应用程序。

我正在使用 Stackexchange.Resis.extension

我当前仅用于 get(而不是 pop)的方法是

 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 和 get,我找到了一个片段

 var cacheClient = new StackExchangeRedisCacheClient(Muxer, new NewtonsoftSerializer());
                    var redisValues = cacheClient.ListGetFromRight<T>(key);

但它只适用于单个项目

最佳答案

我假设您正在处理一个队列,您在一个位置插入 1000 个项目,并按照插入顺序在多个位置检索它们

您无法使用单个命令来实现它,但可以使用 2 个命令来实现。你可以编写一个 lua 脚本来使它们原子化。

范围:http://redis.io/commands/lrange

Lrange list -100 -1

这将列出列表中的前 100 个元素。这里的偏移量是-100。 请注意,这将以与插入顺序相反的顺序返回项目。所以需要反向循环来保证队列机制。

Ltrim:http://redis.io/commands/ltrim

ltrim list 0 -101

这将修剪列表中的前 100 个元素。这里 101 是 n+1 所以它一定是 101。这里偏移量是 101

将它们写在 lua block 中将确保原子性。

让我举一个简单的例子。

You insert 100 elements in a single place.

lpush list 1 2 3 .. 100

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"

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 2 1。因此您需要反转循环并执行操作。

当下一个客户端进来时,它将获得下一组值。

127.0.0.1:6379> lrange list -5 -1
1) "10"
2) "9"
3) "8"
4) "7"
5) "6"

这样就可以达到你的要求了。希望这可以帮助。

编辑:

Lua脚本:

local result = redis.call('lrange', 'list','-5','-1')
redis.call('ltrim','list','0','-6')
return result

关于c# - Redis 弹出列表项 按项目数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37781806/

相关文章:

c# - 查找对对象的引用

google-app-engine - 在 Google App Engine 节点中缓存的最佳方式

c# - 服务器端数据库写入的最佳策略

c# - 如何在 C# 中从 GWT Request Builder 检索数据

c# - 通过 AutomationElement 设置 DateTimePicker 元素

python - REDIS BGSAVE 断言失败,由信号 6 终止。(macos/python)

使用 Redis pub sub 和 socket io 的 Laravel 广播需要超过 2 秒才能传送

Apache Ivy 术语和歧义

http - 缓存控制 header 中多个值的含义

node.js - connect-redis 不想连接到远程主机