如何使用某个命令或Lua脚本读取存储在Redis上的多个集合

我想在一次调用中使用键列表从Redis获取所有集合。根据文档,Redis提供了SSCAN命令来实现这一点,但是由于我正在使用StackExchange.Redis作为Redis适配器,我估计这个适配器中没有这样的方法。 因此,有两件事情我正在寻找:

-我希望使用Lua脚本执行SSCAN,但是在互联网上找不到任何这样的示例。有人可以分享如何使用多个SET键调用SSCAN的示例吗?

  • 此外,对于StackExchange.Redis,如果我在事务中执行多个SetMembers(),是否类似于使用LUA脚本使用SSCAN()命令?

谢谢

点赞
用户3160475
用户3160475

可以通过传递 Set 键的列表在单个调用中获取多个集合。

由于我不清楚具体的要求,因此可能有几种方法可以实现。最简单的方法是调用 SUNION,它将去重并返回无序的结果。

另一个选择是使用 Lua 脚本,例如:

local reply = {}
for i = 1,#KEYS do
  local elems = redis.call('SMEMBERS', KEYS[i])
  table.insert(reply, elems)
end
return reply

redis-cli 示例(抱歉,.NET 不是我的优势):

$ redis-cli SADD s1 foo bar
(integer) 2
$ redis-cli SADD s2 baz qaz
(integer) 2
$ redis-cli --eval script.lua s1 s2
1) 1) "foo"
   2) "bar"
2) 1) "baz"
   2) "qaz"

注意:如果您的集合成员很多,那么无论采用什么方法,获取所有成员都会很“昂贵” - 重新考虑是否需要。

2017-04-13 08:54:38
用户797473
用户797473

以下是使用 StackExchange.Redis 作为 Redis 连接器获取多个 SETs 的示例 C# 代码:

using StackExchange.Redis;
using System;
using System.Text;

namespace RedisGetMultipleKeys
{
    /// <summary>
    /// 执行 SE.Redis 操作的类
    /// </summary>
    class Program
    {
        /// <summary>
        /// 执行必要的先决条件
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {

            // Connect Redis
            var _cache = Program.Connect();

            // 存储10,000个 SET
            string prefix = "user";
            StringBuilder keys = new StringBuilder();
            for (int i = 0; i < 10000; i++)
            {
                keys.Append(" " + prefix + i);
                _cache.SetAdd(prefix + i, i);
            }

            var keyList = new RedisKey[10000];
            // 生成 key 数组
            for (int i = 0; i < 10000; i++)
            {
                var key = new RedisKey();
                key = prefix + i;
                keyList.SetValue(key, i);
            }

            var startTime = DateTime.Now;
            // 执行 SUNION
            var values = _cache.SetCombine(SetOperation.Union, keyList);

            var endTime = DateTime.Now;
            TimeSpan diff = endTime.Subtract(startTime);

            Console.WriteLine("total time taken to read 10k keys = " + diff);
            Console.Read();

            //TODO: 根据需要更改,以读取返回的 Set 值而不是字符串
            foreach (var value in values)
            {
                Console.WriteLine(value.ToString());
            }

            endTime = DateTime.Now;
            diff = endTime.Subtract(startTime);

            Console.WriteLine("total time taken to read 10k keys = " + diff);
            Console.Read();

        }

        /// <summary>
        /// 连接到 Redis db
        /// </summary>
        /// <returns>返回 Redis db 的实例</returns>
        private static IDatabase Connect()
        {
            string redisConnection = "localhost:6379,ssl=false,allowAdmin=true,ConnectRetry=3,ConnectTimeout=5000,defaultDatabase=1";
            ConnectionMultiplexer connection = ConnectionMultiplexer.Connect(redisConnection);
            return connection.GetDatabase();
        }
    }
}

我希望这对寻找解决方案的 C# 开发人员有所帮助。感谢 SE.Redis 开发团队的 Mgravell 在 GitHub 上的建议帮助了我。有关更多讨论,请访问 如何通过单个调用传递 set 键列表获取多个 set

2017-04-16 02:57:58