2017-06-14 40 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年。这就是说,我也有相对较好的重试经验,但我绝不会在生产中使用这种方法,因为它根本不可靠。