我使用Sidekiq (在Heroku和Puma上)异步发送电子邮件,并希望使用Redis来保存计数器和缓存模型。
RedisCloud的免费计划包括30个连接到Redis。我不清楚如何管理:
Sidekiq客户端大小配置如下:
Sidekiq.configure_client do |config|
config.redis = {url: ENV["REDISCLOUD_URL"], size: 3}
end如果我正确地理解了这一点,Puma就会分叉多个进程,在我的情况下,这将导致:
2 (Puma Workers) * 3 (size) * 1 (Web Dyno) = 6 connections to redis used to push jobs.侧基服务器
由于Sidekiq采用2个连接(或版本4中的5个连接),设置10的并发性将默认为服务器大小为12或15。
如果我想使用所有剩余的可用连接(30-6= 24),我可以设置:
Sidekiq.configure_client do |config|
config.redis = { size: 19 }
endredis连接的总数将为19 +5 (Sidekiq 4) = 24,使用默认的25将是可以的。正如Mike所指出的,并发性不能超过(服务器池大小- 2) * 2。
现在,它开始让我感到困惑的地方是使用Redis离开Sidekiq。
# initializers/redis.rb
$redis = Redis.new(:url => uri)每当我在模型或控制器中使用Redis时,我都会这样调用:
$redis.hincrby("mycounter", "key", 1)据我所知,当调用$redis.whateverFunction时,所有美洲狮线程都在单个Redis连接上彼此等待。
在这个答案What is the best way to use Redis in a Multi-threaded Rails environment? (Puma / Sidekiq)中,推荐的方法是使用与Sidekiq https://github.com/mperham/sidekiq/wiki/Advanced-Options#connection-pooling相关的connection_pool gem
require 'connection_pool'
$redis = ConnectionPool.new(size: 10) { Redis.new }如果我理解正确的话,$redis.whateverFunction将有自己的连接池10,并拥有自己的连接工作人员池(现在将设置新的20个redis连接(30个(可用总数)- 10 (redis模型连接) ),而sidekiq客户端和服务器的大小需要更改。
如何确定模型/控制器redis连接所需的连接池(此处为10)的大小?既然Redis是单线程的,那么增加连接池实际上是如何提高redis操作性能的?
任何有关这方面的想法都会有很大帮助。谢谢!
发布于 2016-01-14 18:47:40
Redis是单线程的,但使用纯C编写,在内部使用事件循环并异步处理连接,因此如果请求数量相同,连接计数不会对其产生很大影响。它能够以比应用程序生成请求更快的速度处理请求,因为网络延迟、ruby比编译和优化的C慢等等,所以您不需要担心它是单线程的。
增加连接数量对来自不同线程的并发请求是有益的,因为不需要等待通过网络传递响应来解锁连接,而且ruby可以执行并行IOs。
此外,当连接签出时间变得比您预期的还要糟糕时,您还可以判断池是否太小,而相应的线程/工作人员正在等待它,因此对代码进行基准测试,并仔细查看您的实际使用和行为模式。
另一方面,我建议不要使用所有的连接计数限制,有时您可能需要这些额外的连接。例如:
https://stackoverflow.com/questions/34795641
复制相似问题