LINE Shopチームの担当サービス

松崎学氏:それでは「LINE Shopチームのあけおめ対応」というお話をさせていただきます。松崎と言います。よろしくお願いします。SREを担当しております。

今日のアジェンダですが、まず最初に背景を知っていただこうと思っています。僕たちのチームの紹介と担当しているサービスの紹介。そして、サービスのアーキテクチャを簡単にご説明します。

次に、僕たちのチームで年末年始にどのような取り組みを行なっているかについてお話をします。最後に、今年の正月がどんな感じだったのか、また来年に向けての改善事項などをお話しさせていただきます。

では、最初にチームの紹介と開発しているサービスの紹介をさせてください。実はLINE Shopという名前のサービスは存在していなくて、僕たちのチームの名前や担当している機能などを指して社内ではLINE Shopと呼んでいます。

僕たちのチームではLINEサービスにおけるスタンプ、絵文字、着せかえなどのコンテンツを利用、販売するためのプラットフォームを開発運用しています。みなさんLINEでスタンプや絵文字や着せかえを使っていただいたり、購入していただいたことがあるかもしれません。その機能を担当しているのが僕たちです。

スタンプなどのコンテンツは、スマホのLINEアプリだけではなく、Webのストアからも購入していただくことができます。また、LINEアプリの一番右にウォレットというタブがあるんですが、それに携わっているメンバーもいます。

僕たちはサーバーサイドのチームで、メンバーは今、福岡と東京合わせて25人くらいいます。

ふだんはいろいろなチームと一緒に仕事をしています。僕のセッションの前に発表された竹下さんたちアプリケーションエンジニアや、Webのフロントエンドエンジニア、DBA、モニタリングプラットフォームチーム、インフラチーム、データ分析チームなどですね。

次に、サービスの規模感がどれくらいかというお話です。これは今年の3月に出たプレスリリースからの抜粋です。今年の3月時点で販売中のスタンプが855万セット。ユーザーのみなさんが送信される1日あたりのスタンプの送信数が、去年の4月あたりで平均4億3300万回。そして、1秒あたりのリクエスト数がふだんのピークだと毎秒5万リクエスト。イベントや新年のタイミングでは毎秒10万リクエストとなっています。

次に、去年と今年にリリースされたいくつかの新機能について少しだけご紹介させてください。これは去年リリースされたカスタムスタンプという機能です。スタンプのテキストの一部をユーザーのみなさんが自由に変更して使っていただけるスタンプです。

次は、LINEスタンプ プレミアムですね。これは先ほど竹下さんからご紹介があった機能です。これも去年リリースされたものですね。いわゆるサブスクリプションモデルで、毎月定額で300万種類以上のクリエイターズスタンプが使い放題になります。

そして、これが一番最近のもので、今年の3月にリリースされたメッセージスタンプという機能です。先ほどのカスタムスタンプと違って、決まった範囲内のテキストをより自由に、より長文で使っていただけるというものになります。ここまではサービスの紹介でした。

LINE Shopサービスのアーキテクチャ

次に、アーキテクチャを簡単にご説明します。青い枠の中が僕たちのサービスです。

僕たちはマイクロサービスアーキテクチャを採用しています。青い枠の左上がWebのストアで、そのとなりのshop-proxyというのがLINE Shopにおける、いわゆるAPI gatewayです。

そしてその上、青い枠の外にあるLEGYというのが、LINE自体のgatewayサーバー。そのとなりのtalk-serverというのがLINEのメッセージングのアプリケーションサーバーです。これらは僕たちとは別のチームが開発運用しています。

次に、データベースなども含めた概要をお話すると、実際はもうちょっと複雑なのですが、こんな感じですね。

主要なものだけ簡単にご紹介しておきますと、データベースは用途に応じていくつか使い分けています。MySQLとMongoDBとElasticsearch。そしてキャッシュ用途としてRedisを使っています。

それぞれの役割ですが、WebのLINE STORE。あとは先ほどもご紹介したshop-proxyですね。そしてshop-serverがshop-proxyの下にあるやつですね。これがほかのマイクロサービスを取りまとめています。

