Shopifyでシニアプロダクトエンジニアリングリーダを務めるSimon Eskildsen氏が、GOTO Copenhagen 2017で、大規模販売をサポートするShiopifyのアーキテクチャについて、その概要を説明した。取り上げたのはOpenRestyで構成したNGINXインスタンス、ショップとポッドを分離するアーキテクチャ、フェイルオーバ戦略などの話題だ。
Shopifyは50万以上の小売店をサポートする大規模なオンラインコマースを提供している、とEskildsen氏は説明した。そこでの主な要件のひとつは、オンライン専業ショップを中心とする顧客に対して、フラッシュセールを提供することだ。販売トラフィックの運用自体は難しくないが、スパイクに対処可能なアーキテクチャの構築が大きな課題となっている。
Shoplifyにとって、最適化課題の最初のひとつはDNS層にある、とEskildsen氏は説明した。DNS層のトラフィックの最適化は、単一ドメインであれば容易だが、複数ドメインでは不可能だ。Shopifyのケースは後者で、複数の顧客ドメインがすべて独自のIPに割り当てられている。代わりに彼らが採用したのはTCP/ICPエニーキャスト、すなわち“ルーティング先IPが分かっている近隣のISPをお互いに教え合う、ゴシップ的アルゴリズム”だった。本質的にはこれによって、最も近いIPを選択してトラフィックが移されることになる。
Shopifyではまた、OpenRestyを大々的に活用している。OpenRestryはNGINXロードバランサをLuaでスクリプト化して、必要な処理を実行可能にするツールである。ShopifyでのOpenRestyは極めて有効に機能しており、業界内でもっと利用されるべきではないか、とEskildsen氏は強調した上で、同社で使用しているモジュールをいくつか紹介した。
- ルールバナー: 不定期なリフレッシュや疑わしいIPアドレスなどのパターンを監視してボットを検出し、排除する。二次流通市場をシャットダウンすることが目的である。
- エッジキャッシュ: キャッシュを最適化し、アプリケーション層ではなくロードバランサ層のキャッシュからコンテンツ提供を可能にする。
- チェックアウトスロットル: 極端な負荷環境のショップを待ち行列に入れることで書込みを制限し、同じシャード(shard)上の他のショップに対して騒々しい隣人になることを防止する。
アプリケーション層とデータ層にはポッド(pod)というコンセプトも導入した。ポッドは完全に独立したShopifyインスタンスで、多数のショップを格納することができる。ポッド間およびショップ間のコミュニケーションは不可能なように設計されている。顧客間の分離が重要であるからだ – “ショップ隔離の原則 – ショップはすべて、互いに隔離されていなければならない。”
ポッドは自分自身のステートフルサービス(データベースなど)を持つが、ステートレスなサービスは共有する。この主な理由は、自動スケーリングによって発生するボトルネックがあまりに大きいからだ、新たなインフラストラクチャをプロビジョニングできるよりも前に、トラフィックのスパイクが発生する可能性がある、とEskildsen氏は説明した。
Eskildsen氏はさらに、ポッドロードバランサの概要も紹介した。ポッド間のショップのバランスを取り、負荷が均等に分配されるようにするものだ。これを短時間に、データの一貫性を失うことなく実行するため、MySQLのバイナリログを使用して、古いインスタンスから新しいインスタンスにデータベース更新イベントをストリーミングしている。
リージョン間のマイグレーション用にはポッドムーバ(pod mover)というコンポーネントがあり、最小限のダウンタイムでポッドのリージョン間移動を行なう。これが起動するのはリージョンが機能しない場合だが、最終的にはSlackコマンドを発行することで、このタイプのフェールオーバを必要な時に発生できるようにしたい、とEskildsen氏は説明した。
講演の全内容はオンラインで公開されており、アーキテクチャのより詳細な説明を見ることができる。
この記事を評価
- 編集者評
- 編集長アクション