ruby-on-rails - 使用 Sidekiq 缓冲和批处理作业
问题描述
我有一个运行非常频繁的 sidekiq 作业,每个作业使用 Rails 中的 ActiveRecord 更新单个 MySQL 数据库记录:
HTTP request
-> RecordUpdateWorker(id, value)
-> Record.find(id).update(value: value)
它导致数据库中的死锁锁定超时。似乎没有重复的工作,但 ID 彼此靠近,所以我只能猜测这是由于Gap Locks造成的。无论如何,我对解决方案的想法是“缓冲”作业并减少批量执行它们的频率。无需立即执行它们,因此对于此用例,它不会引起问题。
HTTP Request
-> Add Record to Buffer
-> Occasionally run RecordUpdateWorker()
-> Record.where(id: ids_from_buffer).update_all(value: values_from_buffer)
# I'd have lots of flexibility to tune the transaction size, etc here
有什么方法可以通过 sidekiq 或 sidekiq 插件来实现这一点?我已经在其他地方使用批处理(Sidekiq Pro),但它似乎不适合这个用例。一个明显的解决方案是仅使用自定义 Redis 队列和重复作业(或类似until_and_while_executing
sidekiq-unique-jobs 中的锁定),但如果有标准方法来完成此操作,我宁愿使用它。
我已经查看了 sidekiq 文档,包括专业版和企业版,但没有找到与此描述完全匹配的任何内容。
编辑:将死锁更改为锁定超时,因为我不确定这是一个死锁场景。
解决方案
推荐阅读
- python - werkzeug.routing.BuildError with Flask -- 尝试构建一个非常简单的 webapp
- php - 如何在电子商务网站的数据库中创建产品规格表
- python - TypeError:'str'对象不能解释为整数python for循环
- ruby-on-rails - RSpec - 除非从撬点调用局部变量,否则测试失败
- c# - API 响应始终为“空”
- ios - SwiftUI - 根据条件添加导航栏按钮
- typescript - 使用“ts_library”中的非“.ts”/“.tsx”文件作为依赖项
- android - 在 RecyclerView 中重复项目
- javascript - js 中的 fetch() (react hooks) - 那么我可以访问第三个数据吗?
- docker - 为什么我的绑定挂载实际上并没有绑定某些文件?