Skip to content

Instantly share code, notes, and snippets.

@Gab-km
Last active December 30, 2022 10:56
Show Gist options
  • Star 87 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Gab-km/5660808 to your computer and use it in GitHub Desktop.
Save Gab-km/5660808 to your computer and use it in GitHub Desktop.
何故私は Heroku から離れたか、および新しい AWS セットアップのメモ

何故私は Heroku から離れたか、および新しい AWS セットアップのメモ

原著者

Adrian Holovaty

原文

Why I left Heroku, and notes on my new AWS setup

金曜日、私は Heroku から Amazon Web Services(AWS) を直接使うように Soundslice を移行しました。私はこの変更ができてとても、そうとても嬉しくて、私がどうやったかということと、もし皆さんが同じような立場だったら何故それを検討すべきかということについて広く伝えたいと思います。

私の Heroku 体験

Soundslice はサイトを立ち上げた2012年11月からずっと Heroku 上にありました。いくつか理由があって、私は Heroku を使おうと決めました:

  • システム管理者でいるのは趣味に合わない。楽しめないし、特別得意なわけでもない。
  • Soundslice は2人でする操作(開発者とデザイナー)で、私の時間はシステム管理者としての作業よりもそのプロダクトの作業に費やした方がずっと良い。
  • Heroku はセットアップが簡単で、高トラフィックの場合にスケールさせるのも簡単だと約束してくれた。

Soundslice を Heroku 上に立ちあげて稼働している間、私はすぐに問題にぶち当たりました。例えば、彼らの Python/Django の自動検知は機能しなかったのです。自動検知が私のアプリを見つけてくれるようにするために、私は自分のコードを4, 5回(「settings.py ってこのディレクトリに入れるの?それともその下?さらにその下?」)修正しなくてはなりませんでした――この自動検知機構はとてもデバッグが難しい類のものでした。

それから、私は1.5日(!)ほどかけて Django のエラーメール機能が動くようにしていました。サーバー側はメールを送ることができて、必要なすべてのコードは Python シェルから動いていましたが、いくつかの理由によりエラーが起こってもアプリからメールが送られ ません でした。私はその問題を解明できませんでした――結局、諦めて Sentry/Raven (強くオススメします)を使いました。

他にもいくつかヘンテコなことを体験して Heroku にはうんざりしましたが、でも継続することにしました。

評価できることもあって、Heroku は Soundslice を上手く、特に問題もなくローンチしてくれました――そして、コマンドラインから heroku:ps scale を使うのはめっちゃカッコ良かったんです。12月、Soundslice は Reddit 入りを果たし 、数時間のうちに350,000人もの人がサイトを訪れてくれました。私が dyno をたくさん増やした後、Heroku はそのアクセスを良い感じに捌いてくれました。

しかし、それから数ヶ月が過ぎて、さらに数回炎上することとなりました。

まず、1月、 彼らはデプロイを壊してしまいました。何度デプロイしようとしても、ひどいエラーメッセージ を目にしました。結局、Jacob からの情報 のおかげで、異なる "buildpack" をインストールするという彼らのバグを迂回しましたが、このことは私にひどい後悔の念をもたらしました。

それから、ある4月の夕刻、私はアプリをデプロイし、Heroku はデプロイ中に Python のバージョンを上げることを決め、2.7.3 から 2.7.4 にアップグレードしました。(それ自体、何となく動揺させるもので、私はアップグレードをお願いなんてしていませんでした。しかし、私のアプリのコードは新しいバージョンでもちゃんと動いたので、それについては OK としました。)デプロイが終わったとき、私のサイトは完全にダウンしました――私のユーザーが目にしたとてもひどい Heroku のエラーメッセージを伴った ひ ど い 障害です。何が起こったのか、分かりませんでした。私の最近のコミットを大急ぎで見回し、問題を探しました。ローカルでサイトを稼働させて、ちゃんと動作していることを確認しました。ちゃんと動いていたのです。この日の最初の方はデプロイは上手くいっていて、パッケージレイアウトの根本的な変更は行なっていませんでした。

サイトが完全にダウンしたまま、ダラダラと時間を過ごした数分後、私が知る中で、ちょうどその瞬間にサイトを評価してくれていた見込み客の数名にまさにリンクを送った後――もう一度デプロイして、サイトは再び動きました。だから、これで私は一巻の終わりではなかったのです。明らかに、何かが Heroku のデプロイプロセスと一緒にぶっ壊われたのです。

これが Heroku が私の信用を失った 時でした。ここから、デプロイする度に、なにか悪いことが起こって、制御できなくなるんじゃないかと少し神経質になりました。

同じ頃、Soundslice はいくつかのコンパイル済みC拡張による Python 製モジュールと、標準の requirements.txt プロセスでは Heroku にデプロイ出来ない他の幾つもの非 Python コードを使い始めました。Heroku は コンパイルとバイナリのパッケージのやり方 を提供していて、それは上手く使えたのですが、私が root アクセスをしているサーバ上で簡単な apt-get コマンドを走らせるのではなく、プロプライエタリなプロセスを使った より多くの 作業でした。

これで、私は Heroku を離れる時だと心に決めました。私はこのブログ用にまだ Heroku を使っていますし、小さい、または捨ててもいいようなプロジェクト用に将来使うかもしれませんが、もっとちゃんとしたもの用にこれを使うのは個人的にはオススメしません。特に、パワフルな AWS のスタックを稼働するのがどれだけ簡単なことかを知った今となっては。

私の AWS セットアップ

