2013-05-27 23 views
5

Đôi khi mất nhiều thời gian để mở kết nối với Redis. Có vẻ như nó phụ thuộc vào việc kết nối số lượng và có thể, cấu hình PC. Tôi chạy thử nghiệm cho 50 chủ đề trên hai máy trạm với CPU 4 nhân, và phải mất 70-100ms để mở kết nối, và trên 8-core workstation và 8-core staging server phải mất 1000-1500ms và đôi khi nhiều hơn nữa. Sự phụ thuộc kỳ lạ, nhưng nó có thể tái tạo được. Khi hồ bơi ứng dụng IIS khởi động lại, và tất cả các chuỗi đang cố gắng kết nối lại, nó gây ra một cái gì đó giống như thời gian chết của bộ nhớ cache. Những gì tôi phải thay đổi để có được thời gian kết nối hợp lý?Việc mở lại kết nối lại quá chậm

tôi sử dụng BookSleeve khách hàng, và đây là mẫu mã:

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

:) Tôi đã chỉnh sửa bài đăng gốc – MihaKuz

+0

Phiên bản chính xác của sách mà bạn đang sử dụng là gì? Điều này quan trọng, bởi vì lớp IO đã thay đổi khá đáng kể giữa các phiên bản. –

+0

1.3.37, phiên bản mới nhất từ ​​NuGet – MihaKuz

Trả lời

2

Hãy nhìn; chúng tôi có một vòng lặp ở đây:

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

nó là không rõ ràng với tôi rằng TryGetConnection được xử lý một cách chính xác tất cả các kịch bản ("mở cửa", vv), nhưng thẳng thắn mà nói, đó là một điểm tranh luận: nếu bạn đang đi để làm một vòng lặp chặt chẽ cho đến khi bạn nhận được một kết nối, bạn cũng có thể đơn giản hóa đáng kể. Điều đầu tiên bạn có thể làm là chờ về tác vụ (với thời gian chờ, rõ ràng), thay vì sử dụng vòng lặp nóng. Tổng quát:

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

Wait ở trên sử dụng thời gian chờ được chỉ định của kết nối và thực hiện một số cách đơn giản hóa ngoại lệ cho bạn.

Tuy nhiên, trong trường hợp cụ thể này, bạn có thể có thể chỉ cần sử dụng một cái gì đó như:

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

với:

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; 
    } 
} 

nơi config là một hỗn hợp của các giá trị; về cơ bản giống như:

myserver:6389,syncTimeout=1000 

chuỗi Cấu hình này cũng có thể phức tạp hơn, bao gồm nhiều máy chủ redis (master/slave vv), một tên dịch vụ (để sử dụng với sentinel), một khách hàng tên tuổi (để sử dụng với client list), v.v.

I nghi ngờ một số tính phức tạp trong phương pháp của bạn đang dẫn đến một số vòng lặp bổ sung vào lúc này. Xem nếu nó là bất kỳ đáng tin cậy hơn với ở trên.

Các vấn đề liên quan