自己紹介と発表前半のアジェンダ

齋藤智之氏:LINE Data Platform室の齋藤智之です。現在私は、データプラットフォーム開発組織のシニアソフトウェアエンジニアとして、研究開発や開発プロジェクトのリードをしています。今日の発表では、データプラットフォームを開発運用する中で直面してきた課題と、その解決に向けた取り組みの一部を紹介しようと思います。

発表は前半と後半の2部に分かれています。前半ではデータ処理のお話、後半ではデータのインジェスチョンパイプラインにおける課題と、解決に向けた取り組みについてお話しします。

LINEのデータプラットフォームについて

まずはLINEのデータプラットフォームの紹介です。LINEには、LINEが提供しているあらゆるサービスのデータを集積し、統合的なデータ分析環境を提供するプラットフォームがあります。データプラットフォームは、データ分析、機械学習のための要求や、適切な権限管理などのデータガバナンスの要求に応えるためセルフサービス化された機能を提供し、データの民主化を支えています。

データプラットフォームにおけるデータ活用の流れは、大まかに3つのプロセスに分けられます。データをプラットフォームに集積するための、インジェストのプロセス。データ分析の要求を満たすようにデータを加工するプロセス。意思決定やサービス開発に役立てるために、データを利用しやすいように提供するプロセスです。

LINEのデータプラットフォームの特長は、データ量、種類、活用の規模が大きいことです。ユーザー数やサービスが成長するにつれてデータの規模も大きくなり、分析の要求に応えるプラットフォーム、インフラもスケールアウトする必要が出てきます。

現在のデータプラットフォームで扱われるデータの規模を紹介します。プラットフォームで使われるマシンの数は5,000台、集積されているデータの量は290ペタバイト、Hiveテーブルの数は40,000を超えるスケールになっています。

ログインジェスチョンパイプラインでのログの流量は秒間1,750万、1日に実行されるジョブの数は15万、プラットフォームのユーザーの数は700を超えています。

このようなデータ規模の拡大の中、データプラットフォームではデータ分析に必要な処理を実行するためのサービスを提供しています。データインジェスチョンの基盤では高いスループット、データ処理基盤ではデータの種類や量が大きくてもスケールするシステムを構築することが要求されます。

データ処理のためのクエリ実行の概要

ここからは、LINEのデータ処理を支えるサービスにおける課題を紹介します。

まずは、データ処理のためのクエリ実行の概要を説明します。分析のためのデータ処理は、SQLで行われることが多いです。SQLの実行の際には、SQLクエリエンジンがデータの分散処理を可能にしています。

(スライドを指して)こちらは、分散SQLクエリエンジンの処理の様子を表したものです。SQLクエリは分散処理エンジンごとの実行プランに変換され、最終的にリソース管理システムによって割り当てられた、コンピューティングリソースを用いて実行されます。

SQLクエリを実行プランに変換するには、SQLで指定されたテーブルについて、データファイルがどこにあるか、どうやってデータを読み書できるかなどの情報が必要です。クエリに必要なテーブルの情報をどのように管理するかは、テーブルフォーマットによって定義されます。

テーブルフォーマットというのは、あるデータセットが1つのテーブルとして表現できるように、ファイルの管理方式を定めます。テーブルフォーマットはクエリ実行において、主に2つの大きな役割を果たしています。

1つ目は、どのファイルがテーブルのデータを構成しているかに答えることです。2つ目は、そのファイルがどのように読み書きできるかに答えることです。そのためには、パーティショニングやスキーマ定義など、メタデータの管理も必要になります。

テーブルフォーマットのデファクトスタンダードと言えるのが、Hive table formatです。Hive table formatは、データファイルをファイルシステムのディレクトリによって管理しています。テーブルの管理に使われるパーティションやスキーマなどのメタデータの変更、照会はHive Metastoreというサーバーを介して行われます。

Hive Metastoreのバックエンドでは、メタデータがRDBMS(Relational DataBase Management System)に保存されます。ここではそのバックエンドDBをMetastore DBと呼んでいます。LINEのデータプラットフォームでも、このHive table formatでテーブルを管理するのが一般的です。

