LINE株式会社は、2023年10月1日にLINEヤフー株式会社になりました。LINEヤフー株式会社の新しいブログはこちらです。 LINEヤフー Tech Blog

Blog


【インターンレポート】負荷テスト環境の非同期処理周りの環境構築とその利用

こんにちは、LINE LIVEのサーバーサイドの開発を行なっているLIVEサーバー開発チームでインターンに参加させていただいている山内です。

今回は6週間の就業型インターンに参加させていただき、負荷テスト環境の非同期処理周りの環境構築と、それに依存した負荷テストシナリオを追加して実際にパフォーマンス計測を行いました。

背景

LINE LIVEではCarlosというツールで負荷テストを実行しており、その負荷テスト専用の環境を持っています。

しかしその負荷テスト環境はIMF Kafkaのcousumerが独立しておらず、alpha/beta環境(開発環境)のconsumerを共有しています。

そのため、consumerに依存した負荷テストが実行できないという問題があり、負荷テスト用のconsumerを用意したいという背景がありました。

consumerの概要

LINE LIVE では、定期的なバッチ処理や、ピーク時大量発生の恐れがあるが即時性は求めない処理については、IMF Kafka を使って非同期処理で対応しています。

consumer は次の図の message を pull して処理をするコンポーネントで、実際に非同期処理をしている部分です。

負荷テスト環境

次に、負荷テスト環境についてです。

概要は下図のようになっています。Slack Botから実行でき、Grafanaで可視化された実行結果もSlackに通知されるようになっています。また、ローカルからでも負荷テストの実行が可能で、シナリオファイルはGitHubと自動で同期しているためシナリオ追加・編集の際にデプロイの必要はありません。また、負荷テストの実行基盤として、k6をベースとしたstampedeという社内ツールを使用しています。

使用した社内ツールの説明

PMC

LINEではサービス管理にPMCという社内ツールを使っています。PMCはDeploymentに使用されます。PMCにはfarmやprojectというものがあり、それぞれ以下のようなものです。

  • farm
    • PMCのサーバーグループ
  • project
    • PMCで管理するもの
    • projectはfarmと一対一

ops inventory

社内のCMDB(構成管理データベース)です。

CAS2

CAS2とは、Ansible PlaybookをGUI上から実行するための社内ツールです。ボタンを押すだけでplaybookが実行できるようになっています。

また、誰が実行したかや実行時のログを見れるため、何か問題が起こっても原因の追跡が容易になっています。

Verda (Verda Dev)

Verdaとは、社内プライベートクラウドです。Verda Devは開発環境用のプライベートクラウドです。今回は負荷テスト環境の構築のため、Verada Devのみを使用しました。

負荷テスト環境の構築

この「負荷テスト環境の構築」のセクションで使用した社内環境は一般的には外部公開されていません。そのため、説明で使用するスクリーンショットなどはみなさんに馴染みのないものですが、今回どのような作業をしたのかをわかりやすくお伝えするためにあえて社内環境のスクリーンショットを用いています。

サーバーの用意

LINE LIVEでは社内のクラウドプラットフォームであるVerda Dev内で負荷テストの環境を構築しています。そのため、下記のような手順でload環境用のサーバーの用意をしました。

  • PMC farmの作成
  • 今回使用するload環境用のconsumerのPMC projectを作成
  • CAS2上にload環境用のconsumerのprojectを作成
  • Verda Devにload環境用のIMF Kafkaのconsumerを用意
  • load環境用のconsumerの設定を追加
  • CAS2のplaybookを実行

farmの作成

farmの作成は以下の画像のようなops inventoryという社内CMDBを使って、名前を入力するだけで簡単に作成することができます。

farm内にprojectを作成

同様に、ops inventoryの下記のようなフォームに記入してprojectを作成します。この際、画像の左側では上で作ったfarmと紐付けており、右側ではデプロイ時に読み込むファイルの設定などをしています。

