2024.12.19
システムの穴を運用でカバーしようとしてミス多発… バグが大量発生、決算が合わない状態から業務効率化を実現するまで
提供:LINE株式会社
リンクをコピー
記事をブックマーク
河村勇人氏:それでは始めたいと思います。河村勇人といいます。みなさん、こんにちは。LINEでシニアソフトウェアエンジニアをしています。現在は、全社向けに提供されているKafkaのプラットフォームを開発・運用しているチームのリーディングをしています。
個人的にパフォーマンスエンジニアリングがすごく好きで、Apache Kafkaのオープンソースのコミュニティでもアクティブに活動をしていて、過去にはいくつか大きな場でパフォーマンスエンジニアリングに関する話をしています。Kafka Summit2017年・2018年や、去年のLINE DEVELOPER DAYでも、今日お話しするようなパフォーマンスエンジニアリング・リライアビリティエンジニアリングに関わる話をしました。
さて、今日はLINEにおいてKafkaがどのように使われているかという話から始めるのですが、その前に1つみなさんにお伝えしておきたいのは、今日私がみなさんにお伝えしたいことは、我々がどのようにKafkaを使っているかやKafkaがどれだけ優れているかといったことでもなければ、Kafkaを使う上でのベストプラクティスでもありません。
我々がこのKafkaのプラットフォームを運用していく上で日々行っているリライアビリティエンジニアリングの考え方や、言語やソフトウェアに固有ではない応用可能なテクニックについて、なるべく一般化したかたちでみなさんにお話しできればと思っています。
まず、その前提として、LINEにおいてKafkaがどのような環境でどのように使われているかを話したいと思います。
KafkaはStreaming Data Middlewareと呼ばれるものです。オープンソースで、高いスケーラビリティとパフォーマンスを備えた分散システムです。
特徴としては、データのpersistencyがデフォルトであること、またPub-Subと呼ばれるデータのディストリビューションモデルをサポートしていることがあります。Kafkaのサーバ自体はScalaで書かれていて、JVMの上で動作します。
LINEにおけるKafkaの使い方としては大きく2つあります。1つはサービス間のイベントプロパゲーションです。これは、あるサービスにおいて発生したさまざまなデータのアップデートに関心がある、ほかの多くのサービスに対して、このアップデートの内容を伝搬するためのハブとして用いられています。
もう1つはバックグラウンドにおける非同期のタスクプロセッシングです。これは、例えばあるサービスのWebサーバにおいて、リクエストを処理する過程で発生した非常に重たい処理、これをそのWebサーバの中で処理をするのではなくて、Kafkaを分散キューイングシステムとして用いて、別のプロセスで動くタスクプロセッサーに対して処理をデリゲーションする。こういった目的で用いられています。
現在、LINEにおいて、Kafkaは非常に多くのサービスから使われています。LINEメッセージング、広告のプラットフォーム、LINE Pay、ブロックチェーン、そのほかにもさまざまな多くのサービスに使われています。
LINEでKafkaが使われ始めてまだ数年なんですが、すでにLINEにおいて最もポピュラーなミドルウェアの1つになっています。今日においては、我々のプラットフォームは60を超えるサービスに利用されています。
結果的に、我々のクラスタに入ってくるデータの量も非常に大きなスケールになっていて、レコードの件数はDailyで3,600億件。また、クラスタに1日の間に出入りするトラフィックの総量は550TB(テラバイト)を超えています。これは単一のクラスタとしてはおそらく世界最大級だと思います。
また、我々のKafkaプラットフォームは非常に多くのサービスからバックエンドとして依存されているために、そこに求められるサービスレベルも非常に高いものになっています。
我々は、社内のサービス向けにSLO(Service Level Objective)を決めて提示しているのですが、今日はその中でも重要な値を2つ持ってきてみました。
まず、クラスタのアベイラビリティに関しては、99.999パーセント、いわゆるFive Ninesが設定されています。これは年間で累計のダウンタイムが5分未満であることを意味します。また、Kafkaクラスタの重要なAPIのレスポンスタイムについては、99パーセンタイルで40ms(ミリセカンド)以下という非常に厳しい条件が設定されています。
さて、今お話ししたトラフィックのスケール、そして高いサービスレベルの要求、これらは単独であっても非常にチャレンジングなものなのですが、おもしろいのはこれらが2つ組み合わさったときに起きることです。
非常に大きなスケールのトラフィックを捌きながら高いサービスレベルを維持するのは、一種の究極的な挑戦になります。なので、我々のチームにおいては、日々多くの時間をリライアビリティエンジニアリングに費やしているわけです。
我々が考えるリライアビリティエンジニアリングの責任範囲は比較的広くて、ここに書かれているような活動をリライアビリティエンジニアリングと位置づけています。
まずはSLOのビジュアライゼーションです。これは、サービスレベルを継続的に測って、SLOに実際どれだけ沿えているのかを観測し続けるためのメトリックを選択ないし開発して、それをビジュアライズしていく作業です。
また、オートメーションも非常に重要です。これには大きく2つのモチベーションがあります。1つは、誰が行っても同じオペレーションであれば一貫したワークフローで行われるようにすること。また、我々がオペレーションにかけなければならない時間を削って、我々の時間をより高度なレベルのエンジニアリングに割けるようにするためでもあります。
また、アーキテクチャの提案。これは、我々のチームではKafkaのクライアントライブラリの開発や、また我々の考える理想的なKafkaクライアントの設定、またその使い方をリファレンス実装のようなかたちで見せることによって、各サービスが理想的なかたちでクライアントをコンフィギュレーションして我々のプラットフォームを使えるように努めています。
最後は、トラブルシューティングと、そこから発生する予防的なエンジニアリングです。
今日はこれらの活動のうちいくつかについて具体例を紹介したいと思うのですが、まずはSLOのビジュアライゼーションです。
SLOを定めるためには、SLI(Service Level Indicator)を決める必要があります。これはサービスのパフォーマンスを直接的に表すシンプルな値である必要があります。
一般的には、サーバ側で観測されるAPIのレスポンスタイムやAPIのエラーレートといったものをレイテンシーやアベイラビリティの指標として用いることが多いと思います。しかし、それで十分なのかということを考えると、Kafkaのような分散システムにおいては、クライアント側からの視点が非常に重要であるということがわかります。
Kafkaのような分散システムにおいては、クライアント側とサーバ側は非常に密に協調して動作をします。協調しながら、リトライやフェイルオーバーといったようなことを処理していくわけです。
なので、例えばKafkaを通じたメッセージのデリバリーのレイテンシーを正しく計測しようと思った場合には、まずKafkaに対してデータを書き込むProducerというクライアントが呼び出すAPIのレスポンスタイムは当然関わってきます。
それに加えて、もしここでBroker側でフェイルオーバーが起きれば、そのフェイルオーバーにかかった時間、そしてその間クライアントがリトライをしていた時間。そして、フェイルオーバーが起きたことによってクラスタ側のメタデータをクライアントに反映する必要がありますが、当然そこに要した時間を考慮する必要があるわけです。
また、Consumer側、Kafkaからデータを読み出す側においては、Fetchというデータを読み出すAPIがありますが、これのレスポンスタイムだけではなくて、Consumerが複数の分散したインスタンスで動作しているときにどのインスタンスにパーティションをアサインするかを決めるコーディネーションという処理があります。ここに要した時間も考慮する必要があるわけです。
これらを踏まえて、Kafkaを用いたメッセージデリバリーのパフォーマンスを測るためには、クライアントライブラリの中で行われる処理も経た上での状態に対して観測を加える必要があります。
この目的のためには、実際のサービスで使われているクライアントは用いることができません。実際のサービスで使われているクライアントは、当然そこに実装されたビジネスロジックからの影響を受けます。また、ここで使われるクライアントは、我々がプラットフォームの提供者側として考える、理想的な状態でコンフィギュレーションされて、理想的な使われ方をしているクライアントであるべきだからです。
その目的のために、我々はProberというコンポーネントを開発しました。これはメトリックの計測専用に用意されたクライアントです。
普通のサービスで使われるクライアントと同様に、複数のインスタンスで分散して動作をして、実際のサービスから使われているクラスタに対して動いているので、クラスタ側で起きたフェイルオーバーなどの影響をダイレクトに受けることになります。
また、Prober自体は複数のインスタンスで構成されており、それぞれが同等のメトリックを出しているため、例えばローリングリスタートしてProberを更新している最中においても、メトリックのロストがないようにデザインされています。
Proberのアーキテクチャとしてはこのようになっています。
Proberは複数のインスタンスで動作をするのですが、1つのProberの中にWriter・Reader・Reporterという3つのスレッドが動作しています。
Writerは、Kafkaのクラスタに対して継続的にレコードを書き込みながら、その書き込もうとしたレコードのIDをRedisにストアします。
一方で、Readerは、Writerが書き込んだレコードをKafkaクラスタからconsume、読み出しながら、読み出せたそのIDを同じくRedisに記録します。そして、もしここで実際のクラスタで例えばフェイルオーバーが起きた場合には、Proberも当然その影響を受けるわけです。
Writerがクラスタに対して書き込んだIDをRedisにストアする際には、そのタイムスタンプによってウィンドウイングされたバケットを用います。タイムスタンプによってウィンドウイングされた現在のバケットに対してIDを書き込んで、Readerはクラスタからレコードを読み出しながら、そこに記録されたタイムスタンプから同じようにバケットを計算して、読み出したIDをバケットに記録します。
そして、ここで3つ目のスレッド、Reporterというものがあるのですが、Reporterはこのウィンドウイングされたバケットのうち、一定時間が経過してタイムアウトしたバケットについて、WriterとReader側の2つのバケットを集めてきて、その内容を比較することによって、その差分をロスレートとして記録します。
Proberは、Scenarioと呼ばれるコンフィギュレーションを複数設定できるようになっています。このScenarioというのは、クライアントの実装、またその使い方、それからクライアントのコンフィギュレーション、そして書き込むデータのスループットや求められるデリバリーのレイテンシーといった、個別の条件を表すものです。
我々のプラットフォームは社内の非常に多様なサービスから使われていて、それぞれが異なるrequirementやワークロードを持っています。例えば、あるサービスにおいてはスループットが非常に重要。また、あるサービスにおいてはレイテンシーが非常に重要。また、あるサービスにおいては、スループットもレイテンシーもそれほど重要ではないのですが、とにかくデータがロストしないことが重要といったような要件もあります。
Proberは、この右側に示されているような15行程度のYAMLを追加することで、こういった個別のScenarioについて、統一された一貫性のある観測指標を生成できるようにデザインされています。
これを用いて、我々はSLI Dashboardというものをメンテナンスしています。これはただ数字が並んだだけの非常に簡素なダッシュボードなのですが、これだけでも非常に有効です。
例えば、我々がクラスタのメトリックを見ていてなにか異常な兆候を観測した際に、それが実際にクライアントにまで波及しているのかを判断するために用いたり、あるいは、我々のプラットフォームのパフォーマンスは、どれぐらい我々の提示したSLOに追随できているのかを追跡するために用いています。
これに示されているのは、各クラスタごと、また、そこで設定されているScenarioごとのアベイラビリティの値なのですが、ご覧のように、いくつかのScenarioにおいては少しのエラーがあったことを示すリアルな値が見えていると思います。
LINE株式会社
関連タグ:
2024.12.20
日本の約10倍がん患者が殺到し、病院はキャパオーバー ジャパンハートが描く医療の未来と、カンボジアに新病院を作る理由
2024.12.19
12万通りの「資格の組み合わせ」の中で厳選された60の項目 532の資格を持つ林雄次氏の新刊『資格のかけ算』の見所
2024.12.16
32歳で成績最下位から1年でトップ営業になれた理由 売るテクニックよりも大事な「あり方」
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
PR | 2024.12.20
モンスター化したExcelが、ある日突然崩壊 昭和のガス工事会社を生まれ変わらせた、起死回生のノーコード活用術
2024.12.12
会議で発言しやすくなる「心理的安全性」を高めるには ファシリテーションがうまい人の3つの条件
2024.12.18
「社長以外みんな儲かる給与設計」にした理由 経営者たちが語る、優秀な人材集め・会社を発展させるためのヒント
2024.12.17
面接で「後輩を指導できなさそう」と思われる人の伝え方 歳を重ねるほど重視される経験の「ノウハウ化」
2024.12.13
ファシリテーターは「しゃべらないほうがいい」理由 入山章栄氏が語る、心理的安全性の高い場を作るポイント
2024.12.10
メールのラリー回数でわかる「評価されない人」の特徴 職場での評価を下げる行動5選
Climbers Startup JAPAN EXPO 2024 - 秋 -
2024.11.20 - 2024.11.21
『主体的なキャリア形成』を考える~資格のかけ算について〜
2024.12.07 - 2024.12.07
Startup CTO of the year 2024
2024.11.19 - 2024.11.19
社員の力を引き出す経営戦略〜ひとり一人が自ら成長する組織づくり〜
2024.11.20 - 2024.11.20
「確率思考」で未来を見通す 事業を成功に導く意思決定 ~エビデンス・ベースド・マーケティング思考の調査分析で事業に有効な予測手法とは~
2024.11.05 - 2024.11.05