【问题标题】:ActiveJob GlobalID and in-memory ActiveRecord objectsActiveJob GlobalID 和内存中的 ActiveRecord 对象
【发布时间】:2015-08-14 17:25:24
【问题描述】:

我正在使用排队系统 (Sidekiq) 并希望迁移到 ActiveJob 以获得性能优势,即每次将 ActiveRecord 对象传递给工作人员时不必查询数据库。我想询问并确认,因为我不是 100% 确定,但我的理解是,当 ActiveJob 使用 GlobalID 传递所有在内存中完成的 ActiveRecord 对象并且没有完成对数据库的单独查询时,对吗?

【问题讨论】:

    标签: ruby-on-rails ruby activerecord rails-activejob


    【解决方案1】:

    这是不正确的。

    如果您使用 ActiveJob,它会将任何 ActiveRecord 对象序列化为 global_id 字符串以保存到您的队列中。然后在作业开始时从该字符串中再次查找它。默认情况下,该字符串仅包含应用名称、类名称和 id,它将使用您的数据库来加载模型。

    "gid://app/User/1"
    

    DelayedJob 会将您提供的任何对象序列化为 yaml 字符串并对其进行反序列化,而不会在加载作业之外访问数据库。您也可以使用 Sidekiq 执行此操作,而不是点击 Redis 来加载作业而不接触主数据库。

    user = User.find(1)
    MyJob.perform_later(user.to_yaml)
    
    # Load the user object from the yaml
    YAML::load(user.to_yaml) == user # true
    

    您无需前往数据库即可获得您的物品。但是,YAML 会很大,并且使用 Redis 获得的性能损失可能不值得。

    还有一些您应该注意的问题。该对象可能在数据和结构方面都已过时。如果您更改代码,序列化对象可能由于结构更改而无法再次加载。如果你在序列化对象后更新数据库,当你加载它时,你会在不知不觉中处理旧数据。

    希望能帮助您了解 ActiveJob 和 GlobalId 提供的内容。

    【讨论】:

      【解决方案2】:

      数据库查询无论如何都会被执行,但是是透明的。下面以 ActiveJob 内部的代码为例:

      gid = User.find(1).to_global_id
        User Load (0.8ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
      => #<GlobalID:0x00007f86f76f46d8 @uri=#<URI::GID gid://app/User/1>>
      

      然后,当作业执行时,ActiveJob 在内部运行以下代码,无论如何都会查询数据库:

      GlobalID::Locator.locate(gid)
        User Load (0.3ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
      => #<User id: 1, ... >
      

      使用 GlobalIDs 的一个问题是,如果在作业入队之后但在调用 #perform 方法之前删除了传递的记录,则 Active Job 将引发 ActiveJob::DeserializationError 异常。

      性能

      根据 Sidekiq 的作者 Mike Perham 的说法,基准测试表明 ActiveJob 将作业推送到 Redis 的速度要慢 2-20 倍,处理开销大约是 3 倍 (https://github.com/mperham/sidekiq/wiki/Active-Job#performance)。

      附加信息

      关于 Sidekiq、ActiveJob 和 GlobalID 的所有信息都可以在这里找到:https://github.com/mperham/sidekiq/wiki/Active-Job#using-global-id

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-16
        • 2012-11-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多