【问题标题】:StackExchange.Redis pipelining on for-loop?StackExchange.Redis 在 for 循环上流水线?
【发布时间】:2018-03-12 11:17:49
【问题描述】:

前言

我有一个简单的接口,它假设键之间的依赖关系。 它的两种方法是:

  1. Remove(string key) - 从缓存中删除单个键。
  2. RemoveDependentsOf(string baseKey) - 删除 baseKeybaseKey 的所有依赖项。

    1. baseKey 的依赖项在 Redis set 中指定。

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


问题

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

但是,我似乎无法理解库如何通过管道传输KeyDelete 命令因为无论密钥是否被删除,该方法都会返回一个布尔值

所以在执行第二个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);
}

【问题讨论】:

    标签: c# .net redis stackexchange.redis


    【解决方案1】:

    您正在使用同步方法,尽管您没有显式依赖 KeyDelete 操作的结果,但 StackExchange.Redis 并不知道您没有使用结果。因此,您不会获得库提供的任何流水线优势。

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

    _redis.KeyDelete(key, CommandFlags.FireAndForget)

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

    【讨论】:

      猜你喜欢
      • 2015-03-03
      • 2015-09-25
      • 2015-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-23
      相关资源
      最近更新 更多