ruby-on-rails - Sidekiq 工作线程中的 Redis 性能不佳

标签 ruby-on-rails ruby performance redis sidekiq

我有一个 Rails 应用程序,它运行 50 个并发 Sidekiq 工作程序,从外部 API 接收数据,对其进行操作并将其存储在数据库中。 为了防止多次存储相同的数据,我创建了唯一的字符串,并将其存储到 Redis 中。

r = Redis.current
r.pipelined do
    options.each do |o|
        r.setex(o.generate_index, 1.hour, o.value)
    end
end

在将新对象保存到数据库之前,我会检查 Redis 中是否存在它的唯一字符串:

r = Redis.current
option_ids = r.pipelined do
    new_options.each do |o|
        r.get(o.generate_index) # check if unique string already exists
    end
end

我也在没有管道的情况下进行了测试,结果相同: Redis GET/SET 非常慢。 某些 GET 请求花费的时间超过一秒!

奇怪的事情:在运行 50 个 Sidekiq 工作线程时,Redis 性能很差,我从 shell 对 Redis 进行了基准测试,结果非常好:

r = Redis.current
10000000.times { puts Benchmark.realtime{ 1000.times{|i| r.get(i)} }}

输出如下:

0.197379041
0.192059888
0.196165358
0.207617425
0.198095963
0.195844917
0.211404108
0.203188759
0.208119298
0.184018683

没有基准测试花费的时间超过 0.5 秒。

我还尝试了 Redis.new 而不是 Redis.current,结果相同。

我不知道问题出在哪里

编辑: 经过更多测试和基准测试后,我注意到代码中的基准测试似乎阻碍了其他工作人员,并使他们的速度比预期慢得多。如果不进行基准测试,工作人员的速度可提高 10 倍。 此外,我的虚拟服务器似乎无法处理那么多工作人员。我的开发笔记本电脑可以容纳 100 名工作人员,并且性能仍然非常快。 而且,当负载很重时,Ruby 端的数据库查询似乎非常慢。 我对简单的 Mongoid 查找进行了基准测试,例如

time = Benchmark.realtime do
    existing_option = Option.find_by(index: o.generate_index)
end

这些基准测试有时花费的时间超过一秒,但查询并未显示在 mongodb 慢速日志中(这意味着数据库上的实际查询花费的时间不到 100 毫秒)。 然而,纯 ruby​​code(没有数据库命中)似乎执行正常。 我想知道当我使用 Typhoeus Hydra 而不是 sidekiq 实现 HTTP 请求时,它的性能是否会更好。

最佳答案

一个线程接触 Redis 与 50 个线程有很大不同。

在您的工作线程中使用了 Sidekiq redis 连接池。它将更好地扩展。

Sidekiq.redis do |conn|
  conn.pipelined do
    ...
  end
end

关于ruby-on-rails - Sidekiq 工作线程中的 Redis 性能不佳,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26568479/

相关文章:

javascript - Gmaps4Rails 相对于一个动态点绘制圆

ruby - 在 Ruby 中按身份比较对象的保证方法

ruby-on-rails - Rails 按键对哈希数组进行分组

ruby-on-rails - Rails 3 工厂与简单实例化

ruby-on-rails - 用于 Lazy HighCharts 的 Rails ActiveRecord group_by & sum db 结果

ruby - 期望创建一个新对象

MySQL:一个普通的盒子每秒可以支持多少次更新?

Java FileChannel 与 BufferedReader - Spring Batch - Reader

c# - 为什么 List<T>.Sort 使用 Comparer<int>.Default 比等效的自定义比较器快两倍以上?

ruby-on-rails - Rails : how should I share logic between controllers?