Rails,Heroku和Resque:长时间运行的后台作业优化

时间:2016-10-18 18:22:58

标签: ruby-on-rails heroku resque

我们正在构建一个火种风格的应用程序,允许用户喜欢"喜欢"或者"不喜欢"事件。每个活动都有大约100个与之关联的关键字。当用户喜欢"或者"不喜欢"和事件,我们将该事件的关键字与用户相关联。用户可以快速获得数千个关键字。

我们使用表格将用户和事件与关键字(event_keywords和user_keywords)相关联。直通表中有一个额外的列relevance_score,它是一个浮点数(例如,如果某个关键字非常相关,则该关键字可以为0.1,如果它非常相关则为0.9)。

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

以下是模型:

User.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

Event.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

UserKeyword.rb:

  belongs_to :user
  belongs_to :keyword

EventKeyword.rb:

  belongs_to :keyword
  belongs_to :event

EventRanking.rb:

  belongs_to :user
  belongs_to :event

Keyword.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

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

User.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

每次用户"喜欢"或者"不喜欢"一个事件,创建一个后台作业:

RecalculateRelevantEvents.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. 根据用户的关键字
  4. 重新计算每个类似的事件

    我试图找出优化方法的方法,因为它很快就会失控。普通用户将每分钟刷过大约20个事件。一个事件最多可以有1000个类似的事件。每个活动都有大约100个关键字。

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

    我该如何处理?

1 个答案:

答案 0 :(得分:1)

你需要按滑动计算吗?你可以debounce,并且每5分钟为用户重新计算一次吗?

这个数据不需要每秒更新20次才有用,事实上,每秒更新一次可能更有用。

通过5分钟的去抖动,您可以从每位用户的6,000(20 * 60 * 5)次重新计算到同期的1次 - 相当可观的节省。

如果可以,我还建议使用sidekiq,通过多线程处理,您可以大大增加同时工作的数量 - 我是一个忠实粉丝。

他们一旦你使用它,你可以尝试像以下宝石: https://github.com/hummingbird-me/sidekiq-debounce

...这提供了我所暗示的那种去抖动。