(スライドを指して)LINEのデータプラットフォームが提供しているシステムの様子は、このようになっています。データを保存するためのHDFS(Hadoop Distributed File System)、テーブルメタデータを保存するためのHive Metastoreが、ストレージレイヤーに書かれています。

SQLクエリエンジンはSpark、Hive、Trinoが実行できる環境を提供しています。データの分析者は、これらのSQLクエリエンジンを用いてインタラクティブなクエリを実行したり、スケジューラーを用いてETLパイプラインを実装したりしています。

Metastoreにまつわる複数のトラブル

LINEにおけるデータ活用の規模の拡大に伴い、私たちはMetastoreにまつわるトラブルを経験してきました。Metastoreのインスタンスは、プラットフォームのユーザー全体で共有されているマルチテナント環境を構築しており、Metastoreでのトラブルはインパクトが大きいです。

(スライドを指して)こちらはMetastore DBにおける、クエリのレートを表したものです。上はSelect文、下は更新を表すDML(Data Manipulation Language)の実行レートです。データプラットフォーム環境ではSelectのQPS(Queries Per Second)が高く、通常時は秒間5,000ほどのクエリが実行されていることがわかります。

続いてCPU使用率です。使用率が高い時間帯においては、50~60パーセントを超えているのが見てとれます。

(スライドを指して)アブノーマルなCPU使用率が観測された例がこちらです。一時は90パーセントに近いCPU使用率となっているのがわかります。

このトラブルの原因を調べたところ、ある1,000万を超えるパーティションを持つHiveテーブルが、問題に関係していることがわかりました。このトラブルの際は、意図せずに作られてしまったパーティションを削除することで解決しました。

Hive table formatはHive Metastoreによってメタデータを管理する設計になっており、パーティションに関しては、1つのパーティションが1つの行としてHive Metastore DBに保存される実装になっています。運用していく中で、今回のトラブルのように、大量のパーティションを扱った場合に問題が起こるとわかりました。

Metastore DBに重たいスキャンが走りレスポンスが遅くなることもあれば、Hive Metastoreサーバーでは、大量のパーティションオブジェクトがメモリにロードされることによってメモリプレッシャーが高くなり、Full GCやOOM(Out Of Memory)でダウンするなどのトラブルも経験してきました。

このリミテーションにより、パーティションを減らしたり、一度に扱うパーティションを少なくするようなワークアラウンドが必要になります。

(スライドを指して)LINEのデータプラットフォームが直面したHive table formatの問題をまとめると、このようになります。Hive table formatではHive MetastoreとMetastore DBのキャパシティがボトルネックとなり、テーブルメタデータ照会のパフォーマンスが制限されるという問題がありました。

Hive Metastoreが大量のパーティションを扱えないため、テーブルは粗い単位でパーティショニングする必要があり、非効率なデータアクセスになってしまう場合があります。Metastoreのキャパシティにより、per-fileの統計情報など、クエリ最適化のためにメタデータを追加するようなモデルの変更は現実的ではありません。

ここまでで、Hive table formatとは何かと、その問題点について紹介してきました。

Apache Icebergの特徴と利点

これまでに見てきたHive table formatの課題解決のために、LINEではApache Icebergというテーブルフォーマットに注目しています。ここからはApache Icebergとは何か、どういう利点があるのかを紹介します。

Apache Icebergはオープンソースのテーブルフォーマットです。Hive table formatと同様に、SQLクエリエンジンに対して、ファイルフォーマットやストレージ上でのファイルレイアウトを抽象化しています。

Icebergテーブルを使った時の様子を紹介します。Icebergが提供しているSpark用のライブラリを用いることで、Spark SQLを使ってIcebergテーブルを扱えます。(スライドを指して)こちらのようにcreate文を記述することで、Iceberg table formatを指定できます。それからは普通のテーブルと同じように、insertやselectなどSQL文が実行できます。

HDFS上でのファイルのレイアウトを表現しているのが下になります。今回作成したのがsampleというテーブルで、sampleディレクトリの下にはdata、metadataというディレクトリが作られています。このmetadataファイルの詳細について見ていきます。

