他のフォーマットと比較した寄木細工のフォーマットの長所と短所は何ですか?


136

Apache Parquetの特徴は次のとおりです。

  • 自己記述
  • カラムナー形式
  • 言語に依存しない

Avro、Sequence Files、RC Fileなどと比較して、フォーマットの概要を知りたい。私はすでに読んでいます:ImpalaがHadoopファイル形式でどのように機能するか、それは形式に関するいくつかの洞察を提供しますが、データへのアクセスとデータのストレージがこれらの各形式でどのように行われるかを知りたいです。寄木細工は他のものよりどのように有利ですか?


2
このプレゼンテーションには、すばらしい要約があります。リンク
Dominik

@ ani-menonリンクが切れています。
Sajjad Hossain

@SajjadHossainが更新されました。
Ani Menon

回答:


282

私が説明できる主な違いは、レコード指向形式と列指向形式に関連していると思います。レコード指向のフォーマットは、テキストファイル、CSV、TSVなどの区切られたフォーマットなど、私たちが慣れ親しんでいるものです。AVROは、レコードから列を追加または削除するなど、時間の経過とともにスキーマを変更する可能性があるため、それらよりも少しクールです。さまざまな形式(特に圧縮を含む)の他のトリックには、形式を分割できるかどうかが含まれます。つまり、データセットの任意の場所からレコードのブロックを読み取っても、スキーマがわかっていますか?ただし、Parquetのような列形式の詳細は次のとおりです。

寄木細工やその他の柱状形式は、一般的なHadoopの状況を非常に効率的に処理します。適切に設計されたリレーショナルデータベースで期待するよりもはるかに多くの列を持つテーブル(データセット)を持つことは一般的です。100列または200列は珍しいことではありません。これは、リレーショナル形式からデータを非正規化する場所としてHadoopをよく使用するためです。そうです。多くの繰り返し値と多くのテーブルがすべて1つにフラット化されます。ただし、すべての結合が計算されるため、クエリがはるかに簡単になります。タイムインステートデータを保持するなど、他にも利点があります。とにかく、テーブルに大量の列があるのが一般的です。

たとえば、132の列があり、それらのいくつかは本当に長いテキストフィールドであり、それぞれ異なる列が次々に続き、レコードごとにおそらく10Kを使用するとします。

これらのテーブルのクエリはSQLの観点からは簡単ですが、これらの100以上の列のいくつかだけに基づいて特定の範囲のレコードを取得することが一般的です。たとえば、売上が500ドルを超える顧客の2月と3月のすべてのレコードが必要な場合があります。

これを行形式で行うには、クエリでデータセットのすべてのレコードをスキャンする必要があります。最初の行を読み取り、レコードをフィールド(列)に解析し、日付と販売の列を取得し、条件を満たす場合は結果に含めます。繰り返す。10年(120か月)の履歴がある場合、2つの月を見つけるためにすべてのレコードを読み取ります。もちろん、これは年と月にパーティションを使用する絶好の機会ですが、それでも、顧客の売上が500ドルを超えているかどうかを調べるために、これらの2か月の各レコード/行の10Kを読み取り、解析しています。

列形式では、レコードの各列(フィールド)は、その種類の他の列と共に格納され、ディスク上の多くの異なるブロック全体に広がります-年の列、月の列、顧客の従業員のハンドブックの列(またはその他)長いテキスト)、そしてそれらのレコードをディスク上の別々の場所にすべて巨大化する他のすべて、そしてもちろん一緒に販売するための列。まあ、日付と月は数字であり、売上もそうです-それらはほんの数バイトです。クエリに一致するレコードを特定するために、各レコードの数バイトを読み取るだけでよいのではないでしょうか。救助への柱状の貯蔵!

パーティションがない場合でも、クエリを満たすために必要な小さなフィールドのスキャンは非常に高速です。これらはすべてレコード順に、すべて同じサイズであるため、ディスクは、含まれるレコードのはるかに少ないデータチェックをシークします。その従業員ハンドブックやその他の長いテキストフィールドを読む必要はありません。無視してください。したがって、行ではなく列を互いにグループ化することで、ほとんどの場合、スキャンするデータを減らすことができます。勝つ!

