1. ホーム
  2. file

[解決済み] 他のフォーマットと比較して、parquetフォーマットの長所と短所は何ですか?

2022-03-06 20:35:10

質問

Apache Parquetの特徴は?

  • 自己記述型
  • カラムナー形式
  • 言語非依存

Avro、Sequence Files、RC Fileなどとの比較で。フォーマットの概要が知りたい。私はすでに読んでいます。 ImpalaとHadoopのファイルフォーマットとの連携について しかし、それぞれのフォーマットにおいて、データへのアクセスやデータの保存がどのように行われているのか知りたいのです。Parquetは他のフォーマットに対してどのような優位性を持っているのでしょうか?

解決方法は?

主な違いは、レコード指向のフォーマットとカラム指向のフォーマットに関するものだと思います。 レコード指向のフォーマットは、私たちがよく使うもので、テキストファイルやCSV、TSVのような区切りフォーマットです。 AVROは、レコードのカラムを追加したり削除したりといったスキーマの変更が可能なため、これらのフォーマットより少しクールです。 その他、様々なフォーマット(特に圧縮を含む)のトリックとして、フォーマットが分割できるかどうか、つまり、データセットのどこからでもレコードのブロックを読み込んで、そのスキーマを知ることができるかどうかということがあります。 しかし、Parquetのようなカラムナーフォーマットについては、ここにもっと詳しく書いてある。

Parquetやその他のカラムナーフォーマットは、Hadoopでよく見られる状況を非常に効率的に処理します。 うまく設計されたリレーショナルデータベースで想定されるよりも多くのカラムを持つテーブル(データセット)を持つことはよくあることです。 これは、私たちがしばしばHadoopを 非正規化 確かに、たくさんの値が繰り返され、たくさんのテーブルが1つにまとめられます。 しかし、すべての結合がうまくいくので、クエリーが非常に簡単になります。 他にも、ステート・イン・タイムのデータを保持できるなどの利点があります。 いずれにせよ、1つのテーブルに大量のカラムを持つことはよくあることです。

例えば、132のカラムがあり、そのうちのいくつかは非常に長いテキスト・フィールドで、異なるカラムが次々に現れ、1レコードあたり10Kを使い切るとしましょう。

このようなテーブルへの問い合わせはSQLの立場からすると簡単ですが、100以上のカラムのうち、いくつかのカラムだけを基に、ある範囲のレコードを取得したい場合がよくあります。 例えば、2月と3月の売上高が500ドルの顧客のレコードをすべて取得したい場合です。

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

カラムナー形式では、レコードの各カラム(フィールド)は、ディスク上の多くの異なるブロックに分散して、同じ種類の他のカラムと一緒に保存されます--年のカラム、月のカラム、顧客社員ハンドブック(または他の長いテキスト)のカラム、その他レコードを巨大化するすべてのものがディスク上の別々の場所にあり、もちろん売上のカラムも一緒に保存されます。 日付も月も数字だし、売上高も数バイトしかない。 各レコードの数バイトを読むだけで、どのレコードがクエリにマッチするかを判断できるとしたら、素晴らしいことではないでしょうか? 列挙型ストレージの出番です。

パーティションがなくても、クエリに必要な小さなフィールドのスキャンは超高速です。レコードごとに順番に並んでいて、すべて同じサイズなので、ディスクが求めるデータ量は、含まれるレコードをチェックするのに比べてはるかに少なくて済みます。 従業員ハンドブックやその他の長いテキストフィールドに目を通す必要はなく、ただ無視すればいいのです。 このように、行ではなく列をグループ化することで、ほとんどの場合、より少ないデータでスキャンすることができます。 勝利

でも、もっといいことがあります。 もしクエリがこれらの値とあといくつか(132カラムのうち10カラムとします)だけ知っていればよく、従業員ハンドブックカラムは気にしないとしたら、返すべき正しいレコードを選んだら、あとは結果を表示するのに必要な10カラムに戻るだけで、データセットの132のうち他のカラムは無視することになるのです。 ここでもまた、多くの読み飛ばしが発生します。

(例えば、2つのテーブルを結合して1つの大きな結果セットにし、新しいテーブルとして保存する場合、ソースはいずれにしても完全にスキャンされるため、読み込みパフォーマンスにはあまりメリットがなく、列挙型フォーマットはどこに何があるかをより多く記憶する必要があるため、同様の行フォーマットより多くのメモリを使用します)。

もう一つ、カラムナーの利点は、データが分散していることです。 1つのレコードを取得するために、132人のワーカーがそれぞれ132ブロックのデータから132の異なる場所にデータを読み書きすることができます。 並列化バンザイ!

圧縮アルゴリズムは、繰り返しのパターンを見つけることができれば、より効果的に機能します。 例えば AABBBBBBCCCCCCCCCCCCCCCC として 2A6B16C しかし ABCABCBCBCBCCCCCCCCCCCCCC は、これほど小さくはならないでしょう(まあ、実際には、この場合はそうなのですが、私を信じてください :-) )。 というわけで、もう一度言いますが、読む量は減ります。 そして書くことも。

そのため、一般的なクエリに答えるために読み込むデータが大幅に減り、並行して読み書きができるようになる可能性があり、圧縮もより効果的になる傾向があります。

入力側が大きく、出力側がフィルタリングされたサブセットである場合、カラムナーは素晴らしいです:大きいものから小さいものまで素晴らしいです。 入力と出力がほぼ同じである場合は、それほど有益ではありません。

しかし、私たちの場合、Impalaは5分、10分、20分、30分かかる古いHiveのクエリを、数秒から1分程度で終わらせることができたのです。

ご質問の答えの一端でもお役に立てれば幸いです。