Icebergにおいて鍵となるコンセプトとして、Snapshotがあります。テーブルフォーマットは、SQLクエリの実行においてどのファイルがテーブルを構成しているかを抽象化するものでした。Icebergではテーブルのファイルの状態をSnapshot形式で管理することで、ファイルを追跡しています。

ここで言うSnapshotは、一般的に使われている意味と同様に、ある時点でのテーブルの状態のことを指します。図の例で言えば、ある時点t0でのテーブルの状態はs0として保存され、s0はテーブルを構成しているファイルへの参照を持っています。

テーブルフォーマットの役割は、テーブルの更新が行われてもテーブルの状態を追跡し管理することです。Icebergではデータの書き込み、コミットが行われると、新しいSnapshotを作成します。

図の例では新しいファイルが1つ追加され、s1 Snapshotはt0時点でのデータを含めた、すべてのファイルへの参照を保存しています。データをテーブルとしてアクセスするために、ファイルのパスだけでなくデータのスキーマ、データの統計情報などもメタデータとして管理されています。

Icebergのスペックについてもう少し詳しく見てみましょう。(スライドを指して)先ほど紹介したmetadataというディレクトリの中身は、このようなファイルの集合になっています。Table metadata fileが現在のテーブルの状態を表すルートとなるようなファイルで、先ほど紹介したSnapshotの情報を格納しています。

SnapshotはManifest list fileへの参照を持ち、Manifest fileの一覧を保持します。Manifest fileが、データファイルのパスや統計情報などのメタデータを直接格納しています。Icebergは階層的なファイル構造を使って、メタデータを効率的に追跡、管理しています。

Iceberg table formatがHive table formatと決定的に異なる部分は、テーブルの状態がファイルによって追跡されることです。Hive table formatでボトルネックとなっていたHive Metastoreへの依存をなくすことができ、HDFSなどのスケールしやすいファイルシステムをメタデータ置き場として利用できます。

データにクエリが実行される例も見てみましょう。テーブルの状態はSnapshotによって管理されているので、現在のSnapshotを参照し、指定されているManifest list fileにアクセスします。

Manifest list fileはManifest fileのパスと、そのManifest fileで管理されるデータのパーティションバリューの上限、下限を格納しています。クエリにパーティションのフィルターがある場合には、このレンジを用いて、実際に読み込むManifest fileをフィルタリングできます。

そしてクエリに該当するManifest fileを読み込むことで、データファイルのパスを取得できます。Icebergでのファイルの追跡はこのように行われ、データのパーティショニングのサポートもあります。

メタデータの格納場所がファイルになったことの1つの利点として、メタデータを格納するキャパシティが増えたことがあります。IcebergのManifest fileにはper-file、per-columnの統計情報を保存しており、クエリの際に実際に読み込むファイルをさらに減らすことが可能です。

Hive table formatとIceberg table formatの違いのまとめです。Hive table formatではHive Metastoreに保存されていたメタデータが、Icebergではファイルとして管理されるようになりました。これによってメタデータ管理におけるHive Metastoreのボトルネックが解消され、スケーラビリティが改善されました。

Hive Metastoreのキャパシティによりパーティションの数が制限されていたのが、Icebergでは解消され、より効率的なテーブル構成を実現できます。HiveではPer-partitionの粒度までだった統計情報が、IcebergではPer-fileで管理できるようになりました。これによってクエリのパフォーマンスの改善が期待されます。

Icebergにはほかにも分析における要求を満たすためのさまざまな設計がされていて、データプラットフォームにおけるほかの課題についても、有効に活用できるのではないかと考えています。

今後はIceberg table formatの活用を検討中

本日の発表のまとめです。現在デファクトスタンダードとなっているHive table formatは、Hive Metastoreがボトルネックになっており、スケーラビリティの問題がありました。Apache Icebergはファイルを使ってデータを追跡することで、そのボトルネックが解消されます。

また、Icebergの設計は、分析におけるほかの課題解消にも役立つことが期待されています。このような背景から、LINEのデータプラットフォームではIceberg table formatを広く採用し、活用していくことを検討しています。

前半の発表は以上です。ご視聴ありがとうございました。引き続き、後半の発表です。

(後半につづく)