ボクココ

サービス開発を成功させるまでの歩み

Heroku Postgres のアクセスが遅くなった時にした対応

ども、@kimihom です。

f:id:cevid_cpp:20200730180548j:plain

先日、Heroku Postgres の Hobby プランを使っていたら、急に DB へのアクセスが遅くなった事象が発生した。その原因と対応について記しておく。

問題の原因

まず、どんなときに遅くなったのかというと、1つのレコードに大量のデータが入ったときだった。それ以降、Heroku Addnons の NewRelic や Scout APM などのアドオンで重たい原因となっている部分を調べたところ、Active Record(DBアクセス) で 90% 以上の時間を費やしていることがわかった。

Postgres のレコードのカラムを text 型で保存し、そのカラムに大量の文字をテストで入れて保存してから、急にデータアクセスが遅くなってしまったのだった。そのデータは、ページロード時に読み込まれるデータであり、とりわけ Heroku Dyno を再起動した直後はまともにアクセスできず、 R12 Error が必ず発生してしまった。

その後、DB アクセスにキャッシュが入るようになると、それ以降は H12 は起きないものの、レスポンスが遅いことには変わりなかった。

問題の対応

まず、大量に入っているテキストのレコードはどれかを調べ、そのレコードを更新してみた。しかし、一度遅くなってしまったら、アクセスはずっと遅いままだった。

Hobby プランで使っていたのは、テスト環境のサーバーであったため、思い切って 一度 Heroku Postgres のバックアップをとってから削除し、改めて Heroku Postgres を入れることで対応した。

1. バックアップの保存、取得

まず Heroku Postgres のページへ遷移し、Durability から、 Create Manual Backup をクリックし、バックアップを作成する。しばらくすると、それがダウンロードできるようになるので、ダウンロードしてローカルのPCに保存する。

2. S3 など、アクセス可能な場所へ保存

ダウンロードしたバックアップを、S3 など URL でアクセスできるような場所に保存する。その URL を控えておく。

3. Heroku Postgres を再インストール

まず必要に応じて、メンテナンスモードを有効にする。その後、Heroku Postgres を削除する。

$ heroku maintenance:on -a myapp

$ heroku addons:destroy heroku-postgresql:hobby-dev -a myapp

$ heroku addons:create heroku-postgresql:hobby-dev -a myapp

4. バックアップデータを取り込む

先ほどバックアップしたデータを新しく入れた Heroku Postgres に入れる。無事に成功したら、メンテモードを OFF へ。

$ heroku pg:backups:restore 'https://myapp.s3-ap-northeast-1.amazonaws.com/backup' DATABASE_URL -a myapp

$ heroku maintenance:off -a myapp

この作業により、DB へのアクセスが劇的に速くなり、問題を解決できた。S3 にあげたデータの削除をお忘れなく。

終わりに

今回の話は、Heroku Hobby プランで起きた問題であり、より上位プランであれば、そもそも大量のデータが入っても遅くはならなかった(確認済み)。

テスト環境のデータはできる限り安く運用したいだろう。今回のデータベースの削除と再インストールは、そこまで手間ではないので、一度 Heroku Postgres が遅いと感じた場合には大きなデータを削除した後、再インストールを試してみて欲しい。