StackExchange.Redis for 循环流水线化?

StackExchange.Redis pipelining on for-loop?

前言

我有一个简单的界面,它假定键之间存在依赖关系。 它的两个方法是:

  1. Remove(string key) - 从缓存中删除单个键。
  2. RemoveDependentsOf(string baseKey) - 删除 baseKeybaseKey.

    的所有家属
    1. baseKey 的家属在 Redis set 中指定。

    2. 因此,为了删除 baseKey 的所有依赖项,我必须读取 baseKey 的集合,然后循环删除它们中的每一个。


问题

我阅读了 StackExchange.Redis 文档,因此我了解了他们传奇的流水线支持,根据他们的文档,以下代码应该非常有效。

但是,我似乎无法理解库如何将 KeyDelete 命令 作为方法 returns 是否删除密钥的布尔值 .

所以在执行第二个 KeyDelete 命令之前,第一个命令应该已经发送并收到了它的响应(效率不高)。


public void Remove(string key)
{
    _redis.KeyDelete(key);
}

public void RemoveDependentsOf(string key)
{
    Remove(key);

    var setKey = GetDependencySetKey(key);
    RedisValue[] dependents = _redis.SetMembers(setKey);
    foreach (var dependentKey in dependents)
    {
        RemoveDependentsOf(dependentKey);
    }

    // This is the way to remove the whole set
    _redis.KeyExpire(setKey, TimeSpan.Zero);
}

您正在使用同步方法,虽然您没有明确依赖 KeyDelete 操作的结果,但 StackExchange.Redis 不知道您没有使用该结果。因此,您无法获得图书馆提供的任何流水线优势。

文档明确指出了您可以使用流水线支持的两种方式;如果您想知道何时完成,请使用 Async 方法并执行 Task.WhenAll 或使用 Fire and Forget。您可以通过将 CommandFlags.FireAndForget 传递给您的命令来明确告诉库您想要执行此操作,例如

_redis.KeyDelete(key, CommandFlags.FireAndForget)

请注意,这会导致调用返回默认结果,而不是实际结果。鉴于您无论如何都无视这些结果,您应该没问题!