【发布时间】:2021-04-02 18:50:03
【问题描述】:
我们目前在 .NET Core 微服务中使用 LazyCache,但想利用分布式缓存,因此我们正在寻找 Redis 的解决方案。
我正在研究缓存未命中情况。假设我们有 100 个请求(在同一台服务器上)进来,都需要获取相同的数据。我们有一个对数据库的后台调用,但它是一个复杂的查询,所以我们使用 LazyCache 缓存了结果。如果数据不在缓存中,则 LazyCache 会调用数据库以获取数据并锁定所有其他请求者,直到有响应为止。所以数据库调用只进行一次。
这是 LazyCache 相对于 Microsoft 的传统 MemoryCache 的优势。这篇文章很好地解释了这个问题: https://blog.novanet.no/asp-net-core-memory-cache-is-get-or-create-thread-safe/
现在我们想对 Redis 做同样的事情,但我想知道这是否可能?我们使用 StackExchange.Redis 客户端。
实际上我们想要这样做:
public async Task<string> GetOrAddAsync(string key, Func<Task<string>> dataFactory)
{
var result = await cache.GetStringAsync(key);
if(result != null)
{
return result;
}
result = await dataFactory();
await cache.SetStringAsync(key, result);
return result;
}
假设我们同时有 100 个请求。在一个线程调用 SetStringAsync 之前,所有其他线程都将调用 dataFactory();也可以获取数据。这可能是一个巨大的性能问题。我想看到的是,只有该键的第一个线程调用 dataFactory,但所有其他线程都被锁定在那里并等待第一个请求完成并设置 SetStringAsync。这与 LazyCache 中的行为相同。
这对我来说似乎是一个很明显的场景,所以我很惊讶我在网上找不到任何关于这个的信息?有谁知道 StackExchange.Redis 客户端可以做到这一点,还是我必须自己实现这个锁定?
【问题讨论】:
标签: multithreading redis stackexchange.redis memorycache lazycache