通过 ServiceStack 运行多个 Redis Sentinel
Posted
技术标签:
【中文标题】通过 ServiceStack 运行多个 Redis Sentinel【英文标题】:Running Multiple Redis Sentinels through ServiceStack 【发布时间】:2021-11-09 22:12:28 【问题描述】:我正在开发一个通过 Servicestack 使用 Redis Sentinel 的项目。项目成立时,最初的开发人员使用 Redis 进行缓存和维护一系列为系统逻辑提供动力的队列。由于性能问题,我们计划启动一个新的 Redis Sentinel 盒子,并在一台服务器上完成缓存和在另一台服务器上完成排队的功能。
我能够对本地实例进行一些小的更改,我必须使用 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 vs 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 服务器并按照我尝试的方式拆分它们?
【问题讨论】:
【参考方案1】:ServiceStack 仅允许每个 AppHost 1 个 IRedisClientsManager
实现,如果您使用 RedisSentinel,其 .Start()
方法将返回使用 RedisSentinel
配置的预配置 PooledRedisClientManager
。
如果您希望 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 是否是在后台线程中的内存中执行 MQ 请求的选项,如果您需要使用分布式 MQ,请查看 Rabbit MQ 其中专为该任务而构建,与尝试管理 2 个独立的 RedisSentinel 集群配置相比,所需的维护工作要少得多。
【讨论】:
谢谢,现在我正被推向两个 Sentinel 计划,所以一旦他们完成了环境的全部配置,我将尝试一下 RedisMqServer 直接配置的想法。我将此标记为已回答,但如果我以后有任何问题,可能会向您提出建议。 嘿,mythz,关于这个的小更新(和一个简短的问题),我们尝试将缓存服务转移到 Memcached,但我们的值经常超过 1 MB 的限制。是否有内置标志或任何能够轻松压缩进入缓存的内容的东西?我可以在 ServiceStack 上找到的所有压缩信息都针对通过网络传输的内容,而不是进出缓存的内容 @lasernick 不,redis 或缓存客户端没有内置压缩功能,您需要使用IRedisNativeClient 中的原始字节 [] API 自己执行解压缩。 好的,谢谢您的信息以上是关于通过 ServiceStack 运行多个 Redis Sentinel的主要内容,如果未能解决你的问题,请参考以下文章
Redis ServiceStack 使用事务时如何创建多个序列号
具有多个数据库服务器的 ServiceStack OrmLite