質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Amazon RDS

Amazon RDSは、米アマゾン社が提供しているRDBMSサービス。クラウド上でのリレーショナルデータベースの構築および運用が可能です。MySQL/PostgreSQL/Oracle/SQL Serverのインストールを容易にすることができます。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Active Record

Active Recordは、一つのオブジェクトに対しドメインのロジックとストレージの抽象性を結合するデザインパターンです。

Amazon EC2

Amazon EC2は“Amazon Elastic Compute Cloud”の略称です。Amazon Web Services(AWS)の一部であり、仮想化されたWebサーバーのコンピュータリソースをレンタルできるサービスです。

Q&A

解決済

2回答

663閲覧

Rails + Nginx + AWS + RDS t2micro(メモリ1G)環境で、20000行のデータベース表示でpumaが落ちてしまう

lyzmfeqpxs54

総合スコア237

Amazon RDS

Amazon RDSは、米アマゾン社が提供しているRDBMSサービス。クラウド上でのリレーショナルデータベースの構築および運用が可能です。MySQL/PostgreSQL/Oracle/SQL Serverのインストールを容易にすることができます。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Active Record

Active Recordは、一つのオブジェクトに対しドメインのロジックとストレージの抽象性を結合するデザインパターンです。

Amazon EC2

Amazon EC2は“Amazon Elastic Compute Cloud”の略称です。Amazon Web Services(AWS)の一部であり、仮想化されたWebサーバーのコンピュータリソースをレンタルできるサービスです。

0グッド

0クリップ

投稿2020/10/27 06:31

編集2020/10/28 01:21

いつもお世話になっております。

Rails + Nginx + AWS + RDS環境でwebページを作成しております。

管理画面のようなページを作成しており、20カラム、20000行程度のデータベースの内容をViewに表示しており、もっと見る機能でページを下にどんどん表示することができる状況です。
ページネーションは100ページずつでGemのKaminariを使用しています。

AWSのインスタンスタイプt2micro(メモリ1G vCPU 1)で運用しているのですが、もっと見るを繰り返し押してどんどん表示してくとPumaが落ちてしまいます。

vmstatで監視していると、Pumaの起動時でメモリは700M程度あり、20000行のページを表示(kaminariで最初の100行分が表示)すると一気に200M程度まで下がり、もっと見るを繰り返し進めていると50M程度まで下がった後Pumaが落ちてしまいます。

インスタンスタイプをt2midium(メモリ4G vCPU 2)に変更してみると、Pumaの起動時でメモリは3.5G程度であり、ページ表示で3G、もっと見るで2.6G程度となります。

