2017-04-06 154 views
2

我正在使用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(); ?

回答

1

您的「連接」屬性是如何實現的?它是否在每次通話中創建與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