CAS2上にload環境用のprojectを作成

以下の画像のようにCAS2のページに必要事項を入力し、projectを作成しました。この際、PMC Farmの項目で上で作ったPMC Farm名を入力し、CAS2のprojectとPMC Farmを紐付けています。

projectの作成ができると、次の画像のようなprojectの詳細ページに遷移します。そこで、Verda Init Scriptという部分をclickすると、下の画像のようなスクリプトが表示されます。このVerda Init Scriptとは、VerdaでVM作成直後に走らせるスクリプトで、このスクリプトを実行することで、作成されるサーバーに実際にログインしなくてもplaybookを回すのに必要なssh権限を付与することができます。

Verda Devにload環境用のIMF Kafkaのconsumerを用意

次に、Verda Dev にload環境用のIMF Kafkaのconsumerを用意するために、再度ops inventoryを使用しました。ops inventoryから提供されている、PMCに必要な構成を自動適応する機能によって間接的にVerda DevにVMを作成します。

ops inventoryのnodeを追加より以下の画像のように必要事項を記入し、作成しました。この際、先ほどCAS2のprojectを作成した際に確認した「Verda Init Script」を画像の一番下の「Init-Script Configuration」というところに書き込みます。そうすることでこのNodeと先ほど作成したCAS2のprojectと紐づけることができ、作成したサーバーからplaybookの実行ができるようになります。

Nodeが作成されると以下のNodesの欄に表示されます。

また、Verda Devのサーバーのインスタンスを確認できるページでも以下のように見えます。

load環境用のconsumerの設定を追加

詳細の設定は指定したリポジトリから読み取るため、他の設定を参考にしながら今回構築したいload環境用のconsumerの設定を追加しました。

CAS2でplaybookの実行

最後に、以下のようなボタンからCAS2でplaybookの実行を行いました。上でも述べたように、CAS2はAnsible PlaybookをGUI上から実行するための社内ツールですので、このplaybookの実行もボタンひとつ押すだけで簡単にできました。

詰まったところ

上記の手順の説明であったように、今回の課題ではさまざまなツールを互いに紐付けて環境構築を行う必要がありました。しかし、初めの方はVerda Devにサーバーを立てて、それとは関係のないPMCのfarmを作成して、といったように互いに紐付けることができていませんでした。ツールの仕組みを理解しようとしてドキュメントを読んでいた結果、実現したいことに対してそれぞれのツールがどのように繋がっているのか、繋げれば良いのかを考えれていなかったことが原因として考えられます。

しかし、メンターさんと話す中で、それぞれのツールがどのように繋がっているのか、どのような役割を担っているのかが明確になり、課題を実現することができました。

load環境での処理の分岐

次に、load環境の処理の分岐を行いました。具体的な内容としては、これまでは同じtopicを見に行っていたものをload環境であれば先ほど作成したload環境用のtopicを見に行くように修正するというものです。

この実現方法として2点考えられました。まず1点目は環境を判断して出し分けるというものです。そして、もう1点は新たに設定ファイルを追加するというものです。

この際、どちらの方が適切かという議論の中で、どうすれば本番環境への影響を最小限にできるかという目線での意見をいただきました。そして、結論としては環境を判断し出し分ける方が本番環境への影響を最小限に抑えられるということで、環境ごとに出し分けるという処理を追加しました。

このような議論を通して、環境を分けて運用していく中でそれぞれの環境ごとに独立させ、互いに影響を与えないように設計するということが重要であるということを学びました。

Slack Bot の修正

LINE LIVEでは以下の図のように開発環境へのデプロイをSlack Botから簡単に行えるよう整備されています。そのため、今回追加したload環境用のconsumerもデプロイできるようにSlack Botの修正を行いました。また、Slack BotについてはVKS(社内プライベートクラウドVerdaのマネージドk8s)上にデプロイされているため、k8sへのデプロイも行いました。

負荷テスト

シナリオ追加