しかし、待ってください、それは良くなります。クエリがこれらの値といくつか(132列のうち10列など)を知る必要があるだけで、その従業員ハンドブック列を気にしていなかった場合、返すべき適切なレコードを選択すると、あとは行かなければなりませんデータセット内の132のうち他の122を無視して、結果をレンダリングするために必要な10列に戻ります。繰り返しますが、多くの読み物をスキップします。

(注:このため、たとえば、2つのテーブルすべてを1つの大きな(結果の)結果セットに結合して新しいテーブルとして保存する場合、ソースを列形式に変換する場合、列形式はお粗末な選択です。とにかく完全にスキャンされるので、読み取りパフォーマンスに大きなメリットはありません。また、カラム形式は、どこにあるかについてより多くのことを覚えておく必要があるため、同様の行形式よりも多くのメモリを使用します)。

柱状のもう1つの利点は、データが分散していることです。単一のレコードを取得するには、132のワーカーがそれぞれ、132のデータブロック上の132の異なる場所との間でデータを読み書きします。並列化が必要です。

そして今、クリンチャーのために:それが繰り返しパターンを見つけることができるとき、圧縮アルゴリズムははるかによく働きます。あなたは、圧縮可能性AABBBBBBCCCCCCCCCCCCCCCCとして2A6B16CはなくABCABCBCBCBCCCCCCCCCCCCCC、小さなとして得ないでしょう(まあ、実際には、このケースでは、それはだろうが、私を信頼して:-))。だから、もう一度、少ない読書。そして、書き込みも。

そのため、一般的なクエリに答えるために読み取るデータがはるかに少なくなり、並列で読み書きする方が潜在的に高速であり、圧縮の方がはるかによく機能する傾向があります。

入力側が大きく、出力がフィルタリングされたサブセットである場合、円柱状は最適です。入力と出力がほぼ同じ場合はそれほど有益ではありません。

しかし、私たちの場合、Impalaは5、10、20、または30分で実行された古いHiveクエリを使用し、ほとんどの場合数秒または1分で終了しました。

これがあなたの質問の少なくとも一部に答えるのに役立つことを願っています!


7
優れた。ありがとうございました。これは、多くのapacheプロジェクトのドキュメントに欠けている非常に便利な要約です。「小さなフィールド...はすべてレコード順です」とあなたは言っています。userid:longとage:intの単純なテーブルがあり、ある年齢のすべてのユーザーを検索したいとします。ここに2つの列があります。順序付けのインデックスはいつ指定する必要がありますか、またはすべての列に効率的にインデックスを付けることができますか?
user48956 2017

1
timeseriesに寄木細工を使用するとどうなりますか?いくつかの列(100+)、各列は異なる周波数(100hz〜0.25hz)のセンサーデータ。それは賢い決断でしょうか?
guilhermecgs 2018

53

Avroは、Hadoopの行ベースのストレージ形式です。

Parquetは、Hadoopの列ベースのストレージ形式です。

通常、ユースケースが各クエリの行のすべてのフィールドをスキャンまたは取得する場合、通常、Avroが最良の選択です。

データセットに多くの列があり、通常、ユースケースでレコード全体ではなく、それらの列のサブセットを使用する場合、Parquetはそのような作業に最適化されています。

ソース


26

トムの回答は非常に詳細で網羅的ですが、Allstate Insuranceで行われたParquetとAvroに関するこの簡単な調査にも興味があるかもしれません。

「全体として、Parquetはすべてのテストで[Avro]よりも同様またはより良い結果を示しました。Parquetの方が大きいデータセットでのクエリパフォーマンスの違いは、圧縮結果によるものです。ワイドデータセットをクエリするとき、Sparkは3.5xを読み取る必要がありました。 ParrotのデータはAvroより少なくなります。疑わしいように、Avroはデータセット全体を処理するときにうまく機能しませんでした。」

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.