Per*_*son 5 c# redis stackexchange.redis
我有一个 redis db,它有数千个键,我目前正在运行以下行来获取所有键:
string[] keysArr = keys.Select(key => (string)key).ToArray();
Run Code Online (Sandbox Code Playgroud)
但是因为我有很多钥匙,这需要很长时间。我想限制正在读取的键数。所以我试图运行一个执行命令,我一次得到 100 个键:
var keys = Redis.Connection.GetDatabase(dbNum).Execute("scan", 0, "count", 100);
Run Code Online (Sandbox Code Playgroud)
此命令成功运行该命令,但是无法访问该值,因为它是私有的,并且即使 RedisResult 类为其提供了显式转换,也无法转换它:
public static explicit operator string[] (RedisResult result);
Run Code Online (Sandbox Code Playgroud)
有什么想法可以一次从 redis 获取 x 数量的密钥吗?
谢谢
SE.Redis.Keys()在IServerAPI上有一个方法,它完全封装了SCAN. 如果可能的话,就用这个方法,一次消耗100条数据。编写批处理函数通常很容易,即
ExecuteInBatches(server.Keys(), 100, batch => DoSomething(batch));
Run Code Online (Sandbox Code Playgroud)
和:
public void ExecuteInBatches<T>(IEnumerable<T> source, int batchSize,
Action<List<T>> action)
{
List<T> batch = new List<T>();
foreach(var item in source) {
batch.Add(item);
if(batch.Count == batchSize) {
action(batch);
batch = new List<T>(); // in case the callback stores it
}
}
if (batch.Count != 0) {
action(batch); // any leftovers
}
}
Run Code Online (Sandbox Code Playgroud)
枚举器将担心推进光标。
您可以使用Execute,但是:这是很多工作!此外,SCAN不保证每页将返回多少;它可以是零 - 它可以是您要求的 3 倍。它只是......指导。
顺便说一下,转换失败的原因是因为SCAN 不返回a string[]- 它返回一个包含两个项目的数组,其中第一个是“下一个”光标,第二个是键。所以也许:
var arr = (RedisResult[])server.Execute("scan", 0);
var nextCursor = (int)arr[0];
var keys = (RedisKey[])arr[1];
Run Code Online (Sandbox Code Playgroud)
但是,这一切正在做的是重新实施IServer.Keys,硬盘的方式(和显著较低的效率-ServerResult是不是存储数据的理想方式,它只是必要的情况下Execute和ScriptEvaluate)。
我将使用 Microsoft此处概述的 .Take() 方法。
从序列开头返回指定数量的连续元素。
它看起来像这样:
//limit to 100
var keysArr = keys.Select(key => (string)key).Take(100).ToArray();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4555 次 |
| 最近记录: |