Redis StackExchange存储50万个类

时间:2018-11-01 14:09:28

标签: caching redis stackexchange.redis

我正在尝试将redis替换为基本上由Dictionary<id, class>组成的现有缓存系统。我大约有500k对象,正在使用MsgPackObjectSerializer。尝试检索整个数据集时遇到性能问题。

获取所有键需要几秒钟。

var keys = cacheClient.SearchKeys("ID:*").ToList();

并以这种方式使用GetAll方法:

cacheClient.GetAll<class>(keys).Values;

即使使用以下配置也会导致超时:

     var configOptions = new ConfigurationOptions();
     configOptions.EndPoints.Add("localhost:6379");
     configOptions.ClientName = "RedisClient";
     configOptions.ConnectTimeout = (int) TimeSpan.FromSeconds(5).TotalMilliseconds;
     configOptions.SyncTimeout = (int) TimeSpan.FromSeconds(5).TotalMilliseconds;
     configOptions.AbortOnConnectFail = false;
     configOptions.ResponseTimeout = (int) TimeSpan.FromSeconds(5).TotalMilliseconds;

我能够获得结果的唯一方法就是这种方式:

var fromRedis = new ConcurrentDictionary<id, class>();
keys.AsParallel().ForAll(k =>
{
    var div = cacheClient.Get<class>(k);
    if (div != null)
    {
        fromRedis.TryAdd(k, div)
    }
});

我觉得这不合适,而且很慢。

必须有一种我看不到的更好的方法。

更新: 这比keys.AsParallel调用快一点。仍然需要6秒钟...

     var insListScan = new List<Task<RedisValue[]>>();

     foreach (var batch in server.Keys(0, "InstrumentSK:*").Batch(1000))
     {
        var tran = cacheClient.Database.CreateTransaction();
        insListScan.Add(tran.StringGetAsync(batch.ToArray()));
        tran.Execute();
     }

1 个答案:

答案 0 :(得分:1)

现在您正在寻找SCAN命令。

因为StackExchange.Redis的目标是针对群集等场景,所以重要的是要知道哪些命令针对数据库(可以分布在多个节点上的逻辑数据库),以及哪些命令针对服务器。 SCAN命令针对单个服务器。

Here is,您可以从StackExchange.Redis文档中找到详细的说明以及使用SCAN的解决方法。