예제 #1
0
        public virtual RedisClient CreateRedisClient(RedisEndpoint config, bool readWrite)
        {
            var client = RedisConfig.ClientFactory(config);

            if (readWrite && RedisConfig.VerifyMasterConnections)
            {
                var role = client.GetServerRole();
                if (role != RedisServerRole.Master)
                {
                    log.Error("Redis Master Host '{0}' is {1}. Resetting allHosts...".Fmt(config.GetHostString(), role));
                    var newMasters = new List<RedisEndpoint>();
                    var newSlaves = new List<RedisEndpoint>();
                    RedisClient masterClient = null;
                    foreach (var hostConfig in allHosts)
                    {
                        try
                        {
                            var testClient = new RedisClient(hostConfig) {
                                ConnectTimeout = RedisConfig.HostLookupTimeout
                            };
                            var testRole = testClient.GetServerRole();
                            switch (testRole)
                            {
                                case RedisServerRole.Master:
                                    newMasters.Add(hostConfig);
                                    if (masterClient == null)
                                        masterClient = testClient;
                                    break;
                                case RedisServerRole.Slave:
                                    newSlaves.Add(hostConfig);
                                    break;
                            }

                        }
                        catch { /* skip */ }
                    }

                    if (masterClient == null)
                    {
                        var errorMsg = "No master found in: " + string.Join(", ", allHosts.Map(x => x.GetHostString()));
                        log.Error(errorMsg);
                        throw new Exception(errorMsg);
                    }

                    ResetMasters(newMasters);
                    ResetSlaves(newSlaves);
                    return masterClient;
                }
            }

            return client;
        }
