地上波でのサービス紹介

渡邊紘太朗氏(以下、渡邊):では、最後のトピックになります。去年の年末に、年明けの1月9日に某バラエティ番組でサービスの紹介が行われるという話が共有されました。予想ではプレスリリース時よりも少ないリクエスト数を見込んでおり、環境の改善を行っていたので問題はなさそうだったんですが、これを機にパフォーマンス・チューニングを行うことにしました。

プレスリリース時には秒間約4,000リクエストによりサーチのスレッドがフル稼働かつスレッドのキューを食いつくしていたので、リクエストのリジェクトが発生していました。今回は同様のエラーが発生しないようにチューニングを実施していくことにしました。

チューニングでは以下の2点を変更しました。1つめはスレッドプールのサイズの変更です。

Elasticsearchはインデクシングやサーチといった各用途ごとに固定もしくは可変長のスレッドプールを持っています。サーチのスレッドプールの場合は、processors×3÷2+1、こちらの計算式に基づいて固定長のスレッドプールが生成されます。

先ほどの話のなかでもあったんですが、Elasticsearchは合計では、デフォルトで32コアに制限されているため、デフォルトであるとサーチのスレッドが49スレッドに制限されることが判明しました。今回はElasticsearchの適切な値を与えることでスレッドプールの数を増やすことにしました。

先ほどの話のなかでもあったとおり、社内の物理サーバーは40コアを搭載しているサーバーなので、この値をprocessorsのパラメータとして与えることにより、サーチのスレッドを61個に増やしました。また、キューのサイズの変更についてはElasticsearchはスレッドプールごとにキューを持っています。すべてのスレッドがアクティブな状態であった場合に、このキューが利用されるようになっています。

Elasticsearch5系だとサーチのキューサイズはデフォルトで1,000に設定されているんですが、この上限を明示的に引き上げることにしました。今回のチューニングでは前回のリクエスト数の80パーセントである3,000までキューを引き上げました。

これらの設定はelasticsearch.ymlファイル内に静的に記載しております。またこれらはデータノードにのみ設定を行いました。これらの設定はElasticsearch5系のものであり、Elasticsearch6系からは異なっているので注意が必要です。

設定後のクラスタはこのようになります。

クラスタの構成は変わらずに、パラメータのみ変更されたかたちになっています。この状態で放送日を迎えました。

放送当日のメトリクスについて説明をします。こちらが放送当日の一週間前の同時刻のメトリクスになります。

サーチのクエリーは秒間150rps、クエリータイムは3msほど、スレッドプールのアクティブ率は最大で5程度ですね。あとリジェクトやサーチのスレッドは、キューはほとんど使われてないような状態になっています。

こちらは当日の1月9日、21時から23時のメトリクスになります。

リクエスト数は750rps、サーチのクエリータイムが3ms、アクティブなスレッドプールが10、キューもほとんど利用されずにリジェクトも発生していないような状態になります。この結果をみてわかるように、チューニングをしたもののそれに至るまでの数値にはなっていなかったというような結果になります。

それでは運用のまとめになります。まず、マスターノードを増やしてデータノードの分離を行いました。次に、サービスとAdmin用にゾーンを追加しました。そして最後に、データノードのチューニングを行い、現在も問題なく稼働しております。

Elasticsearchの監視

では次に、Elasticsearchの監視について説明していきたいと思います。弊社には複数の監視システムがあり、環境ごとにツール使い分けています。

まず1つめは、内製のアラートツールになります。この内製のアラートツールの運用管理は社外の専用のチームが行っており、設定の変更や更新はメールで依頼を行っています。

2つめは、IMONという、こちらも内製ツールで、これはアラーティングとモニタリングの両方を備えたツールになります。社内にPMCというデプロイやホストの管理などを行う管理ツールがあるんですが、そちらに依存しているためPMCを利用しているプロジェクトは必然的にIMONを使うことが多いです。また、PMCはJavaで書かれているプロジェクトが主に利用しています。

これまでの監視環境では厳密なアラート量が設定できなかったり、アラートを設定するのにメールでの依頼が必要であったりと、さまざまな問題があったため監視環境の改善のプロジェクトが発足してPrometheusとGrafanaを用いた新たな監視環境を作成することになりました。

また、Prometheusや後で出てくるAlertmanagerといった管理ツールのコンフィグをジェネレートしてくれるPromgenというツールの開発もチームで行っています。

Elasticsearchを含むLINEデリマの環境は、現在はPrometheusとGrafana、Promgenの環境で監視を行っています。

Prometheusのしくみ

Elasticsearchの話からはそれてしまうんですが、簡単にPrometheusのアーキテクチャの解説を行います。

いま画面に映し出されているのは公式のドキュメントから引用してきた図になります。

Prometheusはコンフィグに設定された情報をもとにターゲットであるサーバーに対して一定間隔でメトリクスを取得しにいきます。

このときサーバーにはエクスポーターと呼ばれるエージェントがインストールされており、メトリクスの取得はHTTP経由で行っております。もし取得したメトリクスがアラートルールに設定してある値に一定間隔で発生し続けると、PrometheusはAlertmanagerというソフトウェアに対してアラートをプッシュします。

Alertmanagerはプッシュされたアラートに基づいて通知先を選択してアラートを通知します。また、取得したメトリクスはPrometheusがデータを保管しているのでPrometheusをデータソースとするアプリケーションから閲覧することができます。

こちらは先ほどの説明をまとめたページになります。

Prometheusはプル型の監視ツールで監視対象のサーバーにインストールされたexporterと呼ばれるエージェントをHTTP経由でメトリクスを取得しにいきます。

