2013-05-27 52 views
5

Bazen Redis'e bağlantı açmak için çok uzun zaman alıyor. İplik sayısının ve belki de PC konfigürasyonunun bağlanmasına bağlı gibi görünüyor. 4 çekirdekli CPU'lu iki iş istasyonunda 50 iş parçacığı için test çalıştırıyorum ve bağlantıyı açmak için 70-100 ms sürüyor ve 8 çekirdekli iş istasyonu ve 8 çekirdekli evreleme sunucusunda 1000-1500ms ve bazen çok daha fazlası vardı. Garip bağımlılık, ama 'yeniden üretilebilir. IIS uygulama havuzu yeniden başlatıldığında ve tüm iş parçacıkları yeniden bağlanmaya çalışırken, önbellek kesintisi gibi bir soruna neden olur. Makul bağlantı süresi almak için neyi değiştirmek zorundayım?Açma redis bağlantısı çok yavaş

Burada BookSleeve istemcisi kullanmak ve kodu bir örnektir:

static void Main(string[] args) 
{ 
    for (var i = 0; i < threadCount; i++) 
     threads.Add(new Thread(RunThread)); 

    foreach (var thread in threads) 
     thread.Start(); 

    foreach (var thread in threads) 
     thread.Join(); 
} 

static void RunThread() 
{ 
    var connection = TryGetConnection(); 
    while (connection == null) 
    { 
     connection = TryGetConnection(); 
    } 
} 

static RedisConnection TryGetConnection() 
{ 
    var connection = currentConnection; 
    if ((connection != null) && (connection.State == RedisConnectionBase.ConnectionState.Open)) 
     return connection; 

    lock (syncRoot) 
    { 
     if ((currentConnection != null) && (currentConnection.State == RedisConnectionBase.ConnectionState.Open)) 
      return currentConnection; 

     if ((connectionTask != null) && connectionTask.IsCompleted) 
      connectionTask = null; 

     if (connectionTask == null) 
     { 
      if ((currentConnection != null) && (currentConnection.State == RedisConnectionBase.ConnectionState.Closed)) 
      { 
       currentConnection.Dispose(); 
       currentConnection = null; 
      } 

      if (currentConnection == null) 
      { 
       currentConnection = new RedisConnection(
        serverAddress, 
        serverPort, 
        ioTimeout: (int) operationTimeout.TotalMilliseconds, 
        syncTimeout: (int) operationTimeout.TotalMilliseconds); 
      } 

      if (currentConnection.State == RedisConnectionBase.ConnectionState.New) 
       currentConnection.Open(); 
     } 
    } 
    return null; 
} 
+0

:) Düzenlediklerim için orijinal yazı – MihaKuz

+0

Kullanım kılavuzunuz nedir? Bu önemlidir, çünkü IO tabakası sürümler arasında oldukça değişmiştir. –

+0

1.3.37, NuGet'in en son sürümü olan NuGet – MihaKuz

cevap

2

atalım; burada bir döngü var: bu bana belli değilolduğunu

var connection = TryGetConnection(); 
while (connection == null) 
{ 
    connection = TryGetConnection(); 
} 

TryGetConnection doğru tüm senaryolar işlediğini ("açılış", vb), ama açıkçası, bu tartışmalı bir nokta şudur: gidiyoruz Bir bağlantı elde edene kadar sıkı bir döngü yapın, önemli ölçüde basitleştirebilirsiniz. Yapabileceğiniz ilk şey, bir sıcak döngü kullanmak yerine beklemede (zaman aşımıyla) beklemek olacaktır. Genelleme:

var task = connection.Open(); 
connection.Wait(task); 

yukarıda Wait bağlantının belirtilen zaman aşımı kullanır ve sizin için istisnalar basitleştirmek için bazı iş yapar. ile

var connection = TryGetConnection(); 
// no loop here 

:

Ancak bu belirli durumda, muhtemelen gibi bir şey kullanabilirsiniz config değerlerinin bir bileşimidir

static RedisConnection TryGetConnection() 
{ 
    var connection = currentConnection; 
    if ((connection != null) && (connection.State == RedisConnectionBase.ConnectionState.Open)) 
     return connection; 

    lock (syncRoot) 
    { // double-checked 
     if ((connection != null) && (connection.State == RedisConnectionBase.ConnectionState.Open)) 
      return connection; 

     connection = ConnectionUtils.Connect(config); 
     return connection; 
    } 
} 

; Temelde böyle bir şey: Bu yapılandırma dizesi aynı zamanda birden fazla Redis sunucularına dahil olmak üzere daha karmaşık olabilir

myserver:6389,syncTimeout=1000 

(Master/Slave vb), (sentinel ile kullanım için) bir hizmet adı, kullanım için bir istemci adı ile (client list), vb.

Ben şüpheli metodunuzdaki karmaşıklığın bir kısmı şu anda bazı ekstra döngülere yol açmaktadır. Yukarıdakilerle daha güvenilir olup olmadığına bakın.