ITエンジニア必見の夏の祭典「July Tech Festa 2018」レポート
ソフトウェアで構築する成長し続けるインフラストラクチャとメルカリの挑戦
招待講演のスピーカーは、株式会社メルカリのプリンシパルエンジニア・SREの長野雅広氏。メルカリといえば、最大手のフリマアプリだ。写真を撮って商品情報を入力し、出品ボタンを押すだけで簡単に出品できる。最近は機械学習を利用して写真からブランドやカテゴリを自動入力する機能も実装されている。さらに、出品者と購入者の間にメルカリが介在するエスクロー決済や匿名配送で安心安全な決済・取引を実現している。
現在メルカリは日本だけでなく、アメリカとイギリスでもサービスを展開している。2018年3月時点で、3ヶ国の累計ダウンロード数は1億800万を突破し、月間利用者は日本だけで1050万人に及ぶという。流通総額は2018年1月から3月までの3ヶ月間で938億円を超えた。また、簡単出品を突き詰めた結果、2018年7月13日には累計出品数が10億に達した。ピークリクエスト数は、なんと1分間で340万にもなるという。この大規模なサービスのインフラストラクチャを見ていこう。
まず、2017年と2018年のインフラストラクチャを比較してみよう。日本ではSAKURA internet、アメリカではAWS、そしてイギリスではGCPといったように、各国でインフラストラクチャが異なるのが2017年の特徴だ。これが2018年になると、日本とアメリカは既存のクラウドサービスに加えてGCPを組み合わせていることがわかる。新たにCDNでクラウド画像変換サービスのImageFlux、モニタリングのマイクロサービス化でDatadogを採用している。
次に、メルカリがリリースされた2013年から2017年まで、どのようにサービスを拡大してきたのかが紹介された。2013年7月、日本でリリースされた時はさくらのVPS 1台にWebもDBもまるっと載っていたそうだ。インフラエンジニアがいなかったため、AWSではなく、開発者に利用経験のある基盤としてさくらインターネットが選ばれたという。冗長化や高負荷時の対策がされていなかったため、リリース2ヶ月後の負荷が上がってきたタイミングで、さくらの専用サーバに移行した。MaaSなのでパフォーマンスが高く、さくらクラウドに接続できるのも特徴だ。
2014年、アメリカでリリースされた時はAWSを利用していた。これはさくらインターネットがアメリカではサービスを展開していなことも一因だが、開発者にAWS経験者が増えてきたこともAWS選択の理由だったという。この時もインフラエンジニアは少なかったため、RDSやElastiCacheなどのマネージドサービスを使用してサービスを構築した。物理サーバを設置しなかったのは、アメリカでのサービス成長予想が困難であり、日本よりもクラウドの柔軟さを重視したからだと説明した。
そして2015年11月にはSREチームが発足し、日本とアメリカのアーキテクチャ改善でサービスの信頼性とスケーラビリティの向上に取り組んでいる。具体例として、memcachedを活用したDBの負荷軽減、N+1問題への対策、SQLチューニング、APIによってMasterとSlaveを使い分ける工夫を挙げた。またDB以外では、SPDYをHTTP/2に変更したほか、PHPのアップグレードや最適化も実施している。
メルカリのアーキテクチャは、nginx、アプリケーションサーバ、DBの3層構成になっている。マネージドサービスをサーバにリプレイスし、できる限り共通のアーキテクチャを採用している。このような取り組みでオペレーションが共通化することによって、少人数での運用が可能となるというわけだ。
2017年のイギリスでのリリース時は、GCPでサービスを構築した。新しい技術ではあるが、前述したアーキテクチャの共通化やAnsible Playbookの再利用により、実績のある基盤でサービスを開始することができたと当時を振り返った。
続いて、インフラストラクチャを支えるソフトウェア事例が紹介された。1つ目のConsulは、サービスディスカバリーやコンフィグレーションデプロイメント、分散ロックなどの機能を備えるツールだ。キーワードサジェストの事例をみてみよう。Solrにインデックスが入っているDockerイメージをデプロイし、定義しておいたservice.jsonをConsulに読ませてURLをたたくと、2つ動いていたらIPアドレスが2つ返ってくる。負荷が高くなった時にもう1つ追加したり、メンテナンス時にconsul maintコマンドでリクエストを瞬時に止められたりするのがメリットだ。
さらに、無停止のIndexアップデートもConsulで実現している。consul lockコマンドで分散ロックし、新しいDockerイメージがあればメンテナンスモードでアップデートしてメンテナンスモードを解除する。これにより、お客様のリクエストに全く影響なくDockerイメージを更新することができる。
続いて紹介されたOpenRestyは、nginxをベースに作られたWebプラットフォームだ。nginx coreをはじめ、LuaJITやLuaライブラリ、C言語の各種サードパーティモジュールで構成されている。大量のリクエストを処理できるnginxのスケーラビリティを保持しつつ、様々な拡張が可能となっている。メルカリではアプリケーションサーバでOpenRestyを起動して、グローバル側のnginxとOpenRestyの間はHTTP KeepAliveが有効となっており、TCP接続回数を減らすことでパフォーマンスを向上できる。
メルカリは特定の商品への購入処理が集中するとSELECT FOR UPDATEでのロックが数百も滞留し、Busy LockによりCPU使用率が急上昇してDBが反応しなくなるという問題を抱えていた。その解決策としてDBへの問い合わせより前に並列度を調整することを挙げたが、PHPでwaitするとApacheのプロセスが枯渇する可能性があるため、OpenRestyで並列度を調整しているということだ。
ここで話題は、インフラの歴史に戻る。2017年から2018年にかけて、メルカリのサービス全体をマイクロサービスアーキテクチャに切り替える取り組みを行っている。目的は細かい単位でのスケーリング、障害を分離してサービスのレジリエンスを向上させることと、サービス開発の速度を上げてチーム・組織のスケーラビリティを高めることだ。最終的には1000人以上のエンジニアが在籍していても、うまく回る組織を構築するのがマイクロサービス化の狙いだ。
マイクロサービス化については、日本よりもアメリカで先行している。アメリカのマーケットに最適化するために、クライアントを更新した。プロトコルはJSON over HTTPSからProtocol Buffers over HTTPSに変わり、これを受けるAPIゲートウェイから各マイクロサービスにリクエストを送る。AWSのMonolith APIに対しては、従来通りJSON over HTTPSでリクエストを送ることで、徐々にマイクロサービスに移行することができる。
また、3つのリージョンで共有していたMonolith APIのコードをアメリカ、イギリスと日本で分離した。これにより、自リージョンのコード変更が他リージョンに影響がないか調整するコストを削減し、各国の事情に合わせた開発を各国で行うことができるようになった。
日本でもマイクロサービス化を進めるためにAPIゲートウェイを導入した。日本ではクライアントのアップデートがないためプロトコルを維持し、先ほど紹介したアメリカのAPIゲートウェイとは全く別のAPIゲートウェイを実装している。
マイクロサービス化を進めるにあたり、インフラストラクチャをソフトウェアで実現している。本セッションではDocker、Kubernetes、Spinnaker、Terraformの4つが紹介された。
Dockerはコンテナ型の仮想環境で、リソースを分離して制御できる。Dockerfileによる一貫したイメージの作成や、開発環境を本番環境に持っていけるポータビリティが特徴だ。Kubernetesはオーケストレーションプラットフォームで、コンテナ数を調節するスケーリング機能、ノードが落ちた場合に別ノードで復旧するヒーリング機能などでコンテナ運用のコスト削減を実現している。SpinnakerはContinuous Deliveryプラットフォームで、Dockerイメージのpushやcronなどをトリガーとして、定義されたPipelineに沿ってデプロイを自動で実行する。TerraformはInfrastructure as Code(インフラストラクチャをコードで管理、IaC)によってDevOpsを実現する。メルカリではマイクロサービスを素早く立ち上げるスターターキットを提供しており、GCPプロジェクトやKubernetesのNamespace、GitHubのチームを作成する機能などが盛り込まれている。
ここからは、マイクロサービス化の課題が取り上げられた。大きな課題となっているのは、データセンターのある石狩と東京間の約1,000kmという物理的な距離だ。普通にpingを打つと、ラウンドトリップタイムは約17ms。メルカリのAPIの多くは45ms程度でレスポンスがくるので、約17msのラウンドトリップタイムはボトルネックになり得る数字だ。HTTPSで通信するとハンドシェイクでラウンドトリップタイムの約17msが積み重なり、トータルで205msもかかってしまう。
物理的な距離は縮められないため、ソフトウェアによる改善を試みているという。具体的にはHTTP/1、HTTP/2のKeepAliveを活用してTCPの3ウェイハンドシェイクとTLSのハンドシェイクを避けるのだが、PHPはリクエスト間でHTTPコネクションの再利用ができないので、choconというミドルウェアでコネクションをアグリゲーションする。
Hostヘッダに「example.jp.ccnproxy-https」をつけてchoconにリクエストを送ると、HTTPS通信に切り替えて「example.jp」にプロキシリクエストを送るのだが、内部DNSと組み合わせることで、APIエンジニアはURLを変えるだけでchoconを利用できるようになるよう工夫されている。choconを利用したHTTPS通信はトータル21msとなり、利用前の205msから大幅に短縮された。choconは通信のレイテンシを低減する重要なサービスなので、Consulで冗長化している。ここはキーワードサジェストで紹介した事例と同様だ。
メルカリのインフラストラクチャは、ソフトウェアによって可用性とパフォーマンスを向上していることがおわかりいただけただろう。最後に長野氏は、SREはオペレーションのプロフェッショナルとしてサーバの能力を引き出し、アプリケーションエンジニアが作成したコードを最高の形で動かすことがその役割だと説明した。サービスの可用性はインフラだけの問題ではなく、ソフトウェアを扱うチームにも責任があるとした上で、お客様に「いつでも快適に安全に使える」信頼性をどのように提供していくかをいつも意識していると述べ、セッションを締めくくった。
連載バックナンバー
Think ITメルマガ会員登録受付中
全文検索エンジンによるおすすめ記事
- Oracle、「Java 16」を発表、「OpenJDK 16」リリース
- Oracle、Java Standard Edition 10の実装「JDK 10」を発表
- 「Java SE 12」リリース
- Oracle、「Java 23」をリリース
- JPCERT、「Oracle Java SE JDK」および「JRE」に複数の脆弱性が存在すると発表、早急なアップデートを推奨
- Oracle、「Java 22」をリリース
- Oracleが2021年4月の定例アップデートをリリース、「Oracle Java SE」「MySQL」「Oracle VM VirtualBox」など
- 「JDK 17」がLTS版としてリリース
- 「JDK 17」がLTS版としてリリース
- JPCERT/CC、Oracle Java SE の脆弱性に関する注意喚起