GrafanaはPrometheusをデータソースとしてグラフを描写しています。現在はGrafanaにはエクスポーターごとやサービスのオーバービューといったダッシュボードが作成されています。また、PromgenはLINE社製のコンフィグジェネレータになります。こちらはOSSとして公開もされています。

ElasticsearchとPrometheus

ではElasticsearchの話にもどって、ElasticsearchとPrometheusについてです。Elasticsearch用のexporterはサードパーティのものが複数あるんですが、弊社ではスライドに記載されているexporterをすべてのElasticsearchのサーバーにインストールしてメトリクスを取得しています。

こちらのexporterはElasticsearchの_nodes/stats APIを経由してメトリクスを取得したものをPrometheusが読めるかたちで出力するようなものになります。

そのため、こちらのAPIで取得できる数値はすべて出力することはできるんですが、こちらのexporterの作成者の方の意思で、必要になったタイミングで必要な値を出力するようにするというスタンスになっているので、もし必要な値が出力されていない場合はプルリクエストを送り改修を行う必要があります。

また、アラートルールにはクラスタの状態がレッドになっていないか、また、メモリの使用率が上昇していないか、サーキットブレーカーが起動していないか、などのルールがデフォルトのルールで設定されています。また、こちらのルールは個別に設定することも可能です。

これらを踏まえたうえで先ほどのアーキテクチャ図を弊社の環境に置き換えたものが次の図になります。

まずユーザーはPromgenでプロジェクトやサーバーの登録を行います。Promgenはプロジェクト、サービス、ファームというような階層的なカテゴリを持っていて、それぞれ登録が必要になっています。ホストは直接入力することも可能なんですが、先ほど説明したPMCという管理ツールからシンクすることも可能です。

次に、exporterをターゲットのサーバーにインストールします。現時点では、Elasticsearchのセットアップと同様、Ansibleで必要なエクスポーターを配布しています。今回の場合だと、先ほど説明したElasticsearchエクスポーターを配布していますが、CPUの使用率やメモリの使用率などのサーバーのメトリクスを取得するためにデフォルトでnode_exporterというexporterも初回セットアップ時にインストールしています。

exporterのインストールが完了したら、再度Promgenに戻り、exporterの指定を行います。エクスポーターの指定が完了したあと、アラートのルールであったり通知先を設定したりします。

アラートルールに関しては、これまでの監視の項目を網羅する形でデフォルトルールが設定されており、サービスごとに必要なルールを追加したり、デフォルトのルールをオーバーライドしたりして設定を行っています。

また、Prometheusは現在、15秒おきにサーバーにメトリクスを取得していくようになっていて、その取得したメトリクスはPrometheus内に蓄積されており、共通のGrafanaからPrometheusをデータソースとしてダッシュボードを作成しています。作成されたダッシュボードをユーザーのかたが見ているというような状況になります。

こちらが抜粋したPromgenのプロジェクトページになります。

こちらのページからエクスポーターの登録であったりホストの登録であったりヘルスチェックのURLの登録、また通知の登録であったりルールの登録を行うことができます。

では監視のまとめです。開発3センターではこれまでの監視環境を改善すべく、Prometheus、Grafana、Promgenの環境に移行を進めている段階になります。また、ジェネレーターであるPromgenはOSSとして公開されており、現在も絶賛開発中になります。

また、Promgenに関してはLINE Engineering BlogであったりPromConであったりの様子がインターネット上にアップロードされているので、こちらもぜひ確認してみてください。また、不定期にはなるんですが、Prometheus Casual Talksといったイベントも開催しております。

今後の展望

では最後に今後の展望について話したいと思います。まず1つ目は、クライアントのアップデートと変更になります。現在は先ほど説明したとおりTransportClientを利用しているんですが、Elasticsearchの今後のリリースで非推奨になることが決定しているようなので、早いうちに対応していきたいなと思っています。

Elasticsearch6系からHighLevelRESTClientというようなものが用意されたので、段階を踏んでこちらにアップデートしていきたいなと思っています。また、これはLINEデリマに限った話ではないんですが、Elasticsearchのバージョンのアップデート、もしくは新しく構築するElasticsearchのクラスタを6系で扱っていくというようなこともやっていきたいと思っています。

現在はほとんどのサービスはElasticsearchの5系を使って検索を行っているので、それを6系に移していきたいとも思っています。これらのアップデートの検証は完了している状態で、いつでも実施できるような状態になっています。また、個人的な願望なんですが、社内でElasticsearchの検証記事を大量に書いているので、そういったものをもっと世の中に出していきたいなというような気持ちもあります。

ではこれで説明を終わらせていただきたいのですが、なにか質問があればよろしくお願いします。

アラートのトリガーについて

質問者1:非常にいい話をありがとうございました。アラートのレベル、トリガーについて訊きたいんですが、先ほどステータスがレッドになったときなどに通知します、という話だったのですが、夜間とか休日とかでも担当を呼び出すようなものはどういった条件で決めているんでしょうか。

渡邉:そうですね、基本的にPrometheusが取得したメトリクスを一定間隔で評価して、それが指定された時間発火し続けるとアラートが飛ぶというデフォルトルールになっていて、それをチームごとに変更したり、先ほどのPromgenに設定した値で変更ができるようになっているので、サービスの担当者の方々に一任しているという感じになっています。

なので、アラートが常に、なるべく早く飛ぶように設定するような方もいれば、デフォルトのルールのまま運用しているチームもあるという状態になります。まあ休日等は関係ないかんじですね。

質問者1:Promgenを知らないのであまりイメージができてなかったのですが、ユーザー側が決めるということですか?

渡邉:そうですね、ユーザーがPromgen上から設定を行って、その設定ががPrometheusに巻かれて起動しています。

質問者1:ありがとうございます。