ここで質問なのですが、20000行程度のテーブルを扱う場合にメモリ1Gというのは一般的にはよくないのでしょうか。
また、4Gにt2midium(メモリ4G vCPU 2」に変更した場合でも表示に5秒程度かかり、「もっと見る」で次の100件を表示するたびに5秒ほどかかり、かなり遅いように感じたのですが、Viewにモデルを渡す場合にもっと効率的な方法などがあるのでしょうか。

参考になるサイトでも構いませんので、適切な方法をご教示いただけますと幸いです。
よろしくお願いいたします。

# コントローラー def show # kaminariでページを区切る @users = User.all.page(params[:page]).per(100) render 'xxxx_xxxs/show' end # ビュー <% @users.each do |user| %> <% user.id %> <% user.name %> ・ ・ ・ <% end %> <%= link_to_next_page @users, 'もっと見る', remote: true, id: 'more_link' %>

環境
Amazon Linux release 2 (Karoo)
Rails 5.2.3
Ruby version: 2.6.1

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

winterboum

2020/10/27 09:07

「もっと見る」とは次の100件表示ですか? それとも 追加100件ですか?
lyzmfeqpxs54

2020/10/27 12:19

ご回答ありがとうございます。 追加で100件です(同一ページで合計が200,300と増えていく)。
guest

回答2

0

ベストアンサー

20カラム、10000行程度のデータベースの内容をViewに表示しており、もっと見る機能でページを下にどんどん表示することができる
ページネーションは100ページずつでGemのKaminariを使用しています。

ちょっと気になったので、Rails6のサンプルをHeroku Freeプラン(RAM512MB/PostgreSQL)に作ってみました。
https://kaminari-test.herokuapp.com/

Freeプランなのでどのくらいメモリを利用しているかわからないのですが、pumaが落ちる、応答がすごい遅いといった感じはないかと思います。
実データとは異なると思うのでなんともいえないですが、アプリに問題をかかえている可能性が高いかと思います。


対策ですが、知見がないということを前提に・・・
bulletを使ってN+1問題を確認するくらいしか思いつきません。


参考になるサイトでも構いませんので、適切な方法をご教示いただけますと幸いです。

今回、実装した方法を記載しておきます。

# PagesController def index @pages = Page.all.page(params[:page]).per(100).order(:id) end
<!-- index.js.erb --> $("<%= escape_javascript(render 'pages', object: @pages) %>").appendTo("#add-pages").hide().fadeIn('slow'); $("#more_link").replaceWith("<%= escape_javascript( link_to_next_page(@pages, 'もっと見る', remote: true, id: 'more_link') ) %>");
<!-- _pages.html.erb --> <tbody id="add-pages"> <%= render 'pages' %> </tbody> <%= link_to_next_page @pages, 'もっと見る', remote: true, id: 'more_link' %>
<!-- _pages.html.erb --> <% @pages.each do |page| %> <tr> <td><%= page.id %></td> <td><%= page.c1 %></td> <td><%= page.c2 %></td> <td><%= page.c3 %></td> <td><%= page.c4 %></td> <td><%= page.c5 %></td> <td><%= page.c6 %></td> <td><%= page.c7 %></td> <td><%= page.c8 %></td> <td><%= page.c9 %></td> <td><%= page.c10 %></td> <td><%= page.c11 %></td> <td><%= page.c12 %></td> <td><%= page.c13 %></td> <td><%= page.c14 %></td> <td><%= page.c15 %></td> <td><%= page.c16 %></td> <td><%= page.c17 %></td> <td><%= page.c18 %></td> <td><%= page.c19 %></td> <td><%= page.c20 %></td> <td><%= link_to 'Show', page %></td> <td><%= link_to 'Edit', edit_page_path(page) %></td> <td><%= link_to 'Destroy', page, method: :delete, data: { confirm: 'Are you sure?' } %></td> </tr> <% end %>

なにかの参考になれば幸いです。

投稿2020/10/28 00:01

no1knows

総合スコア3365

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

lyzmfeqpxs54

2020/10/28 01:20

ご回答ありがとうございます。 わざわざテスト環境まで用意していただき、本当にありがとうございます。 大変申し訳ございません。一点誤りがございまして10000行では、お作りいただいた環境と同じ程度の読み込み速度でした(もっと見るを押して約2秒程度)。実験的に20000行にしてみた場合に5秒程度かかっておりました。不躾なお願いで大変恐縮なのですが、もしお時間が許しましたらお作りいただいた環境の行数を2万行や10万行程度にしただいて速度を確かめていただくことは可能でしょうか。 このデータベースは1年間で5万行程度ずつ増えていく予定ですので、この時点でこの程度の時間がかかるのは結構厳しいのかなと考えております。
winterboum

2020/10/28 01:24

レコードのサイズも関わるのでそれも伝えることと、 5万行も表示させてどうするのでしょう?? そうしなければならないというアプリが想像できません。
lyzmfeqpxs54

2020/10/28 01:28

言葉が足らず申し訳ございません。 表示自体は100行ずつ(実際には先頭の数百行程度しか表示されることはなく、検索機能などである程度絞り込んでから表示するイメージ)なのですが、大元となるデータの行数が5万/年で増えていくようなイメージです。
winterboum

2020/10/28 01:29

1レコードのボリュームです
winterboum

2020/10/28 01:31

もしかしたら、databaseエンジンか? RDBは何を使ってます?
lyzmfeqpxs54

2020/10/28 01:40

MySQL 5.7.30を使用しております
no1knows

2020/10/28 01:50

まぁ、理論上、Kaminariで総レコードをとってきているわけではないのでテストする必要はないと思ったのですが・・・ せっかくなので5万レコードでやってみました。 結論として表示する速度は変わっていないという認識で良いかと思います。 動作として考えると ①SQLで100レコード取得・表示。 ②「もっと見る」で、Ajaxで100レコード取得・表示。 ③「もっと見る」で、Ajaxで100レコード取得・表示。 ④以下ループ なのでDB側の負荷は毎回100レコードのSelectでしかないです。 そのためデータ量が増えたからといってAjaxの読み込みが遅くなることは考えにくいかと思います。 もっと膨大なレコード数や、複雑なアソシエーションを組んでいたりしたら違うのかもしれませんが・・・ テストサイトを見たら、すいませんが、返事をください。 Herokuの無料データ上限1万レコードを超えているため早く消したいです。。。
no1knows

2020/10/28 01:53 編集

> 10000行では、お作りいただいた環境と同じ程度の読み込み速度 計測していないとは言え、日本にあると思われるAWSとテストサイトが同じ読み込み速度だとすると、そもそも問題がある気がしますね。 Herokuはアメリカ西海岸なので、アメリカ1往復分の遅延があるはずなので。
no1knows

2020/10/28 02:08

> t2micro(メモリ1G vCPU 1)Pumaの起動時でメモリは700M程度あり > t2midium(メモリ4G vCPU 2)に変更してみると、Pumaの起動時でメモリは3.5G程度 サーバーはよくわかっていないのですが、メモリを増やしたら、利用するメモリが増えるっておかしい気がしますね。 切り分けのために下記のような手順はいかがでしょうか? ①現在のリポジトリをHerokuでテスト公開する。 ②初期データを投入する。 ⇒アプリに問題なければAWS側の問題。 ⇒アプリに問題があればアプリ側の問題。
lyzmfeqpxs54

2020/10/28 08:56

ご連絡が遅くなり申し訳ございません。 ご教示いただいた通り、こちらで一度問題の切り分けを行い、AWS側なのかアプリ側なのかを確認したいと思います。 ここまでお付き合いいただき本当にありがとうございます。
guest

0

その形式でしたらそれだけの数は無理でしょう。
サーバーのメモリーを沢山載せればサーバーはこけなくなるでしょうが、
そのデータをもらったブラウザーがこけます。
ああ、、、puma自身が利用できるメモリー上限があるならだめですね。
その時はpumaをHACKして利用できるメモリーの上限を変更する。

  1. 100件ずつ表示する か
  2. ブラウザーのことは知らん! というのなら

100件ずつ送ってブラウザー側でJS使って最後に追加していく(「追加」なら普通はこういう実装です)
3. ブラウザーがこけても困る なら、ある程度送ったら頭の100件はブラウザーから削除するJSを書く。上の方にスクロールされたら、慌てて消したのを戻すJSを書く(これはちょっとチャレンジング。私はやる元気ない)

投稿2020/10/27 12:57

winterboum

総合スコア23329

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問