2017-06-14 71 views
2

我有一個包含3個節點的Redis集羣; 1是主人,另外2人是奴隸,持有主人的複製品。當我殺死主實例時,Redis Sentinel促使另一個節點成爲主節點,它開始接受寫操作。在集羣中選出新主節點時恢復連接

在我的測試中,我發現,一旦新主人是促進,在Redis的第一操作與SE.Redis失敗:

StackExchange.Redis.RedisConnectionException:SocketFailure上GET --->系統.IO.IOException:無法從傳輸連接讀取數據:現有連接被遠程主機強制關閉。 ---> System.Net.Sockets.SocketException:一個現有的連接 被強行通過遠程主機

爲了避免它關閉時,我已經如下實現的重試邏輯。有沒有更好的選擇?

private RedisValue RedisGet(string key) 
{ 
    return RedisOperation(() => 
    { 
     RedisKey redisKey = key; 
     RedisValue redisValue = connection.StringGet(redisKey); 
     return (redisValue); 
    }); 
} 

private T RedisOperation<T>(Func<T> act) 
{ 
    int timeToSleepBeforeRetryInMiliseconds = 20; 
    DateTime startTime = DateTime.Now; 

    while (true) 
    { 
     try 
     { 
      return act(); 
     } 
     catch (Exception e) 
     { 
      Debug.WriteLine("Failed to perform REDIS OP"); 

      TimeSpan passedTime = DateTime.Now - startTime; 
      if (this.retryTimeout < passedTime) 
      { 
       Debug.WriteLine("ABORTING re-try to REDIS OP"); 
       throw; 
      } 
      else 
      { 
       int remainingTimeout = (int)(this.retryTimeout.TotalMilliseconds - passedTime.TotalMilliseconds); 
       // if remaining time is less than 1 sec than wait only for that much time and than give a last try 
       if (remainingTimeout < timeToSleepBeforeRetryInMiliseconds) 
       { 
        timeToSleepBeforeRetryInMiliseconds = remainingTimeout; 
       } 
      } 

      Debug.WriteLine("Sleeping " + timeToSleepBeforeRetryInMiliseconds + " before next try"); 
      System.Threading.Thread.Sleep(timeToSleepBeforeRetryInMiliseconds); 
     } 
    } 
} 

回答

0

TLDR:不Stackexchange.Redis使用Sentinel哨兵支持仍然沒有在這個客戶端庫實現的。

查看https://github.com/StackExchange/StackExchange.Redis/labels/sentinel對於所有未解決的問題,還有一個相當不錯的公關開放了大約1年。這就是說,我也有相對較好的重試經驗,但我絕不會在生產中使用這種方法,因爲它根本不可靠。