1

プロファイルのビュー数に基づいてユーザーをランク付けするページを構築しようとしています。そのページは多くのヒットを獲得している可能性があるため、注文したユーザーをキャッシュし、プロファイルがビューを取得するたびにそのキャッシュを無効にします。私のアプリはたった 9 人のユーザーと 1 日の最大 200 ページ ビューで、Heroku のメモリ上限の 512 MB を超えました。New Relic はこれを確認し、ユーザーの一覧表示に非常に時間がかかっていることを示しました。

Slowest Components          Duration        %
-----------------------------------------------
UsersController#index       2,125 ms        80%
users/index.html.erb        506 ms          19%
Memcache get                20 ms           1%
User#find                   18 ms           1%
layouts/_header.html.erb    1 ms            0%
User#find_by_sql            0 ms            0%

ActiveRecord は、リクエスト後にメモリを OS に返さないようだということを読んだことがあります。を見ると、によって割り当てられたメモリが解放されていないUsersController#index場合に、これがどのように問題を引き起こすかがわかります。User.order

UserController#index:

require 'will_paginate/array'

class UsersController < ApplicationController
  PER_PAGE = 20

  def index
    @users = Rails.cache.read("users")
    if @users.nil?
      # .all is used to force the query to happen now, so that the result set is cached instead of the query
      @users = User.order("views DESC").all
      Rails.cache.write("users", @users)
    end

    @users = @users.paginate(page: params[:page], per_page: PER_PAGE)

    if params[:page].nil? || params[:page] == "1"
      @rank = 1
    else
      @title = "Page #{params[:page]}"
      @rank = (params[:page].to_i - 1) * PER_PAGE + 1
    end
  end
end

index.html.erb

<% @users.each do |user| %>
  image_tag user.profile_picture, alt: user.name
  <h3><%= @rank %></h3>
  <p><%= user.name %></p>
  <p><%= user.views %></p>
  <% @rank += 1 %>
<% end %>
<%= will_paginate %>

私はこれをどのように回避するべきかわかりません。一度に 1 ページのユーザーのみをメモリにプルアップすることを考えましたが、1 ページあたり最大 20 のユーザーがリストされることになっているため、ユーザーが 9 人しかいない場合、実際には何も変わりません。@usersリクエストごとに手動でメモリからクリアする必要がありますか、それとも私のアプローチがUsersController#index間違っていますか?

どんな助けでも大歓迎です。

4

0 に答える 0