私は幸運なことに Scott VanDenPlas と親しくしていましたが、彼はオバマ再選技術チームのDev Opsディレクターでした――ご存知ですよね、とんでもないってことでトンでもない注目 を集めた存在です。Scott は Soundslice を AWS に載せるための素晴らしいインフラをセットアップするのを手伝ってくれました。1年以上にわたって Amazon S3 と EC2 をかなりの量使っていたというのに、私は Amazon のサービス一式が如何にパワフルかを、Scott が私に見せてくれるまでさっぱり分かりませんでした。頼まれてもいない宣伝をしましょう: AWS での何かしらの作業を仕上げたかったら、Scott を絶対に雇うべきです。彼はとびっきりの1人です。

Soundslice をセットアップした方法は、比較的シンプルです。私たちはコードと依存関係を付与した特注の AMI1 を作り、それからロードベースで AMI からアプリケーション・サーバのインスタンスを生成する Auto Scaling(自動スケーリング)のルールを設定した Elastic Load Balancer をセットアップしました。私は MySQL を使うようにアプリを変換しました。詳細は次のとおりです:

ステップ1: AMI を「焼きあげる」

私は既存の vanilla Ubuntu AMI (基本的には Linux ボックスのフローズンイメージ)を素早く手に入れて、apt-get と pip を使って Soundslice に必要な幾つものパッケージをインストールしました。私は apt-get に入っていない必要ないくつかのコードをコンパイルし、アプリのコードを Git リポジトリからクローンして載せました。インスタンスに私のコード/依存関係のすべてを用意した後、そこから AMI を作成しました(EC2 ダッシュボードにある "Create Image(EBS AMI)")。

ステップ2: 自動スケーリングのルールを設定する

これは実在する魔法です。私たちはロードベースで自動的にアプリケーション・サーバーを生成するため、(Amazon ELB を使って)ロードバランサーを構成しました。これは"Launch Configuration"(ローンチ設定)と"Scaling Policies"(スケーリングポリシー)と呼ばれる設定を含みます。ここから私の Python コードを確認して 詳細をご覧ください。基本的に、Amazon は定期的にアプリケーション・サーバーを監視して、もしそのうちのいずれかが特定の CPU 使用率に到達したら、X 個の新しいサーバーを自動的に立ちあげ、起動し稼働を始めたらロードバランサーに連携させます。もしトラフィックのレベルが下がり、1、2個のインスタンスを終了させる必要があれば、同じものを適用します。本当にすごいですね。

ステップ3: 共有キャッシュを使わずにアプリケーションを変更する

AWS への移行が完了するまで、Soundslice は Django のセッションデータ用に memcached を使っていました。それぞれのサーバーが共通の memcached インスタンスへのアクセスを必要とするので、これは自動スケールされた環境ではいくつか問題を引き起こします。この問題に対処するのではなく、私はクッキーによるセッションを使うようにアプリケーションを変更したので、セッションデータは memcached ではなく署名付きクッキーに保管されました。このように、Webアプリケーション・サーバーは(データベース以外に)状態を何一つ共有する必要がなくなりました。さらに、アプリがセッションデータのために memcached を叩かなくてもいいので、エンドユーザーにとって早くなったのです。

ステップ4: MySQL への移行

イヤーッ!グワーッ!分かってます。Frank Wiles が私に光を見せてくれた2003年以来、私は筋金入りの PostgreSQL ファンです。しかし AWS 上で PostgreSQL を使うたった一つのやり方はメンテとスケールを自分自身で行うこと…そして、シス管作業が嫌いというのは、MySQL が嫌いということよりも大きいのです(・∀・) Amazonは RDS を提供していますが、これは基本的に MySQL にホストされており、マウス操作でレプリケーションを行うことができます。AWS の管理コンソール上で数回クリックして1つの利用可能ゾーンから2つにスケールしたその瞬間、私は RDS に惚れ込みました。この簡単さは驚きです。

ステップ5: Fabric でイカした API を追加する

Heroku でのデプロイはバカげてるほど単純でしたが、誂えた AWS の環境を使えば同じくらい単純にするのは簡単です――Fabric のタスクを書いて、いくつかの事前作業をする必要があっただけです。鍵は、その瞬間に何台のサーバーがあるか、あるいはそのサーバーのホスト名は何か、ということが分からないので、動的にホスト名を取得するため(素晴らしい boto ライブラリを使って)Amazon API をクエリします。私の fabfile の関連箇所は こちらからどうぞ

それから

私のアプリに必要なコードがあるときはいつでも――そういえば、新しい apt-get パッケージもね――私は AMI の単発のインスタンスを作り、パッケージをインストールし、新しい AMI としてフリーズしておきます。それから、新しい AMI をロードバランサーに連携させて、そしてそれ以降、各アプリケーション・サーバーはその新しい AMI を使います。Amazon コンソールから単に終了させることで、既存のインスタンスに新しい AMI を使わせることができます。ロードバランサーはインスタンスが終了したことを検知し、スケーリングのルールに従って、新しい AMI から新しいインスタンスを立ち上げるでしょう。

AMI 自身にパッケージを「焼く」かわりに、起動時に新しいサーバーのそれぞれに必要なパッケージを自動的にインストールするために ChefPuppet を使う、というのが別のアプローチになるでしょう。不必要に複雑だったので、私たちはこうしないことを選びました。アプリは作成済み AMI を使うやり方が申し分なく機能するぐらい、十分シンプルです。

すべてをまとめると、あなたにはとてもパワフルなセットアップがあって、私が言いたいことは、ちょうど Heroku (前にセットアップした!)と同じくらい使うのが簡単で、加えてマシンの root にアクセスする全権、あなたがインストールしたいものなら何でもインストールできること、スケーリングのルールを設定できること、などなど。さぁ、やってみよう!


訳注


  1. Amazon Machine Image の略。インスタンスのルートパーティションのイメージ

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment