Michael Brown
Jan 27, 2015 • 4 min read
以前、Discourseサーバーのハードウェアについてお話ししました。今回はDiscourseネットワークについてお話しします。社会的な意味ではなく、物理的・ソフトウェア的な意味でのネットワークです。私たちはサーバー上でどのようにDiscourseをホストしているのでしょうか?
Discourseでは、超高速で手作りのコロケーション物理ハードウェア上でのホスティングを好んでいます。クラウドは特定の用途には最適ですが、Stack Exchangeと同様に、自社ハードウェアで運用するという決断を下しました。Rubyが私たちのテストでは仮想化がうまくいかなかったため、その決断は正しいものとなりました。
全体像
(そうです、これはDiaで作成しています。提供されているテンプレート画像が前世紀のものであるとはいえ、ネットワーク図作成においては今でも最速のツールです。)
タイ・インターセプター
アプリケーションへのインターネット全体からの攻撃に耐えられるよう、帝国の最高の技術がすべての前面に配置されています。
tieinterceptorサーバーはいくつかの重要な機能を担っています。
- イングレス/エグレス: 職人手作りのiptablesファイアウォールルールがすべての受信トラフィックを制御し、特定のトラフィックがネットワークから外に出られないようにします。
- メールゲートウェイ: インターセプターはメールが宛先に届くよう支援する役割を担っています。DKIMの署名、ハッシュキャッシュ(場合によっては)の署名、ヘッダーのクリーンアップを行います。
- haproxy: haproxyを使用することで、インターセプターはロードバランサーとして機能し、リクエストをWebティアに振り分け、レスポンスを調整します。
- keepalived: VRRPの実装のためにkeepalivedを使用しています。「haproxyが動作していない場合、このノードは優先されるべきではない」といったルールをkeealivedに設定し、そのルールに基づいてアクション(この場合、インターネット向けネットワークへの共有IPv4(およびIPv6)アドレスの追加または削除)を実行します。
タイ・ファイター(Web)
タイファイターは私たちのデス・スターの大艦隊、つまりDockerサーバー群を表しています。小さく、速く、同一の構成を持ち、多数存在します。
これらはステートレスなDockerコンテナ内でDiscourseサーバーアプリケーションを実行しており、Jenkinsを使ったDiscourseの継続的デプロイを簡単にセットアップできます。
各Dockerコンテナ内で動作しているものは何でしょうか?
- Nginx: Webサーバーなしにはウェブは成り立ちませんよね?最速の軽量Webサーバーの一つであることから、Nginxを選択しました。
- Unicorn: Discourseを提供するRubyプロセスの実行にはUnicornを使用しています。Unicornの数が増えるほど、同時リクエスト数も増えます。
- Anacron: サーバーのスケジューリングはAnacronが担当しており、コンテナが再起動またはオフラインになった場合でも、スケジュールされたコマンドとスクリプトを追跡し続けます。
- Logrotateとsyslogd: ログ、ログ、ログ。すべてのコンテナはsyslogdを介して大量のログを生成し、ログのローテーションと最大ログサイズの管理にはLogrotateを使用しています。
- Sidekiq: RubyコードレベルのバックグラウンドサーバータスクにはSidekiqを使用しています。
共有データファイルは、3-Distribute 2-Replicateのセットアップを使用して、Webティアのホスト間で共有される共通のGlusterFSファイルシステムに永続化されています。Glusterはかなりよく機能していますが、変更に対する耐性はあまり高くないようです。ノードの交換や再構築は、RAID10アレイからディスクを引き抜いて新しいものを挿し込み、レプリケーションがうまくいくことを祈るような、胃が痛くなる作業です。分散ファイルシステムストアとしてCephを検討したいと思っています。S3のようなインターフェースとマルチマウントPOSIXファイルシステムの両方を提供できるためです。
タイ・ファイター(データベース)
新しいSSDを搭載した3台のタイをPostgresデータベースサーバーとして使用しています。
- 1台はビジネスクラス(多数のサイトをホスティングする単一のDiscourseアプリケーションイメージ)コンテナとスタンダードティアプランのデータベースをホストします。
- 1台はエンタープライズクラスのインスタンスのデータベースをホストします。
- 1台はこれら両方のスタンバイです。プライマリDBMSからのストリーミングレプリケーションログを受け取り、深刻な障害が発生した場合にプロモートされる準備が整っています。
タイ・ファイタープライム
グループの中で最も強力なマシンはtiefighter1です。他のすべてのタイとは異なり、8プロセッサと128GBメモリで構成されています。過去1年間、このサーバーにできるだけ多くの作業を割り当てるよう努めてきました。その結果は成功と言えるでしょう。
ユーティリティおよびVMサーバーとしての側面もありますが、このサーバーが担う最も重要な役割の一つがredisのインメモリネットワークキャッシュです。
redisインスタンスを適切に分離することは、しばらく前から私たちの課題でした。すでにパーティショニングのために別々のデータベースを使用するよう設定されていましたが、それでもインスタンスが互いに影響を及ぼす可能性がありました。特に、同じredisサーバーに接続しながら異なるredisデータベースを使用するマルチサイト構成がその例です。
ひらめきがありました。redisサーバーが提供するパスワード機能を使って、同じパスワードを使用する接続を自動的に専用の独立したredisバックエンドに振り分けるというものです。新しいパスワードを設定すると、そのパスワードに紐付けられた新しいインスタンスが自動的に作成されます。分離、セキュリティ、使いやすさ。数日後、Samがredismuxを持って戻ってきました。9月にDocker内に移行されてから、順調に稼働し続けています。
Jenkins
Jenkinsは「すべての」内部管理ルーティンを担っています。自動化できるのに、なぜ同じ作業を何度も繰り返すのでしょうか?もちろん、最大の課題はビルドとデプロイメントのプロセスです。GitHubの更新時に自動的に実行される一連のジョブが設定されています。
メインのGitHubリポジトリへのプッシュから本番環境でコードが動作するまでの総所要時間は12分で、そのうち8分は新しいマスターDockerイメージのビルドに費やされています。
Discourseのホスティングにおいて、ある程度安定した構成に到達するまでに約1年(そして非常に多くのDockerとDiscourseのベータ版)を要しました。この構成は時間とともに変化し続けると確信しており、成長に合わせてスケールアウトを続けていく予定です。
原文はこちら:
Good Loopでは、Discourseのセルフホスティングを安価で提供しています。開発元であるCDCK社の協力のもと、公式ブログ記事の翻訳・公開など、日本での普及にも努めています。