そして、search-feがElasticsearchへの検索機能を提供しているマイクロサービスになります。そして、ownership-serverとcapability-serverというのがユーザーのみなさんが所有しているスタンプなどのプロダクトに関する機能を提供しているマイクロサービスになります。

フレームワーク「Armeria」とモニタリング

次に、フレームワークやモニタリングについてもう少しご紹介します。LINEではArmeriaというJavaで書かれたマイクロサービス向けのフレームワークを開発してGitHubで公開しています。僕たちもArmeriaを使っています。

Armeriaはマイクロサービスアーキテクチャでサービスを開発運用するための機能を持っています。例えば、RPCとしてREST、Thrift、gRPCをサポートしています。またそれぞれのマイクロサービス間の通信としてHTTP2を採用することができます。

またService DiscoveryやCircuit Breaker、Prometheus Metricsのサポート、Zipkin Integrationなどもあります。

モニタリングに関しては、社内の専任のチームが別にいて、彼らがモニタリングの基盤を提供してくれているので、僕たちはそれを使ってサービスのモニタリングをやっています。現在はIMONという内製のモニタリングシステムとPrometheusと両方使っています。

どういうメトリクスをモニタリングしているかというお話ですが、いくつか主なものを紹介しておくと、サービスのレイテンシー。これは50パーセンタイルとか90パーセンタイルとか99パーセンタイルとかですね。

あとは、ログの量やJVMのメトリクス。それからサーバーの負荷。こういったものをモニタリングしています。ここに貼ってあるスクリーンショットはレイテンシーですね。

次に実際のログです。アプリケーションからロガーで出力するログはElasticsearchに貯めていてKibanaで見ています。次にZipkinですね。これはマイクロサービス間で例えばボトルネックがあった場合に、どこでどのくらいの時間がかかっているかを調査するときに使っています。

このスクリーンショットの例だと、shop-serverがsearch-feを呼んで、search-feがキャッシュから取れるものはキャッシュから取りつつElasticsearchに検索を行なって結果を返しているのが見てとれるかなと思います。それぞれの右側の部分でそれぞれが何ミリ秒かかっているといったことも見れるようになっています。

新年にトラフィックが増える要因

次に、新年のときの僕たちのサービスのトラフィックについてです。新年は僕たちのサービスにとって最もトラフィックが増えるイベントの1つです。

いくつか要因がありますが、1つ目が新年の挨拶ですね。いわゆる「あけおめLINE」と言われているやつです。そしてもう1つが、毎年やっている新年のキャンペーンですね。今年はLINEのお年玉という名前でキャンペーンを実施しました。

もう1つの要因としては、みなさん「LINEスタンプ」というLINE公式アカウントがあるのをご存知でしょうか? このアカウントと友だちになっているとおすすめのスタンプや新作のスタンプの販売、キャンペーンのお知らせなどが届くようになります。

このアカウントと友だちになっていただいてるユーザー数が今年の2月時点で5,700万人。現在は6,000万人を超えていて、前年比で1.5倍くらいになっています。それだけたくさんのユーザーに対してお知らせを出すので、ふだんからそれをトリガーにしたリクエストもけっこう多いです。年末年始だととくに増えます。

ここまでのまとめです。僕たちのチームではLINEサービスにおけるスタンプ、絵文字、着せ替えなどに関わる機能を開発運用しています。いくつかの数字を例に出してサービスの規模をご説明しました。

販売中のスタンプ数だったり、ユーザーのみなさんが1日に送信されているスタンプ数だったり、1秒あたりのリクエスト数だったり。そしてサービスのアーキテクチャについて簡単にご紹介しました。

そして新年は僕たちのサービスにとって最もトラフィックが増えるイベントの1つです。要因としては新年の挨拶、新年のキャンペーン、あとはLINE公式アカウントからのお知らせメッセージなどがあります。

トラフィックを捌くためのキャパシティ計測

それでは次に、トラフィックを捌くために実際にどんな準備や作業を行なっているかというお話をさせていただきます。

