ste*_*cdn 5 ruby multithreading redis sidekiq ruby-on-rails-4
我正在使用Sidekiq(与Puma一起在Heroku上)异步发送电子邮件,并希望使用Redis保持计数器和缓存模型。
RedisCloud的免费计划包括与Redis的30个连接。我不清楚如何管理:
Sidekiq客户端大小配置如下:
Sidekiq.configure_client do |config|
config.redis = {url: ENV["REDISCLOUD_URL"], size: 3}
end
Run Code Online (Sandbox Code Playgroud)
如果我正确理解这一点,Puma会分叉多个过程(在我的情况下为2),这将导致:
2 (Puma Workers) * 3 (size) * 1 (Web Dyno) = 6 connections to redis used to push jobs.
Run Code Online (Sandbox Code Playgroud)
Sidekiq服务器
使用Sidekiq进行2个连接(或在版本4中为5个)时,将服务器大小默认设置为12或15并发设置为10。
如果我想使用所有剩余的可用连接(30-6 = 24),则可以设置:
Sidekiq.configure_client do |config|
config.redis = { size: 19 }
end
Run Code Online (Sandbox Code Playgroud)
Redis连接总数将为19 + 5(Sidekiq 4)= 24,并且使用默认的并发25是可以的。正如Mike Perham所说,并发一般不能超过(服务器池大小-2)* 2。
现在,让我感到困惑的是在Sidekiq中使用Redis。
# initializers/redis.rb
$redis = Redis.new(:url => uri)
Run Code Online (Sandbox Code Playgroud)
每当我在模型或控制器中使用Redis时,我都会这样调用:
$redis.hincrby("mycounter", "key", 1)
Run Code Online (Sandbox Code Playgroud)
据我了解,当调用$ redis.whateverFunction时,所有puma线程在单个Redis连接上彼此等待。
在此答案中,在多线程Rails环境中使用Redis的最佳方法是什么?(Puma / Sidekiq),推荐的方法是使用与Sidekiq Wiki https://github.com/mperham/sidekiq/wiki/Advanced-Options#connection-pooling相关的connection_pool gem
require 'connection_pool'
$redis = ConnectionPool.new(size: 10) { Redis.new }
Run Code Online (Sandbox Code Playgroud)
如果我理解正确,那么$ redis.whateverFunction将拥有自己的连接池10,sidekiq拥有自己的连接工人池,现在将新设置总共20个redis连接(30(可用总数)-10 (redis模型连接),并且需要更改Sidekiq客户端和服务器的大小。
如何确定模型/控制器redis连接所需的连接池(此处为10)的大小?由于Redis是单线程的,因此增加连接池实际上如何提高Redis的操作性能?
任何对此的想法都会有很大帮助。谢谢!
Redis 是单线程的,但用纯 C 语言编写,内部使用事件循环并异步处理连接,因此在提供相同数量的请求时,连接计数不会对其产生太大影响。由于网络延迟、ruby 比编译和优化的 C 慢等,它能够比您的应用程序生成请求更快地处理请求,因此您无需担心它是单线程的。
增加连接数有利于来自不同线程的并发请求,因为不需要等待通过网络传递响应来解锁连接,而且 ruby 可以执行并行 IO。
此外,当连接检出时间变得比您预期/容忍的更糟并且相应的线程/工人在等待它时处于空闲状态时,您可以判断池是否太小,因此请对您的代码进行基准测试并仔细查看您的实际使用和行为模式。
另一方面,我建议不要使用所有连接数限制,有时您可能需要这些额外的连接。例如:
| 归档时间: |
|
| 查看次数: |
2553 次 |
| 最近记录: |