DUICUO

Instagramの背後にあるテクノロジーを理解する

[丁雪峰はInfoQ Chinaの編集者であり、Manjianghong翻訳チームのコアメンバーです。彼女は『Spring Strategies』や『JRuby in Action』など、複数の翻訳著作を出版しています。主な専門分野は、エンタープライズアプリケーション、大規模データコンピューティング、動的言語アプリケーションです。]

Facebookが最近10億ドルで買収した人気モバイル写真共有アプリ「Instagram」は、大きな注目を集めています。Android版はGoogle Playで1ヶ月足らずで1,000万ダウンロードを突破し、ユーザーベースは5,000万人に迫っています。Instagramの共同創設者であるマイク・クリーガー氏は、オリジナルのInstagramの構築には8週間を費やしたと述べていますが、現在のシステムは確かに大きく異なります。Instagramの技術チームは以前、Instagramの技術を紹介する記事を公開しており、最近の「Scaling Instagram」と題した講演でマイク・クリーガー氏はさらに詳細を語り、5人のエンジニアがどのようにシステム全体を支えていたかを明らかにしました。

写真をアップロードする手順は次のとおりです。

メディア データベースに同期的に書き込みます。

写真にジオタグが付いている場合は、非同期的にインデックス作成のために Solr に送信されます。

Redis に保存されている各フォロワーのリストに写真の ID を追加します。

フィードを表示するときに、写真 ID の小さなサブセットを選択し、Memcached でクエリを実行します。

Instagram のシステムを設計する際の設計哲学は、シンプルさ、運用上の負担を最小限に抑える最適化、すべてのコンテンツの監視です。その基本原則は、物事をシンプルに保ち、車輪の再発明を避け、可能な限り実績のある安定した信頼性の高いテクノロジーを使用することです。

技術スタッフはわずか5名(バックエンドエンジニアはわずか2.5名)でリソースも限られているため、Amazonのクラウドサービスを選択することは賢明な選択でした。現在、100台以上のEC2インスタンスを使用して様々なサービスを提供しています。Ubuntu 11.04は、以前のバージョンでは高トラフィック時に安定性が低かったためです。負荷分散にはAmazonのElastic Load Balancerを使用し、バックエンドでは3つのNginxインスタンスを稼働させています。SSLはELBのみに適用され、NginxのCPU負荷を軽減しています。DNSとCDNは、それぞれAmazonのRoute 53とCloudFrontによって提供されています。すべての写真はS3に保存されており、現在数テラバイトの容量に達しています。

リクエストを処理するアプリケーションサーバーは、Amazon High-CPU Extra-Large Instances 上で実行されます。これらのインスタンスは、リクエストがCPU負荷が高いため、CPUとメモリの使用量をよりバランス良く調整します。開発フレームワークにはDjango、WSGIサーバーにはGunicornが使用され、デプロイはFabricを介してすべてのマシンに並列で行われ、各デプロイにはわずか数秒しかかかりません。

データの大部分はPostgreSQLに保存されています。プライマリシャードクラスターは、12個のハイメモリ4倍超大型インスタンス(メモリ容量68.4GB)で稼働し、さらに異なるアベイラビリティゾーンに配置された12個のレプリカがrepmgr経由でストリーミングレプリケーションによって同期されています。Elastic Block StoreのディスクIOPSは比較的低いため、使用中のデータはメモリにロードする必要があり、vmtouchはこのメモリ内データの管理を支援します。書き込みスループットを向上させるため、EBS上にmdadmを用いたソフトウェアRAIDを実装しました。データベースはファイルシステムとしてXFSを使用し、スレーブデータベースからスナップショットを取得する際には、スナップショットの一貫性を確保するために、まずRAIDアレイをフリーズします。

アプリケーションがデータベースに接続すると、Pgbouncerは接続プールを確立します。現在、InstagramのデータはユーザーIDごとにシャーディングされています。シャードによっては物理ノードの容量制限を超える可能性があるため、データは多数の論理シャードに分割され、複数の物理ノードにマッピングされます。ノードが満杯になった場合、一部の論理シャードを他のノードに移動することで、そのノードの負荷を軽減できます。将来的には、データ量の増加に合わせて垂直パーティショニングも実装される予定で、Django DB Routerによってさらに容易になります。

Instagram は、メインフィード、イベントフィード、チャットシステム、その他の関連システムにおいて、複雑なオブジェクト(サイズ制限あり)の保存に Redis を多用しています。Redis のデータはすべてメモリ上に保存する必要があるため、ハイメモリ クアドラプルエクストララージインスタンスを使用し、データをシャーディングしています。Redis インスタンスのリクエストレートが 1 秒あたり 40,000 リクエストに達すると、徐々にボトルネックになりました。そこで、マスター・スレーブ・レプリケーションを実装し、レプリカデータを頻繁にディスクにエクスポートし、EBS スナップショットを使用してバックアップしました。

Redisに加え、キャッシュにはMemcachedも使用しており、現在6つのインスタンスが稼働しています。アプリケーションサーバーはpylibmcとlibmemcachedを介して接続します。AmazonはElastic Cacheを提供していますが、安価ではないため、自社でMemcachedインスタンスを運用する方がコスト効率が良いです。非同期タスクキューにはGearmanを使用しており、約200のワーカープロセスでTwitterやFacebookへの写真の共有、ユーザーへの新着写真の通知など、様々なタスクを処理しています。Pyapnsはすでに10億件のプッシュ通知を処理しており、非常に安定しています。また、Androidデバイスへのプッシュ通知送信用に、Node.jsベースのnode2dmも独自に開発しています。

Instagramは監視のためにMuninを使用し、システム全体のステータスをグラフィカルに表示するほか、Python-Muninを使用してビジネスデータを表示するためのプラグインもいくつかカスタマイズしています。ネットワークデーモンStatedはリアルタイムでデータを収集・要約し、Dogslowはプロセスを監視し、実行に時間がかかりすぎるプロセスのスナップショットを保存して後で分析できるようにします。例えば、応答時間が1.5秒を超えるリクエストは、通常、Memcachedの`set()`メソッドと`get_many()`メソッドでスタックしています。Pythonエラーについては、Sentryにログインするだけでリアルタイムにエラー情報を取得できます。

HighScalability は、Mike Krieger 氏の講演から得られた次のような貴重な教訓もまとめました。

使い慣れたテクノロジーとツールを見つけて、まずは簡単なユースケースで試してみましょう。

同じタスクを処理するために 2 つのツールを使用しないでください。

必要に応じて負荷を軽減できるように、事前に低下計画を準備します。

過度に最適化したり、サイトの拡張が必要になることを事前に把握しようとしたりしないでください。スタートアップのソーシャルネットワーキングサイトにとって、解決できないスケーラビリティの問題はありません。

1 つの方法が機能しない場合は、すぐに次の方法に切り替えます。

Instagram の技術的な詳細について詳しく知りたい場合は、Instagram の技術チームのブログをご覧ください。

[編集者のおすすめ]

  1. Instagramを支えるオープンソース技術
  2. テクノロジーを理解していない人は、テクノロジーを理解している人に、テクノロジーは簡単に実現できると言うべきではありません。
  3. Maxthon ブラウザの新バージョンリリースは、ビデオ デコード テクノロジーの饗宴です。