运行 通过 ServiceStack 的多个 Redis Sentinels

Running Multiple Redis Sentinels through ServiceStack

我正在开发一个通过 Servicestack 使用 Redis Sentinel 的项目。当项目建立时,最初的开发人员使用 Redis 来缓存和维护一系列为系统逻辑提供动力的队列。由于性能问题,我们计划启动一个新的 Redis Sentinel box,并将功能拆分为缓存在一台服务器上完成,排队在另一台服务器上完成。

我能够对本地实例进行一些小的更改,我不得不使用 RedisClient 和 PooledClient 将其拆分到两个服务器

container.Register<IRedisClientsManager>(c => new RedisManagerPool(redCon, poolConfig));
container.Register<PooledRedisClientManager>(c => new PooledRedisClientManager(redCon2Test));    

container.Register(c => c.Resolve<IRedisClientsManager>().GetClient());
container.Register(c => c.Resolve<PooledRedisClientManager>().GetClient());
 // REDIS CACHE
container.Register(c => c.Resolve<PooledRedisClientManager>().GetCacheClient());

// SESSION
container.Register(c => new SessionFactory(c.Resolve<ICacheClient>()));

// REDIS MQ
container.Register<IMessageService>(c => new RedisMqServer(c.Resolve<IRedisClientsManager>())
    {
        DisablePriorityQueues = true,
        DisablePublishingResponses = true,
        RetryCount = 2
    });
container.Register(q => q.Resolve<IMessageService>().MessageFactory);
this.RegisterHandlers(container.Resolve<IMessageService>() as RedisMqServer);

但问题是我没有在我使用的机器上设置 Redis Sentinel,当我尝试将 Sentinel 连接作为 PooledRedis 连接放入时,我在第二次启动时收到编译错误。它可以让我将其转换为 PooledRedisClientManager,但我不确定 Pooled 与 Sentinel 是否可以在一开始就很好地协同工作

if (useSentinel)
{
    var hosts = redCon.Split(',');
    var sentinel = new RedisSentinel(hosts, masterName)
       {
           RedisManagerFactory = CreateRedisManager,
           ScanForOtherSentinels = false,
           SentinelWorkerConnectTimeoutMs = 150,
           OnWorkerError = OnWorkerError,
           OnFailover = OnSentinelFailover,
           OnSentinelMessageReceived = (x, y) => Log.Debug($"MSG: {x} DETAIL: {y}")
       };
    container.Register(c => sentinel.Start());


    var hosts2 = redCon.Split(',');
    var sentinel2 = new RedisSentinel(hosts2, masterName)
       {
           RedisManagerFactory = CreatePooledRedisClientManager,
           ScanForOtherSentinels = false,
           SentinelWorkerConnectTimeoutMs = 150,
           OnWorkerError = OnWorkerError,
           OnFailover = OnSentinelFailover,
           OnSentinelMessageReceived = (x, y) => Log.Debug($"MSG: {x} DETAIL: {y}")
       };
    
    container.Register<PooledRedisClientManager>(c => sentinel2.Start());
} 

但老实说,我不确定这是否是尝试解决此问题的正确方法。我什至应该使用 Pooled 管理器吗?有没有好的方法可以在容器中注册两个不同的 Redis Sentinel 服务器并按照我尝试的方式拆分它们?

ServiceStack 仅允许每个 AppHost 执行 1 IRedisClientsManager,如果您使用 RedisSentinel,其 .Start() 方法将 return 预配置 PooledRedisClientManager使用 RedisSentinel 配置。

如果您希望RedisMqServer使用不同的 RedisSentinel 集群,您应该避免在 IOC 中重复 Redis 注册,直接使用 RedisMqServer 进行配置,例如:

container.Register<IMessageService>(c => new RedisMqServer(sentinel2.Start())
{
    DisablePriorityQueues = true,
    DisablePublishingResponses = true,
    RetryCount = 2
});

然而,通常 RedisSentinel requires 6 nodes 用于设置最小的高可用性配置似乎适得其反,将所需的基础设施资源加倍只是为了为 RedisMQ 提供一个单独的 Sentinel 集群,尤其是当负载为与处理消息的计算资源相比,使用 Redis 作为消息传输应该可以忽略不计。 MQ 吞吐量是多少?您应该验证 Redis 服务器上的负载是瓶颈,因为它不太可能。

我建议避免这种重复的复杂性,并使用不同的 RedisMQ 服务器,例如 Background MQ is an option where MQ Requests are executed in Memory in Background Threads, if you need to use a distributed MQ look at Rabbit MQ,它是专门为该任务构建的,并且比尝试管理 2 个单独的 RedisSentinel 集群配置需要更少的维护。