【问题标题】:Rails, Heroku, and Resque: Long Running Background Job OptimizationRails、Heroku 和 Resque:长时间运行的后台作业优化
【发布时间】:2016-10-19 03:24:44
【问题描述】:

我们正在构建一个 tinder 风格的应用程序,允许用户“喜欢”或“不喜欢”事件。每个事件都有大约 100 个与之关联的关键字。当用户“喜欢”或“不喜欢”和事件时,我们将该事件的关键字与用户相关联。用户可以快速获取上千个关键词。

我们使用通过表将用户和事件与关键字(event_keywords 和 user_keywords)相关联。 through 表有一个附加列 relevance_score 是一个浮点数(例如,如果关键字非常相关,则可以是 0.1,如果非常相关,则可以是 0.9)。

我们的目标是根据用户的关键字向他们展示最相关的事件。因此,Events 有许多属于用户的 event_rankings。从理论上讲,我们希望为每个用户对所有事件进行不同的排名。

以下是模型:

用户.rb:

  has_many :user_keywords, :dependent => :destroy
  has_many :keywords, :through => :user_keywords
  has_many :event_rankings, :dependent => :destroy
  has_many :events, :through => :event_rankings

事件.rb

  has_many :event_keywords, :dependent => :destroy
  has_many :keywords, :through => :event_keywords
  has_many :event_rankings, :dependent => :destroy
  has_many :users, :through => :event_rankings

用户关键字.rb:

  belongs_to :user
  belongs_to :keyword

EventKeyword.rb:

  belongs_to :keyword
  belongs_to :event

EventRanking.rb:

  belongs_to :user
  belongs_to :event

关键字.rb:

  has_many :event_keywords, :dependent => :destroy
  has_many :events, :through => :event_keywords
  has_many :user_keywords, :dependent => :destroy
  has_many :users, :through => :user_keywords

我们有一种方法可以根据特定用户的关键字计算事件与特定用户的相关程度。这个方法运行得很快,因为它只是数学运算。

用户.rb:

def calculate_event_relevance(event_id)
  ## Step 1: Find which of the event keywords the user has 
  ## Step 2: Compare those keywords and do math to calculate a score 
  ## Step 3: Update the event_ranking for this user
end

每当用户“喜欢”或“不喜欢”一个事件时,就会创建一个后台作业:

重新计算相关事件.rb:

def self.perform(event_id)
  ## Step 1: Find any events that that share keywords with Event.find(event_id)
  ## Step 2: calculate_event_relevance(event) for each event from above step
end

所以这里是这个过程的总结:

  1. 用户喜欢或不喜欢某个事件
  2. 创建后台作业,查找与步骤 1 中的事件相似的事件
  3. 每一个类似的事件都会根据用户的关键字重新计算

我正在努力想办法优化我的方法,因为它很快就会失控。普通用户每分钟会浏览大约 20 个事件。一个事件最多可以有 1000 个类似事件。每个事件都有大约 100 个关键字。

因此,使用我的方法,每次滑动时,我需要遍历 1000 个事件,然后在每个事件中遍历 100 个关键字。每个用户每分钟会发生 20 次。

我应该如何处理这个问题?

【问题讨论】:

    标签: ruby-on-rails heroku resque


    【解决方案1】:

    每次滑动都需要计算吗?你能debounce它,并为用户重新计算不超过每 5 分钟一次吗?

    这些数据不需要每秒更新 20 次才有用,事实上,每秒更新的频率可能比有用的频率高得多。

    通过 5 分钟的去抖动,您可以在同一时期内从每位用户 6,000 (20 * 60 * 5) 次重新计算减少到 1 次 - 节省了大量资金。

    如果可以的话,我还建议使用 sidekiq,它的多线程处理可以极大地增加同时作业的数量 - 我是一个忠实的粉丝。

    一旦你使用它们,你可以尝试像这样的 gem: https://github.com/hummingbird-me/sidekiq-debounce

    ...提供了我建议的那种去抖动。

    【讨论】:

    • 不,我不一定需要计算每次滑动。因此,使用这种方法,我将每 5 分钟为每个最近活跃的用户计算 1000 个事件?
    • 就是这样。 5 分钟是一个不知从何而来的数字,但其想法是这些数据不需要每秒更新 20 次才能有用,实际上每秒更新一次可能比有用的频率更高。通过 5 分钟的去抖动,您可以在同一时期从每位用户 6,000 (20 * 60 * 5) 次重新计算减少到 1 次 - 节省了大量资金。
    • 是的,这很好。还有其他明显的地方可以优化吗?
    • 不明显。我确实想到了几个问题:每个事件有这么多关键字有意义吗?将它们全部用于计算相关性是否有意义?将它们全部添加给用户是否有意义,或者只添加对事件最重要的那些?您是否有理由自己构建它而不是使用内置相关性的弹性?
    • 好的,这些都是我要研究的重点。非常感谢。
    猜你喜欢
    • 2023-03-21
    • 2016-08-05
    • 2016-03-23
    • 2013-01-10
    • 1970-01-01
    • 1970-01-01
    • 2016-08-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多