2017-04-06 2 views
2

https://github.com/StackExchange/StackExchange.Redis을 사용 중입니다. (StackExchange.Redis.StrongName.1.2.1)C# async에서 Redis 캐시를 사용한 후 높은 CPU 사용량

I는 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