APIサーバーの応答時間が増加してしまうという問題がありました。ロードアベレージがこの時最大16とかです。ネットワークの問題というよりは何らかのハードウェア資源が不足してるという状況が考えられます。このときCPU負荷は常に90%以上を推移していてCPUが何らか圧迫されているように見えました。SARをみたsysstatというパッケージを入れておくと定期的にCPUが何に取られているかログを取ってくれるで便利です。headしてみたら、%sysや%iowaitは低かったのですが、%userが40%近い値になっていました。これはつまり何らかユーザープロセスがCPUを圧迫しているということです。topでざっくりと負荷を確認topコマンドは常識だと思いますが、topでしばらくCPUの負荷を観察したところ、定期的にbundleコマンドの何かが3つほど呼び出されてそれら個別に20%ずつほどCPUを食っているようでした。-n4で、全プロセスをCPU処理を食っている割合で降順にソートし、トップ3を取り出してみました。定期的にユーザー端末のヘルスチェックを行ったり、定期的なログを吐き出すようなジョブたちがCPUの大部分を占めていました。他のプロセスは基本的にCPU負荷は5%にも届かないような状態が多く、圧倒的にこれらのプロセスがCPUを食っていました。以前から気がかりだった定期的な処理とAPIサーバーが同じところに乗っているという問題は早急に解決しないと行けないレベルになったと判断しました。APIサーバーから追い出そうと決め、とりあえずGoのスクリプト等がcronで呼び出されていたサーバー(以下バッチサーバー)に移動しようと決めました。ソースコードをバッチサーバにもデプロイデプロイ処理を現在はCapistranoで行っていたこともあり、rbenvの登録や必要なライブラリのインストール等を適宜バッチサーバーに実施してやり、デプロイ対象にバッチサーバーを登録してやったところすんなりCapistranoでソースコードをバッチサーバーにデプロイできました。%w(<サーバー接続情報>)を登録してやりました。これで本番環境のデプロイ時にバッチサーバーにもソースコードがアップロードされるようになりました。:batchという感じで設定してやればwheneverのcron登録は先程のbatchロールにだけ実施されるようなりました。上記の話はプロダクション環境のみに関係のある話でステージング環境は以前すべて同じサーバーで問題ありません。:batchを書いておいてやって、具体的なbatchロールに属するサーバーはproduction.rbとstaging.rbで設定する形にしておくと楽です。staging.rbではたとえばメインのサーバーと同一の接続情報にしておくことで同じサーバーですべて実施されます。ジョブを正しくキューするにはRedisもどこかに移さなくてはなりません。APIサーバーはAPIのみに注力しようと考え、暫定的にバッチサーバーにRedisも移動することにしました。redis接続可能になったらOKです。このとき、APIサーバーからもRedisにつなげておくようにしておくと、Sidekiqに付属しているWebコンソール経由で見張れるので便利です。"<どこか適切なパス>"この段階で、cron経由やAPIサーバー経由でジョブがバッチサーバー上のredisに登録される様になりました。(こちらも本来はSidekiq用の専用サーバーを立ててやってAutoScalingとかするのが良いと思います)Sidekiqをバッチサーバー上でのみ実施するこちらもCapistranoのお陰で超簡単です。:sidekiqとsidekiq_roleを設定してやって、wheneverの時と同様に各環境ごとにサーバーを設定してやれば完了です。これで、デプロイ時にバッチサーバー上でSidekiqが実行されるようになります。<pid>で止めて、Webの監視画面からsidekiqが正常に動いていることを確認したら無事完了です。FluentdをバッチサーバーにインストールJobの中にはFluentd経由でログを収集しているインスタンス向けてRails内部からログを送信するタイプのものもありました。バッチサーバー上のsidekiqのログを見ていたらFluentdとの接続エラーが出ていたので、適宜Fluentdの設定をしました。これはAPIサーバー上にFluentdを設定したときのItamaeのレシピが残っていたので、それを適宜再利用してすんなり完了しました。今回の移行で負荷が増大する懸念があったので、インスタンスタイプの変更を検討しました。-rssの結果を確認したところこれらはunicornのワーカーが使用していもので、バッチジョブとは無関係でした。CPUの消費はほぼバッチによるものでした。バッチの定期的なものだけでなく、オンラインで実施されるJobも含めて検討するとサービスの実施時間帯中のスポットで一気にユーザーの需要に合わせて高まる傾向が多く、ずっとCPUを消費するというよりは必要なときにパワーの出るタイプが望ましいと判断しました。サービス拡大の時期であり、需要の上限が用意には見積もれず、またオートスケールを導入してしまうよりは一旦サービス中の負荷を確認できたほうが良いだろうと判断し、一旦大きめのインスタンスタイプで余裕を持つことにし、インスタンスタイプはt2.mediumを選択しました。なったCloudWatchで見張ったその晩は果たして上記の判断が正しいものだったのか不安だったので、CloudWatchでAPIサーバー及びバッチサーバーを見張ることにしました。実施直後ロードアベレージが一気に下がったまず、上記の施策を実施した時点でロードアベレージががくんと下がりました施策の実施直前は色々とサーバー内で必要なプロセスを止めたり、色々と作業をしていたので一時的にロードアベレージは上がっていますが、実施後に、一気に平均のロードアベレージが下がりました。負荷の高い時間帯でなくても平均してロードアベレージは0.4程度あったのですが、施策を実施した直後0.04程度に一気に下がりました。サービス時間帯中もロードアベレージが異常事態を迎えなくなった実施して一晩たった記録ですが、最近発生してきていた異常な状態がなくなったことがわかります。サービス時間野メイン時間には多少ロードアベレージが上がっていますが、一番高いもので1.99です。2日連続で通信エラーに悩まされていて眠れない夜が続いていたのですが、今回の施策を実施して、一気に異常なピークが発生しなくなりました。メモリ使用率は30%程度です。t2.microはコアが2つなので、実際は24%~30%程度ですので、ベースラインパフォーマンスの40%は常に下回っている状態となりました。T2インスタンスT2インスタンスはベースラインパフォーマンスを下回っていると自動的にCPUクレジットが溜まっていき、必要なときに頑張ってくれるのですが、現状のインスタンスタイプだとピーク時にもクレジットはたまり続けて居ますね。いえ、まだ一日しか様子は見ていないので、ここで小さくするのは早計だと思うので、一週間から一ヶ月程度様子を見た上で判断したいと思います。開発環境はDockerでビルドできているので、本番環境でもDockerに移行してECS等で管理したい。用意に対応できると思う。»プロフィールid:Pocket7878_devプログラミング好きで、仕事の傍らで趣味で書いたもの等があればちょびちょび更新していきます。Inc.はてなブログをはじめよう!Pocket7878_devさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。