2017-04-06 21 views
2

私はhttps://github.com/StackExchange/StackExchange.Redisを使用しています。 (StackExchange.Redis.StrongName.1.2.1)c#asyncでRedisキャッシュを使用した後のCPU使用率が高い

私は100%にCPUを引き起こし、このような非同期機能を持っており、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; 
     } 

を務めた後、4〜5分後にタイムアウトエラーを取得を開始します私はredisキャッシュの使用を中止し、DBから直接値を返すと、2分20秒で1300要求のロードを実行することができます。 CPUは依然として負荷を完了することができます。

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

私はちょうどgetDatabaseの機能を変更して何もしません。 CPUが直ちに100%進んでしまい、2分で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

レイジー・イニシャルは静的ではありませんが、それを含むクラスはinstanceperlifetimeスコープでシングルトンに変更されました。それはローカルキャッシュとして高速に動作しています:) – Shiv