まずはキャパシティ計測をします。それぞれのマイクロサービスについてサーバー1台あたりどのくらいのリクエストを捌くことができるのかを計測します。

次に、その計測結果と過去のイベントの記録をもとにサーバーのスペックや台数を決めていきます。実際にどうやってキャパシティを計測しているかについてですが、現在のところ実際の本番サーバーでモニタリングしながらサーバーを少しずつ減らしてどのくらい捌けるかを計測しています。

今後はより安全に計測を実施できるように改善していきたいなとは思っています。いくつか案はありますので、少しだけあとでご紹介したいと思います。

そして、この計測中にどういったメトリクスに注目してモニタリングしているのかというお話ですが、まずは1サーバーあたりのリクエスト毎秒、あとはレイテンシーとエラー数ですね。

ここにあるスクリーンショットが実際の作業のときのものですけれども。サーバーを減らしていくのでサーバー1台あたりの毎秒のリクエストが増えていっています。そして下がレイテンシーですね。

あとはエラーが増えてないかとか、レイテンシーが悪化してないか。このあたりを見ながら作業しているということになります。他には、CPU使用率だったりネットワークトラフィックだったり、JVMのGCなど。このあたりもモニタリングをします。

先ほど少し話に出した、今後より安全にキャパシティ計測を行うためのアイデアですが、サービスインしているサーバーを減らすのではなくて、サーバーごとのリクエストの割合を調整するようにすればより安全に作業ができるかなと思っています。

例えば、ロードバランシングのアルゴリズムを重みづけRound Robinにして、特定のサーバーだけリクエスト数を増やしていくといったことですね。

また、ほかにはテスト環境で負荷テストを継続的に行うと。これについては、実際の本番のリクエストと同等な負荷をテストで再現するのはちょっと難しいかもしれないなとは思っています。ここまではキャパシティ計測のお話でした。

過去のデータをもとにサーバーの台数とスペックを決める

計測ができたら、その計測結果と過去のイベントのときのサーバーの負荷状態やどのくらいのリクエストが来たかなどの情報をもとに、今回のサーバーの台数とスペックを決めていきます。

例えば、想定される毎秒のリクエストが1万で、1サーバーあたり1,000リクエストを捌ける場合なら、サーバーは10台必要ですねという感じで決めていきます。なので、過去のデータが大事ということですね。新年以外でもリクエストが多いイベントがいくつかありますので、そういったときもきちんと記録を取ってまとめておくということがサーバー増強のときには役に立ってきます。

そして、DBサーバーの負荷も気をつけないといけません。例えば、アプリケーションサーバーがボトルネックになっている場合に、アプリケーションサーバーを単純に足しただけだとDBサーバーが次のボトルネックになるというのはよくある話かもしれません。弊社の場合、DBAがDBサーバーの管理をしてくれているので、DBAと一緒にそのあたりの話を進めています。

あとは、アプリケーションサーバーを追加したときに起こり得るかもしれない問題として、DB側のmax connectionsの制限に引っかかるというのが1つ考えられますね。

今回は、いくつかのマイクロサービスにおいてサーバーをよりハイスペックなサーバーにリプレイスを行いました。けっこう台数も増えてきていて、このまま同じスペックで増やすよりもハイスペックなものにリプレイスしたほうがいいかなという判断です。

サーバーを減らすことでDBサーバーとの接続を減らすことができます。また、僕たちはAnsibleを使ってプロビジョニングをやっているのですが、その時間を短縮する事ができます。あとは、サーバーの台数が減るので、運用に関するコストも下げることができると思っています。

実際の2020年の正月の結果

では次に、今年の正月の結果がどうだったかというお話です。これは実際の、今年の1月1日0時0分付近のチャートです。毎秒のリクエストのチャートですね。先ほどイベントや新年では10万リクエスト毎秒というお話をしましたが、今年は例年よりリクエストがかなり多かったです。

