前回のブログでは、Uber の Presto のユース ケースと、Presto クエリを高速化する際のさまざまな課題を克服するために協力して Alluxio ローカル キャッシュを実装した方法を紹介しました。 2 番目の部分では、ローカル キャッシュ メタデータの改善について説明します。
まず、古いキャッシュを防止したいと考えています。基になるデータ ファイルは、サード パーティのフレームワークによって変更される可能性があります。この状況は、Hive テーブルではまれかもしれませんが、Hudi テーブルでは非常に一般的であることに注意してください。
次に、HDFS からの重複していないデータの毎日の読み取りは大きくなる可能性がありますが、すべてのデータをキャッシュするのに十分なキャッシュ スペースがありません。そのため、テーブルごとにクォータを設定することで、範囲指定されたクォータ管理を導入できます。
第 3 に、サーバーの再起動後にメタデータを回復できる必要があります。ディスクではなくメモリ内のローカル キャッシュにメタデータを保存しているため、サーバーがダウンして再起動したときにメタデータを復元することはできません。
そのため、キャッシュした各データ ファイルの最終変更時刻とスコープを保持するファイル レベル メタデータを提案します。ファイル レベルのメタデータ ストアは、再起動後にデータが失われないように、ディスク上で永続化する必要があります。
ファイルレベルのメタデータの導入により、複数のバージョンのデータが存在します。データが更新されると、新しいバージョンに対応する新しいタイムスタンプが生成されます。この新しいタイムスタンプに対応して、新しいページを格納する新しいフォルダーが作成されます。同時に、古いタイムスタンプを削除しようとします。
上記のように、timestamp1 と timestamp2 の 2 つのタイムスタンプに対応する 2 つのフォルダーがあります。通常、システムの実行中は、古いタイムスタンプ 1 を削除してタイムスタンプ 2 のみを保持するため、2 つのタイムスタンプが同時に存在することはありません。ただし、サーバーがビジーな場合や同時実行性が高い場合は、タイムスタンプを時間通りに削除できない場合があり、その場合、2 つのタイムスタンプが同時に存在する可能性があります。さらに、protobuf 形式のファイル情報と最新のタイムスタンプを保持するメタデータ ファイルを維持します。これにより、Alluxio のローカル キャッシュが最新のタイムスタンプからのみデータを読み取るようになります。サーバーが再起動すると、メタデータ ファイルからタイムスタンプ情報が読み取られるため、クォータと最終更新時刻を正しく管理できます。
Alluxio は一般的なキャッシュ ソリューションであるため、メタデータを Alluxio に渡すには Presto などのコンピューティング エンジンが必要です。したがって、Presto サイトでは、HiveFileContext を使用します。 Hive テーブルまたは Hudi テーブルのデータ ファイルごとに、Presto は HiveFileContext を作成します。 Alluxio は、Presto ファイルを開くときにこの情報を利用します。
openFile を呼び出すと、Alluxio は PrestoCacheContext の新しいインスタンスを作成します。これは、HiveFileContext を保持し、スコープ (4 つのレベル: データベース、スキーマ、テーブル、パーティション)、クォータ、キャッシュ識別子 (つまり、ファイル パスの md5 値)、およびその他の情報。このキャッシュ コンテキストをローカル ファイル システムに渡します。したがって、Alluxio はメタデータを管理し、メトリックを収集できます。
Presto から Alluxio にデータを渡すだけでなく、Presto にコールバックすることもできます。クエリ操作を実行すると、キャッシュにヒットした読み取りデータのバイト数や、外部 HDFS ストレージから読み取られたデータのバイト数など、いくつかの内部メトリックがわかります。
以下に示すように、PrestoCacheContext を含む HiveFileContext をローカル キャッシュ ファイル システム (LocalCacheFileSystem) に渡します。その後、ローカル キャッシュ ファイル システムは CacheContext にコールバックします (IncremetCounter)。次に、このコールバック チェーンは HiveFileContext に続き、次に RuntimeStats に続きます。
Presto では、RuntimeStats を使用して、クエリの実行時にメトリック情報を収集し、集計操作を実行できるようにします。その後、Presto の UI または JSON ファイルでローカル キャッシュ ファイル システムに関する情報を確認できます。上記のプロセスで、Alluxio と Presto を緊密に連携させることができます。 Presto 側では、より優れた統計があります。 Alluxio 側では、メタデータをより明確に把握できます。
上記のコールバック プロセスによって CacheContext のライフサイクルが大幅に長くなるため、GC レイテンシの上昇に関する問題がいくつか発生しましたが、これに対処するために取り組んでいます。
私たちが提案するファイルレベルのメタデータに基づいて、セマンティック キャッシュ (SC) を実装します。たとえば、フッター、インデックスなどのデータ構造を Parquet または ORC ファイルに保存できます。
より効率的な逆シリアル化を実現するために、protobuf の代わりに flatbuf を使用します。 protobuf は ORC ファクトリでメタデータを保存するために使用されますが、ORC のメタデータは、Alluxio と Facebook のコラボレーションにおける合計 CPU 使用量の 20 ~ 30% 以上をもたらすことがわかりました。そのため、既存の protobuf を flatbuf に置き換えてキャッシュとメタデータを格納することを計画しています。これにより、デシリアライズのパフォーマンスが大幅に向上することが期待されます。
要約すると、前回のブログと合わせて、この 2 部構成のブログ シリーズでは、Uber の Presto と Alluxio コミュニティ間の最近のオープンソース コラボレーションに基づいて、Presto フリートに必要なホット データの新しいキャッシュ レイヤーをどのように作成したかを共有します。このアーキテクチャ的にシンプルでクリーンなアプローチは、マネージド SSD と一貫したハッシュベースのソフト アフィニティ スケジューリングにより、HDFS レイテンシを大幅に削減できます。コミュニティ Slackチャンネルで 9000 人以上のメンバーに参加して、詳細を確認してください。
Chen Liangは Uber のインタラクティブ分析チームのシニア ソフトウェア エンジニアで、Presto を専門としています。 Uber に入社する前は、LinkedIn のビッグデータ プラットフォームのスタッフ ソフトウェア エンジニアでした。 Chen は、Apache Hadoop のコミッターおよび PMC メンバーでもあります。チェンは、デューク大学とブラウン大学で 2 つの修士号を取得しています。
Dr. Beinan Wangは Alluxio のソフトウェア エンジニアで、PrestoDB のコミッターです。 Alluxio の前は、Twitter の Presto チームの Tech Lead であり、Twitter のデータ プラットフォーム用に大規模な分散 SQL システムを構築しました。彼は、パフォーマンスの最適化、分散キャッシュ、およびボリューム データ処理に 12 年間取り組んできた経験があります。彼は博士号を取得しました。シラキュース大学で、分散システムのシンボリック モデル チェックと実行時検証に関するコンピューター エンジニアリングの博士号を取得しました。