在群集中选择新主服务器时恢复连接

时间:2017-06-14 20:54:14

标签: redis stackexchange.redis

我有一个包含3个节点的Redis集群; 1是主设备,其他2是从设备,持有主设备的副本。当我杀死主实例时,Redis Sentinel将另一个节点提升为主节点,它开始接受写入。

在我的测试中,我注意到一旦新主人升级,Redis中SE.Redis的第一次操作失败了:

  

StackExchange.Redis.RedisConnectionException:GET上的SocketFailure   ---> System.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);
        }
    }
}

1 个答案:

答案 0 :(得分:0)

TLDR:不要将Sentinel与Stackexchange.Redis一起使用,因为此客户端库中仍未实现Sentinel支持。

有关所有未解决的问题,请参阅https://github.com/StackExchange/StackExchange.Redis/labels/sentinel,现在还有一个相当不错的PR开放约1年。

话虽如此,我在重试方面也有相对较好的经验,但我绝不会在生产中使用这种方法,因为它根本不可靠。