예제 #2
0
        public virtual RedisClient CreateRedisClient(RedisEndpoint config, bool master)
        {
            var client = ClientFactory(config);

            if (master)
            {
                var role = RedisServerRole.Unknown;
                try
                {
                    role = client.GetServerRole();
                    if (role == RedisServerRole.Master)
                    {
                        lastValidMasterFromSentinelAt = DateTime.UtcNow;
                        return(client);
                    }
                }
                catch (Exception ex)
                {
                    Interlocked.Increment(ref RedisState.TotalInvalidMasters);

                    if (client.GetHostString() == lastInvalidMasterHost)
                    {
                        lock (oLock)
                        {
                            if (DateTime.UtcNow - lastValidMasterFromSentinelAt > sentinel.WaitBeforeForcingMasterFailover)
                            {
                                lastInvalidMasterHost         = null;
                                lastValidMasterFromSentinelAt = DateTime.UtcNow;

                                log.Error("Valid master was not found at '{0}' within '{1}'. Sending SENTINEL failover...".Fmt(
                                              client.GetHostString(), sentinel.WaitBeforeForcingMasterFailover), ex);

                                Interlocked.Increment(ref RedisState.TotalForcedMasterFailovers);

                                sentinel.ForceMasterFailover();
                                Thread.Sleep(sentinel.WaitBetweenSentinelLookups);
                                role = client.GetServerRole();
                            }
                        }
                    }
                    else
                    {
                        lastInvalidMasterHost = client.GetHostString();
                    }
                }

                if (role != RedisServerRole.Master)
                {
                    try
                    {
                        var stopwatch = Stopwatch.StartNew();
                        while (true)
                        {
                            try
                            {
                                var masterConfig = sentinel.GetMaster();
                                var masterClient = ClientFactory(masterConfig);
                                masterClient.ConnectTimeout = sentinel.SentinelWorkerConnectTimeoutMs;

                                var masterRole = masterClient.GetServerRole();
                                if (masterRole == RedisServerRole.Master)
                                {
                                    lastValidMasterFromSentinelAt = DateTime.UtcNow;
                                    return(masterClient);
                                }
                                else
                                {
                                    Interlocked.Increment(ref RedisState.TotalInvalidMasters);
                                }
                            }
                            catch { /* Ignore errors until MaxWait */ }

                            if (stopwatch.Elapsed > sentinel.MaxWaitBetweenSentinelLookups)
                            {
                                throw new TimeoutException("Max Wait Between Sentinel Lookups Elapsed: {0}"
                                                           .Fmt(sentinel.MaxWaitBetweenSentinelLookups.ToString()));
                            }

                            Thread.Sleep(sentinel.WaitBetweenSentinelLookups);
                        }
                    }
                    catch (Exception ex)
                    {
                        log.Error("Redis Master Host '{0}' is {1}. Resetting allHosts...".Fmt(config.GetHostString(), role), ex);

                        var         newMasters   = new List <RedisEndpoint>();
                        var         newSlaves    = new List <RedisEndpoint>();
                        RedisClient masterClient = null;
                        foreach (var hostConfig in allHosts)
                        {
                            try
                            {
                                var testClient = ClientFactory(hostConfig);
                                testClient.ConnectTimeout = RedisConfig.HostLookupTimeoutMs;
                                var testRole = testClient.GetServerRole();
                                switch (testRole)
                                {
                                case RedisServerRole.Master:
                                    newMasters.Add(hostConfig);
                                    if (masterClient == null)
                                    {
                                        masterClient = testClient;
                                    }
                                    break;

                                case RedisServerRole.Slave:
                                    newSlaves.Add(hostConfig);
                                    break;
                                }
                            }
                            catch { /* skip past invalid master connections */ }
                        }

                        if (masterClient == null)
                        {
                            Interlocked.Increment(ref RedisState.TotalNoMastersFound);
                            var errorMsg = "No master found in: " + string.Join(", ", allHosts.Map(x => x.GetHostString()));
                            log.Error(errorMsg);
                            throw new Exception(errorMsg);
                        }

                        ResetMasters(newMasters);
                        ResetSlaves(newSlaves);
                        return(masterClient);
                    }
                }
            }

            return(client);
        }
        public virtual RedisClient CreateRedisClient(RedisEndpoint config, bool master)
        {
            var client = ClientFactory(config);
            if (master)
            {
                var role = RedisServerRole.Unknown;
                try
                {
                    role = client.GetServerRole();
                    if (role == RedisServerRole.Master)
                    {
                        lastValidMasterFromSentinelAt = DateTime.UtcNow;
                        return client;
                    }
                }
                catch (Exception ex)
                {
                    Interlocked.Increment(ref RedisState.TotalInvalidMasters);

                    if (client.GetHostString() == lastInvalidMasterHost)
                    {
                        lock (oLock)
                        {
                            if (DateTime.UtcNow - lastValidMasterFromSentinelAt > sentinel.WaitBeforeForcingMasterFailover)
                            {
                                lastInvalidMasterHost = null;
                                lastValidMasterFromSentinelAt = DateTime.UtcNow;

                                log.Error("Valid master was not found at '{0}' within '{1}'. Sending SENTINEL failover...".Fmt(
                                    client.GetHostString(), sentinel.WaitBeforeForcingMasterFailover), ex);

                                Interlocked.Increment(ref RedisState.TotalForcedMasterFailovers);

                                sentinel.ForceMasterFailover();
                                TaskUtils.Sleep(sentinel.WaitBetweenFailedHosts);
                                role = client.GetServerRole();
                            }
                        }
                    }
                    else
                    {
                        lastInvalidMasterHost = client.GetHostString();
                    }
                }

                if (role != RedisServerRole.Master && RedisConfig.VerifyMasterConnections)
                {
                    try
                    {
                        var stopwatch = Stopwatch.StartNew();
                        while (true)
                        {
                            try
                            {
                                var masterConfig = sentinel.GetMaster();
                                var masterClient = ClientFactory(masterConfig);
                                masterClient.ConnectTimeout = sentinel.SentinelWorkerConnectTimeoutMs;

                                var masterRole = masterClient.GetServerRole();
                                if (masterRole == RedisServerRole.Master)
                                {
                                    lastValidMasterFromSentinelAt = DateTime.UtcNow;
                                    return masterClient;
                                }
                                else
                                {
                                    Interlocked.Increment(ref RedisState.TotalInvalidMasters);
                                }
                            }
                            catch { /* Ignore errors until MaxWait */ }

                            if (stopwatch.Elapsed > sentinel.MaxWaitBetweenFailedHosts)
                                throw new TimeoutException("Max Wait Between Sentinel Lookups Elapsed: {0}"
                                    .Fmt(sentinel.MaxWaitBetweenFailedHosts.ToString()));

                            TaskUtils.Sleep(sentinel.WaitBetweenFailedHosts);
                        }
                    }
                    catch (Exception ex)
                    {
                        log.Error("Redis Master Host '{0}' is {1}. Resetting allHosts...".Fmt(config.GetHostString(), role), ex);

                        var newMasters = new List<RedisEndpoint>();
                        var newSlaves = new List<RedisEndpoint>();
                        RedisClient masterClient = null;
                        foreach (var hostConfig in allHosts)
                        {
                            try
                            {
                                var testClient = ClientFactory(hostConfig);
                                testClient.ConnectTimeout = RedisConfig.HostLookupTimeoutMs;
                                var testRole = testClient.GetServerRole();
                                switch (testRole)
                                {
                                    case RedisServerRole.Master:
                                        newMasters.Add(hostConfig);
                                        if (masterClient == null)
                                            masterClient = testClient;
                                        break;
                                    case RedisServerRole.Slave:
                                        newSlaves.Add(hostConfig);
                                        break;
                                }

                            }
                            catch { /* skip past invalid master connections */ }
                        }

                        if (masterClient == null)
                        {
                            Interlocked.Increment(ref RedisState.TotalNoMastersFound);
                            var errorMsg = "No master found in: " + string.Join(", ", allHosts.Map(x => x.GetHostString()));
                            log.Error(errorMsg);
                            throw new Exception(errorMsg);
                        }

                        ResetMasters(newMasters);
                        ResetSlaves(newSlaves);
                        return masterClient;
                    }
                }
            }

            return client;
        }
        public virtual RedisClient CreateRedisClient(RedisEndpoint config, bool master)
        {
            var client = ClientFactory(config);

            if (master && RedisConfig.VerifyMasterConnections)
            {
                var role = client.GetServerRole();
                if (role != RedisServerRole.Master)
                {
                    Interlocked.Increment(ref RedisState.TotalInvalidMasters);
                    log.Error("Redis Master Host '{0}' is {1}. Resetting allHosts...".Fmt(config.GetHostString(), role));
                    var         newMasters   = new List <RedisEndpoint>();
                    var         newSlaves    = new List <RedisEndpoint>();
                    RedisClient masterClient = null;
                    foreach (var hostConfig in allHosts)
                    {
                        try
                        {
                            var testClient = ClientFactory(hostConfig);
                            testClient.ConnectTimeout = RedisConfig.HostLookupTimeoutMs;
                            var testRole = testClient.GetServerRole();
                            switch (testRole)
                            {
                            case RedisServerRole.Master:
                                newMasters.Add(hostConfig);
                                if (masterClient == null)
                                {
                                    masterClient = testClient;
                                }
                                break;

                            case RedisServerRole.Slave:
                                newSlaves.Add(hostConfig);
                                break;
                            }
                        }
                        catch { /* skip */ }
                    }

                    if (masterClient == null)
                    {
                        Interlocked.Increment(ref RedisState.TotalNoMastersFound);
                        var errorMsg = "No master found in: " + string.Join(", ", allHosts.Map(x => x.GetHostString()));
                        log.Error(errorMsg);
                        throw new Exception(errorMsg);
                    }

                    ResetMasters(newMasters);
                    ResetSlaves(newSlaves);
                    return(masterClient);
                }
            }

            return(client);
        }
        public virtual RedisClient CreateRedisClient(RedisEndpoint config, bool readWrite)
        {
            var client = RedisConfig.ClientFactory(config);

            if (readWrite)
            {
                var role = client.GetServerRole();
                if (role != RedisServerRole.Master)
                {
                    try
                    {
                        var stopwatch = Stopwatch.StartNew();
                        while (true)
                        {
                            var masterConfig = sentinel.GetMaster();
                            var master = RedisConfig.ClientFactory(masterConfig);
                            var masterRole = master.GetServerRole();
                            if (masterRole == RedisServerRole.Master)
                                return master;

                            if (stopwatch.Elapsed > sentinel.MaxWaitBetweenSentinelLookups)
                                throw new TimeoutException("Max Wait Between Sentinel Lookups Elapsed: {0}"
                                    .Fmt(sentinel.MaxWaitBetweenSentinelLookups.ToString()));

                            Thread.Sleep(sentinel.WaitBetweenSentinelLookups);
                        }
                    }
                    catch (Exception ex)
                    {
                        log.Error("Redis Master Host '{0}' is {1}. Resetting allHosts...".Fmt(config.GetHostString(), role), ex);
                        var newMasters = new List<RedisEndpoint>();
                        var newSlaves = new List<RedisEndpoint>();
                        RedisClient masterClient = null;
                        foreach (var hostConfig in allHosts)
                        {
                            try
                            {
                                var testClient = new RedisClient(hostConfig)
                                {
                                    ConnectTimeout = RedisConfig.HostLookupTimeout
                                };
                                var testRole = testClient.GetServerRole();
                                switch (testRole)
                                {
                                    case RedisServerRole.Master:
                                        newMasters.Add(hostConfig);
                                        if (masterClient == null)
                                            masterClient = testClient;
                                        break;
                                    case RedisServerRole.Slave:
                                        newSlaves.Add(hostConfig);
                                        break;
                                }

                            }
                            catch { /* skip */ }
                        }

                        if (masterClient == null)
                        {
                            var errorMsg = "No master found in: " + string.Join(", ", allHosts.Map(x => x.GetHostString()));
                            log.Error(errorMsg);
                            throw new Exception(errorMsg);
                        }

                        ResetMasters(newMasters);
                        ResetSlaves(newSlaves);
                        return masterClient;
                    }
                }
            }

            return client;
        }