2015-04-13 4 views
3

Мы используем C1 Azure Redis Cache в нашем приложении. В последнее время мы испытываем много тайм-аутов в операциях GET.Azure Redis Cache - пул ConnectionMultiplexer объектов

According to this article, одно из возможных решений заключается в реализации пула объектов ConnectionMultiplexer.

Другим возможным решением является использование пула ConnectionMultiplexer объектов в клиенте, и выбрать «наименее загруженный» ConnectionMultiplexer при отправке нового запроса. Это должно помешать единовременному тайм-ауту, вызвав другие запросы и таймауту.

Как будет реализована реализация пула объектов ConnectionMultiplexer с использованием C#?

Edit:

Related question that I asked recently.

+0

Вы выполнения каких-либо особенно длительные операции? Прежде чем переходить в пул, я хотел бы понять, если это латентность, насыщенность полосы пропускания, перегрузка сервера и т. Д. –

+1

@MarcGravell - мы почти решили все наши тайм-ауты, просто переписав часть нашего кода что приведет к повышению производительности. Это действительно не нужно, но мне все равно будет интересно увидеть фрагмент кода, который будет реализовывать пул ConnectionMultiplexers. –

+0

@JakubHolovsky вы можете поделиться опытом перезаписи, чтобы добиться лучшей производительности? – huangcd

ответ

1

Если вы используете StackExchange.Redis, в соответствии с этим github issue, вы можете использовать свойство TotalOutstanding на объекте мультиплексора соединения.

Вот реализация я придумал, что правильно работает:

public static int POOL_SIZE = 100; 
private static readonly Object lockPookRoundRobin = new Object(); 
private static Lazy<Context>[] lazyConnection = null; 

//Static initializer to be executed once on the first call 
private static void InitConnectionPool() 
{ 
    lock (lockPookRoundRobin) 
    { 
     if (lazyConnection == null) { 
      lazyConnection = new Lazy<Context>[POOL_SIZE]; 
     } 


     for (int i = 0; i < POOL_SIZE; i++){ 
      if (lazyConnection[i] == null) 
       lazyConnection[i] = new Lazy<Context>(() => new Context("YOUR_CONNECTION_STRING", new CachingFramework.Redis.Serializers.JsonSerializer())); 
     } 
    } 
} 

private static Context GetLeastLoadedConnection() 
{ 
    //choose the least loaded connection from the pool 
    var minValue = lazyConnection.Min((lazyCtx) => lazyCtx.Value.GetConnectionMultiplexer().GetCounters().TotalOutstanding); 
     var lazyContext = lazyConnection.Where((lazyCtx) => lazyCtx.Value.GetConnectionMultiplexer().GetCounters().TotalOutstanding == minValue).First(); 
    return lazyContext.Value; 
} 

private static Context Connection 
{ 
    get 
    { 
     lock (lockPookRoundRobin) 
     { 
      return GetLeastLoadedConnection(); 
     } 
    } 
} 

public RedisCacheService() 
{ 
    InitConnectionPool(); 
}