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

问题描述:

我想在单次调用中使用键列表从Redis获取所有集合。根据文档,Redis提供了SSCAN命令,但由于我使用StackExchange.Redis作为Redis适配器,我猜这个命令在这个适配器中没有任何这样的方法。因此,有两件事我要找:如何使用某些命令或LUA脚本读取存储在Redis上的多个集合

  • 我期待着执行SSCAN使用LUA脚本,但没能找到在互联网上的任何这样的例子。任何人都可以分享如何使用多个SET键从LUA调用SSCAN。
  • 同样对于StackExchange.Redis,如果我在事务中执行多个SetMembers(),它是否类似于使用SSCAN()命令使用LUA脚本?

感谢

+1

'SCAN'命令被设计用于迭代而不会阻塞服务器。从一个阻塞的Lua脚本中使用它们,有点失败了。 –

+0

@ItamarHaber感谢您的建议,这是非常好的。但是我仍然坚持通过传递Set键列表来获取多个集合的挑战。有什么知识可以分享吗? – Riky

的C#示例代码来获得多套在一个单一的呼叫如下: 我使用StackExchange.Redis作为Redis的连接器:

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

namespace RedisGetMultipleKeys 
{ 
/// <summary> 
/// Class to perofrme operations on SE.Redis 
/// </summary> 
class Program 
{ 
    /// <summary> 
    /// Executes necessary pre-requisites 
    /// </summary> 
    /// <param name="args"></param> 
    static void Main(string[] args) 
    { 

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

     //Store 10k Sets 
     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]; 
     //Generate keys array 
     for (int i = 0; i < 10000; i++) 
     { 
      var key = new RedisKey(); 
      key = prefix + i; 
      keyList.SetValue(key, i); 
     } 

     var startTime = DateTime.Now; 
     //Perform 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: to be changed accordingly to read Set values returned other than String 
     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> 
    /// Connects to Redis db 
    /// </summary> 
    /// <returns>Returns an instance of 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 dev团队的Mgravell通过他的建议来帮助我。更多的讨论可以在这里找到GitHub How to get multiple sets by passing set key list in a single call

通过传递一组密钥列表获得在一次调用多套

我不清楚这里的具体要求,所以有可能是几种方法可以做到那。最简单的方法是调用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" 

注意:如果您的集合中有很多成员,然后无论采用何种方法,都将会“昂贵” - 重新考虑对此的需求。

+0

谢谢@Itamar,你的回答很好地满足了我现在的要求。当然,我会考虑你的建议,以限制Set成员的大小。目前,任何一组的成员不应超过5人。 – Riky