在c#异步中使用Redis缓存后CPU使用率高

问题描述:

我正在使用https://github.com/StackExchange/StackExchange.Redis。 (StackExchange.Redis.StrongName.1.2.1)在c#异步中使用Redis缓存后CPU使用率高

我有一个这样的异步函数导致CPU到100%,并开始获取超时错误后4-5分钟服务400个请求

public async Task<T> GetOrSetAsync<T>(string cacheKey, Func<Task<T>> getItemCallback) where T : class 
     { 
      T item = null; 
      IDatabase cache = Connection.GetDatabase(); 
      var cacheValue = await cache.StringGetAsync(cacheKey); 
      if (cacheValue.IsNull) 
      { 
       item = await getItemCallback(); 
       await cache.StringSetAsync(cacheKey, JsonConvert.SerializeObject(item)); 
      } 
      else 
      { 
       item = await Task.Factory.StartNew(() => JsonConvert.DeserializeObject<T>(cacheValue)); 
      } 
      return item; 
     } 

后如果我停止使用redis缓存并从数据库返回直接值,我可以在2分20秒内执行1300次请求。 CPU仍然能够完成高负载。

public async Task<T> GetOrSetAsync<T>(string cacheKey, Func<Task<T>> getItemCallback) where T : class 
     { 
      return await getItemCallback(); 
     } 

如果我只是修改下面的函数getDatabase并且什么都不做。它会导致CPU在2分钟内立即转到100%并在200次请求后卡住,这是因为CPU很高。

public async Task<T> GetOrSetAsync<T>(string cacheKey, Func<Task<T>> getItemCallback) where T : class 
     { 
      IDatabase cache = Connection.GetDatabase(); 
      return await getItemCallback(); 
     } 

但问题是,为什么CPU占用率只与另外的

增加

缓存了IDatabase = Connection.GetDatabase(); ?

您的“连接”属性是如何实现的?它是否在每次通话中创建与Redis的新连接?如果是这样,那将不被推荐。你应该在你的通话*享一个连接。

private static Lazy<ConnectionMultiplexer> lazyConnection = new Lazy<ConnectionMultiplexer>(() => 
{ 
    return ConnectionMultiplexer.Connect("<your connection string here>"); 
}); 

public static ConnectionMultiplexer Connection 
{ 
    get 
    { 
     return lazyConnection.Value; 
    } 
} 
+0

尽管lazy init使用它不是静态的,但包含它的类是instanceperlifetime scope,我将其更改为singleton。它的工作速度与本地缓存一样快:) – Shiv