例えば、shop-proxyだと前年比の1.7倍、12万4000リクエスト毎秒。そしてsearch-feでは去年の4.9倍、14万2000リクエスト毎秒のリクエストが来ていました。

ですが、残念ながら、先ほどご紹介したカスタムスタンプの機能でサービスの障害が発生していました。ユーザーのみなさまにはご不便をおかけして申し訳ありませんでした。

原因は、想定以上のリクエストが来たことによるサーバーのリソース不足です。なのでもっとサーバーを追加する必要がありました。

その背景なんですが、カスタムスタンプは先ほどお話したように2019年にリリースされた機能なので、参考にする前年の実績がないという状態で、正しい見積もりができていなかったということになります。また、当日サーバーの追加を緊急で行なったんですけど、その作業も時間がかかってしまいました。

しかし、幸いにもこの障害の影響はカスタムスタンプの機能だけにとどまり、ほかのカスタムスタンプ以外の機能については影響が出ていませんでした。これはマイクロサービスアーキテクチャを採用する利点の1つです。よく設計されたマイクロサービスというのは、サービス全体へのインパクトを軽減することができます。

ポストモーテムで改善のための議論を

最後に、来年に向けた改善のお話です。SREのプラクティスの1つとしてポストモーテムというのがありますが、LINEでも以前からこの取り組みを行なっています。僕たちのサービスの場合、サービスの障害が発生したら関係するチームと一緒にポストモーテムのミーティングを開催し、改善のための議論を行います。

そのポストモーテムのレポートには、このような内容をまとめています。障害の発生した日時、サービスの影響、あとは障害の原因。そのときのタイムライン。今後どうやってその今回発生した障害を防ぐのか。障害の検出に問題があった場合は検出をどうやって改善するのか。そしてもしその障害のハンドリングに問題があった場合は、それをどうやって今後改善していくのかなどを話し合っています。

今回の障害の改善事項としては、このようなタスクを作りました。まずカスタムスタンプの機能にレートリミッターを実装するというものです。レートリミッターは一定の割合でリクエストをリジェクトすることによってサービスが過負荷状態になるのを防ぐことができます。

そして、サービスのスケールアウトをもっと早く行えるようにするということですね。Ansibleで自動化はしているんですが、サーバーを追加するという作業をするときにAnsibleを実行する以外にもいくつか手順があります。1個1個は自動化できているけれども、間で手作業が入っているという状況なので、そこの自動化をもっと進めていくというのが課題としてあります。

また、Verdaという名前の僕たちのプライベートクラウドがあるんですが、そこでKubernetesのサービスも提供されていて、Kubernetesを使うことによってスケールアウトを早く行えるようになるのではないかと思っています。

全体のまとめ

それでは、全体のまとめです。新年は僕たちのサービスにとって最もトラフィックが増えるイベントの1つです。そして毎年キャパシティ計測を行い、その結果と過去データに基づいてサーバーのスケールアウト、スケールアップを検討しています。

今年は例年より多くのリクエストが来ました。その結果、サービスの一部の機能で障害が発生してしまいました。しかし、マイクロサービスアーキテクチャを採用していたことによりその障害はサービス全体には影響を与えませんでした。そしてLINEでもポストモーテムの取り組みを行なっており、サービスの安定化と信頼性の向上に取り組み続けています。

最後に、僕たちのサービスに関係している資料の紹介を少しさせてください。これは最近LINE Engineering Blog、LINEのエンジニア向けブログに掲載されたページです(https://engineering.linecorp.com/en/blog/high-throughput-distributed-rate-limiter/)。チームのメンバーが書いてくれています。今年の新年のキャンペーンに関する記事ですね。

この記事では、そのキャンペーンを安定的に処理するためにHigh-throughputな分散レートリミッターを実装したというお話です。もしご興味があればぜひご覧ください。

また、LINEでは毎年エンジニア向けのLINE DEVELOPER DAYという技術カンファレンスを開催しています。2019年のカンファレンスでも僕たちのサービスに関わるセッションがいくつかあり、資料とビデオが公開されています。ぜひご覧ください。

以上になります。ご清聴ありがとうございました。