今回構築したconsumerに依存する負荷テストシナリオとして、Viewer Listのシナリオを追加しました。Viewer Listとは、配信に入室したユーザーのユーザー情報を入室時間の降順で最大100件まで表示するリストです。今回はこのViewer Listにユーザーを追加するAPIのパフォーマンス計測を行いました。具体的な処理の流れは以下のようになっており、総合的に計測できないものでした。

パフォーマンス計測

追加したシナリオをもとにパフォーマンス計測を行いました。

結果は以下のようになり、応答時間が90パーセンタイルで140ms程度と問題のない結果となりました。

全体的には問題なさそうなのですが、一時的に応答時間が長くなる瞬間がありました。このことに関しては上の2つの画像からも分かるように再現性がありそうです。

インターン期間の関係でどれくらい再現性があるのかや、何が原因なのかの検証はできていないのですが、今後検証する必要があると思います。

改善点の発見

また、結果を見ている際にRedisキャッシュのヒット・ミスを確認していると、以下の画像のように極端に悪いものがありました。

これは、サービス当初からある視聴者数を取得するキャッシュで、今は別手段で代替可能なものであることがわかりました。これで今後不要なキャッシュを削ることで、LINE LIVE サービスの改善につながると思います。このように、今回環境構築からその環境を利用したテストを行い問題点を発見するところまででき、LINE LIVEサービスの改善に貢献できたたことはよかったと思います。

今後について

応答時間が瞬間的に遅くなる現象の再現性があるのかの検証

上でも述べたように、一時的に応答時間が遅くなる瞬間があり、その再現性の有無に関しては検証する必要があり、再現性があるのであればその原因に関しても調査していく必要があると思います。

consumerのパフォーマンス計測方法

冒頭でも示したように、consumerの構造は他のAPIサーバーと異なります。APIサーバーではパフォーマンスが劣化した場合リクエストが捌き切れないであるとか、応答時間が長くなってしまうといった観点で評価できます。しかし、consumerは構造上「キューが溜まる速度 > キューを捌く速度」となるとパフォーマンスが悪いという状況になります。現状、このような状態を検知する仕組みがないため、その整備をすることで今回構築した負荷テスト環境を使用し、consumerのパフォーマンスチェックがしっかりとできると思います。

学んだこと

私は今回のインターンで大規模なサービスだからこそ考えないといけないことや高トラフィックを捌くための技術を学びたいと思いこのインターンに参加しました。そこで、今回のインターンで得られた学びを簡単に紹介します。

LINE LIVEでは開発環境(alpha/beta)、負荷テスト環境、本番環境とさまざまな環境を持っています。そのような中で、load環境での処理の分岐のセクションで書いたように、環境ごとに処理を変える際本番環境になるべく影響が出ないように設計することの重要性を学びました。また、このようにさまざまな環境がある中でデプロイなどをどのように効率化しているかなどもSlack Botの修正などを行う中で感じることができました。

続いて高トラフィックを捌く技術という点についてです。今回のインターンでは、インフラ面からその技術というものに触れることができました。

感想

今回のインターンではこれまであまり触ったことのないインフラ周りのタスクということもあり、つまずくことも多々ありました。

今回使用した社内ツールにはそれぞれその概要や使い方が書かれたドキュメントが存在します。しかし、実際にタスクをこなす中でそれぞれのツールがどのようにつながっているかが理解できていませんでした。しかし、メンターさんとお話しする中でその全体像が見えてきて、より理解を進めることができたと思います。簡単に表現すると、点がつながって線になったというような感覚です。

そのほかにもわからないことをSlackなどで質問するとメンターさんだけではなく、チームメンバーの方も答えていただき、スムーズにタスクを進めることができました。メンターの zhu さんをはじめ、LIVEサーバー開発チームの皆さんのサポートなしではこのインターンをやり切ることはできなかったと思います。

6週間という短い期間ではありますが、非常に多くの学びを得ることができました、ありがとうございました!