【问题标题】:speed up response of request with cache or binary response使用缓存或二进制响应加快请求响应
【发布时间】:2015-01-13 03:54:15
【问题描述】:

我想用缓存二进制响应

加快查询响应速度

渲染 5k ~ 100k 条记录的 json 响应需要超过 30 秒 ~ 500 秒

如何让它更快?

因为渲染时响应时间仍然很慢

是否可以进行二元响应(跳过渲染视图)?

  WeatherLog Load (335.5ms)  SELECT  "weather_logs".* FROM "weather_logs"   ORDER BY "weather_logs"."datetime" ASC LIMIT 90000
Write page /Users/public/index.json (35.2ms)
Completed 200 OK in 40488ms (Views: 32459.3ms | ActiveRecord: 336.8ms)

控制器

caches_page :index
respond_to :json

def index
  begin       
    @weather_logs = WeatherLog.result(q)

    respond_to do |format|
      render json: @weather_logs
      return
    end
  rescue Exception => e
    respond_to do |format|
      format.json { render json: {status: "Invalid Request #{e.backtrace.first(3)}"} }
    end
  end
end

数据流:第 4 步是渲染的瓶颈

简而言之

我只需在短时间内将响应发送给客户

不管是什么格式。

即使是二进制格式也可以。

请给我一些方向或想法来提高性能

【问题讨论】:

  • 流式响应是否适合您?见stackoverflow.com/a/24292549/2463468
  • 生成的文件有多大(或单个条目有多大)?
  • @mdrozdziel 大约几十万到几百万
  • 你不会把缓存结果和缓存响应混为一谈吗?
  • “几十万到百万”是什么单位?

标签: ruby-on-rails ruby-on-rails-4 jbuilder


【解决方案1】:

肯定只是渲染有问题吗,WeatherLogs.result(q) 的结果是什么。您是否对 WeatherLogs#results 调用进行了基准测试?迭代返回的集合而不是仅仅渲染它需要多长时间?将其呈现为 JSON 时是否调用了任何方法,例如不仅是类字段?

如果确实是渲染问题,您可能需要在将数据插入 WeatherLogs 时考虑使用 LRU 缓存,这实际上是对客户端请求的数据进行非规范化处理。因为,根据您的流量和可能的查询数量(尽管这也会影响非规范化数据),当它在渲染时生成时,它几乎永远不会命中缓存。这篇文章可能是一个好的开始:http://oldblog.antirez.com/post/redis-as-LRU-cache.html

但是如果不了解渲染需要这么长时间的确切原因,我不会去构建一个复杂的缓存,如果 JSON 渲染是问题 OJ 可能是一个解决方案或者任何声称是最快的库,但我有一个预感这不是实际的渲染问题。

如果您有任何其他问题,我们很乐意提供帮助。

【讨论】:

  • 有什么方法可以响应 postgreSQL 的原始结果,跳过渲染任务?
  • 您好,感谢您的详细解释,希望您能给我更多关于跳过渲染的提示或指导谢谢
  • 当然,不过我需要更多信息。您是否考虑过分析渲染?(ruby-prof:github.com/ruby-prof/ruby-prof)。您还可以考虑在我的初步回复中回答第一段问题吗?无论如何,为了消除渲染,当新数据插入数据库时​​,您必须渲染它们。这在何时何地发生,可能的查询参数是什么(传入 WeatherLog.result(q) 的 q)?
  • 您好,我加了一张数据流程图来解释,尽量解释清楚
  • - 初始 HTTP 请求中可能使用的查询参数是什么? - WeatherLogs 数据如何添加到数据库中? - 渲染是否调用任何其他方法,然后只是 DB 字段? (您是否分析过 \@weather_logs.to_s ? to_s/to_json 是自定义实现吗?) - \@Weather_logs 中的集合有多大,大约需要 30 秒?
【解决方案2】:

你需要显式调用 Oj:

  def index
    begin         
      @weather_logs = WeatherLog.result(q)

      respond_to do |format|
        render json: Oj.dump(@weather_logs)
        return
      end

如果你想让它变得隐含,试试我公司的这个宝石:https://github.com/GoodLife/rails-patch-json-encode

【讨论】:

  • 很抱歉,这无法帮助我加速瓶颈。有什么方法可以加速?或跳过渲染?
  • 所以使用Oj.dump时没有速度差异?至少应该有一些。
  • 它会更胖,但没有多大帮助。我可以跳过渲染并响应客户端的原始结果吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-06
  • 1970-01-01
  • 2013-02-20
  • 1970-01-01
  • 2016-05-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多