amakanをUnicornからPumaに移行した

amakan.net

移行したぞ、というだけで特に技術的な知見の無い記事です。


移行の背景

https://amakan.net/ という、レビューの無いシンプルな読書管理サービスを2016年7月から運営している。

5ヶ月ほど運用している中で、利用してくれている人達に色々な意見をもらうことができて、これに対応して年末に時間を取って大きく改善しようとしている。しかし「年末に時間を取ってやろうとしていて...」という発言は明らかに危険信号で、高確率で「結局やれなかったよHAHAHA」ということになるのが目に見えている。そこで、年末に向けて小さな改善を徐々に積み重ねていくことで、モチベーションを高めつつ、新たに変更を加えることへの心理的障壁を無くそうと目論んでいる。今回はその一環として、amakanを動かすWebサーバをUnicornからPumaに変更することで、改善を図ることにした。

amakanの事情

amakanの事情としては、こういう状況にあった。

  • 前段にNginxを配置しているので、Pumaを入れてもそこまで大きく挙動が変わる訳ではない
  • 貧弱なサーバ (EC2で言うとt2.micro程度) の上で動かしている
  • 初回リクエスト以外はJSONを返しているので、基本的に1リクエスト辺りの処理は軽い
  • リクエスト処理中に外部の遅いWeb APIと通信を行う必要性がたまに発生する
  • 少ないメモリ量で同時に処理できるリクエストの数が増えると嬉しい
  • Unicornで4 workersも動かすとわりとメモリが厳しい状況
  • 雑にローリングデプロイしているのでデプロイ時に更にメモリを使いがち
  • デプロイ時にダウンタイムを発生させたくない

Pumaに移行した結果

同程度の処理性能を実現するために利用するメモリの総量が880MB程度から600MB程度に減ったように見える。しかし少しabでリクエストを送ってtopで調べてみた程度で、それ以上に厳密な検証は行っていないので、あまり参考にしないでほしい。

Pumaへの移行時につまづいたところ

折角なので https://github.com/seuros/capistrano-puma を使ってみたんだけど、こいつに結構癖があり、Pumaに与える設定を出来る限りCapistranoの設定として持ちたい、という雰囲気の利用方法を提供するようになっている。なので、Pumaに関する設定はPuma用の設定ファイル、Capistranoに関する設定はCapistrano用の設定ファイルという感じではなくて、これを使うならある程度その流儀に従う必要がある。そのあたり譲歩できないと色々面倒な設定をすることになる、というのがざっくりとした感想。抽象的で歯切れが悪い説明で申し訳ない。理解する必要はないが具体的に言うと、bind、pidfile、state_pathをきちんと設定しないと、上手く起動あるいは再起動できないので気を付けよう、ということだ。

実際デプロイする場面では、既に動いているUnicornは動かせ続けていたのでサービスが止まることは無かったものの、デプロイ時に何度か失敗して設定ファイルを編集する羽目になったので、面倒だった。ちなみに移行方法としては、Unicornが動いているサーバにPumaも動かすようにデプロイして、そのあとNginxの設定で接続先のsocketファイルのパスを変更して、nginxの設定を再読込させるという方法で雑にやった。

Pumaに移行した感想

個人のサービスレベルならPumaで動かすとメモリ節約できて良いんじゃないでしょうか。小規模な話で利点を挙げると、情報が比較的新しいものが多くて助かる。Nginxを前段に立てている状態で、I/OでブロッキングしないPumaのメリットというものは、まだ感覚としては実感できていない。そもそもそんなにリクエストの多いサイトでも無かったし… しかし数千冊読んでいるユーザの新刊リストをiCal形式でGoogleカレンダーなどに大量に要求されると結構つらくて、その辺に影響あったりするのかな。何かハマりそうなので、自分の持っている他のサービスでも幾つか試してみて、もう少し様子を見たい。

amakanの今後

似たような変更として、ResqueからSidekiqへの移行をやってみようかなと思っている。amakanの表立った機能変更としては、このあたりの内の幾つかの対応を予定しています。

  • 未来の新刊を見やすくする
  • Kindle版・非Kindle版・両方の3パターンの新刊リストを見られるようにする
  • 読んだ本を公開せずに利用する設定を提供する
  • 本のカテゴリを整理する
  • 読んだ本の分析を詳しくやる
  • オススメの本に出てくる候補から読みたくないやつを外す
  • Kindle版と非Kindle版とのリンクが後からAmazon側で追加されたときに自動的に統合する
  • シリーズ判定ロジックが頻繁に更新されるのでシリーズ再判定を定期的にやる
  • 1巻で切った場合と1巻しか発売していない場合とを区別する
  • メールアドレス以外でのログイン方法を提供する
  • モバイルアプリを提供する
  • Chrome拡張がGoogleに消されたので何とかする