ファイル保存形式
Hive の公式 Web サイトから、Apache Hive は、Apache Hadoop で使用されるいくつかの使い慣れたファイル形式 ( . 、 . 、 . TextFile(文本格式)
、 .など)を サポートしています。RCFile(行列式文件)
SequenceFile(二进制序列化文件)
AVRO
ORC(优化的行列式文件)
Parquet
TextFile
SequenceFile
ORC
Parquet
これら 2 つの行列式ストレージを詳しく見てみましょう。
1、オーク
1.1 ORC ストレージ構造
まず、公式ウェブサイトから ORC ストレージ モデル図を取得します。
少し複雑に見えるので、少し簡略化して説明するために簡単な図を描きました
左の図は、従来の行ベースのデータベース格納方法を示しています.行ごとに格納されています.格納インデックスがない場合、フィールドをクエリする必要がある場合は、行全体のデータを見つけてからフィルタリングする必要があります.これはより多くの IO. リソースを消費するため、当初は Hive でこの問題を解決するために index メソッドが使用されていました。
ただし、インデックスのコストが高いため、「現在の Hive 3.X ではインデックスが廃止されている」ため、もちろんカラムナ ストレージは以前から導入されてきました。
カラムナストレージの格納方法は、上図右図のように1列ずつ格納する方式で、この場合、フィールドのデータをクエリすればインデックスクエリに相当し、効率が高い. ただし、テーブル全体を検索する必要がある場合は、すべての列を取得して個別に集計する必要があるため、より多くのリソースが必要になります。そこで、ORC 行列式ストレージが登場しました。
-
全表スキャンが必要な場合は、行グループごとに読み取ることができます
-
列データを取得する必要がある場合は、すべての行グループのすべての行のデータと 1 つの行のすべてのフィールドのデータではなく、行グループに基づいて指定された列を読み取ります。
ORC ストレージの基本的なロジックを理解したら、ストレージ モデル図を見てみましょう。
同時に、以下に詳細なテキストも添付しましたので、確認してください。
-
ストライプ: ORC ファイルにデータが格納される場合、通常、各ストライプは HDFS のブロック サイズです。(以下の3部構成)
index data:保存了所在条带的一些统计信息,以及数据在 stripe中的位置索引信息。
rows data:数据存储的地方,由多个行组构成,每10000行构成一个行组,数据以流( stream)的形式进行存储。
stripe footer:保存数据所在的文件目录
-
ファイル フッター: ファイル内の sipe のリスト、各ストライプの行数、および各列のデータ型が含まれます。また、各列の最小、最大、行数、合計などの集計情報も含まれています。
-
追記: 圧縮パラメータと圧縮サイズに関する情報が含まれています
実際、ORC は、ファイル レベル、ストリップ レベル、および行グループ レベルの 3 つのレベルのインデックスを提供することがわかりました.したがって、クエリを実行するとき、これらのインデックスを使用して、クエリ条件を満たさないほとんどのファイルとデータ ブロックを回避できます。 .
ただし、ORC 内のすべてのデータの記述情報は、保存されたデータと一緒にまとめられ、外部データベースを使用しないことに注意してください。
「特記事項: ORC 形式のテーブルもトランザクション ACID をサポートしますが、トランザクションをサポートするテーブルはバケット テーブルである必要があるため、データの大きなバッチを更新するのに適しています。小さなデータのバッチをトランザクションで頻繁に更新することはお勧めしません」
#开启并发支持,支持插入、删除和更新的事务
set hive. support concurrency=truei
#支持ACID事务的表必须为分桶表
set hive. enforce bucketing=truei
#开启事物需要开启动态分区非严格模式
set hive.exec,dynamicpartition.mode-nonstrict
#设置事务所管理类型为 org. apache.hive.q1. lockage. DbTxnManager
#原有的org. apache. hadoop.hive.q1.1 eckmar. DummyTxnManager不支持事务
set hive. txn. manager=org. apache. hadoop. hive. q1. lockmgr DbTxnManageri
#开启在相同的一个 meatore实例运行初始化和清理的线程
set hive. compactor initiator on=true:
#设置每个 metastore实例运行的线程数 hadoop
set hive. compactor. worker threads=l
#(2)创建表
create table student_txn
(id int,
name string
)
#必须支持分桶
clustered by (id) into 2 buckets
#在表属性中添加支持事务
stored as orc
TBLPROPERTIES('transactional'='true‘);
#(3)插入数据
#插入id为1001,名字为student 1001
insert into table student_txn values('1001','student 1001');
#(4)更新数据
#更新数据
update student_txn set name= 'student 1zh' where id='1001';
# (5)查看表的数据,最终会发现id为1001被改为 sutdent_1zh
1.2 ORCについてのハイブ構成
テーブル構成プロパティ (テーブルの作成時に構成されます。たとえば、tblproperties ('orc.compress'='snappy');
)
-
orc.compress: ORC ファイルの圧縮タイプを示します. "The optional types are NONE, ZLB and SNAPPY. The default value is ZLIB (Snappy does not support slices)" --- この構成は最も重要です。
-
orc.compress.Slze: 圧縮されたブロック (チャンク) のサイズを示します。デフォルト値は 262144 (256KB) です。
-
orc.stripe.size: 書き込みストライプ、使用できるメモリ バッファ プールのサイズ、デフォルト値は 67108864 (64MB)
-
orc.row.index.stride: 行グループ レベル インデックスのデータ サイズ。デフォルトは 10000 です。10000 以上の数値に設定する必要があります。
-
orc.create index: 行グループ レベルのインデックスを作成するかどうか。デフォルトは true
-
orc.bloom filter.columns: ブルーム フィルターを作成する必要があるグループ。
-
orc.bloom filter fpp: ブルーム フィルターを使用した偽陽性 (False Positive) の確率。デフォルト値は 0 です。
拡張: Hive でブルーム フィルターを使用すると、ファイル容量の少ないテーブルにデータが格納されているかどうかをすばやく判断できますが、このテーブルに属さないデータがこのテーブルに属していると判断される状況もあります。偽陽性確率と呼ばれ、開発者は確率を調整できますが、確率が低いほどブルーム フィルターが必要になります。
2、寄木細工
上記の ORC について説明した後、行と列のストレージの基本的な理解も得られました。Parquet は、もう 1 つの高性能な行と列のストレージ構造です。
2.1 Parquet のストレージ構造
ORC は非常に効率的であるため、なぜ別の Parquet が存在する必要があるのでしょうか。それは、「Parquet は、Hadoop エコシステム内の任意のプロジェクトで利用できる圧縮された効率的な列データ表現を作成するためのものである」ためです。
❝Parquet is language-independent and is not bound to any data processing framework. さまざまな言語とコンポーネントに適しています. Parquet と連携できるコンポーネントは次のとおりです。
クエリ エンジン: Hive、Impala、Pig、Presto、Drill、Tajo、HAWQ、IBM Big SQL
コンピューティング フレームワーク: MapReduce、Spark、Cascading、Crunch、Scalding、Kite
データ モデル: Avro、Thrift、プロトコル バッファ、POJO
❞
Parquet のストレージ構造を見てみましょう。まず公式 Web サイトを見てください。
ちょっと大きいので簡略版で描いてみます
Parquet files are stored in binary format, so they cannot be read directly. ORC と同様に、ファイルのメタデータはデータと共に保存されるため、Parquet 形式のファイルは自己解析されます。
-
行グループ: 各行グループには一定数の行が含まれ、orc のストライプの概念と同様に、少なくとも 1 つの行グループが HDFS ファイルに格納されます。
-
列チャンク: 行グループの各列は列ブロックに格納され、行グループのすべての列はこの行グループ ファイルに連続して格納されます。列ブロック内の値はすべて同じ型であり、異なる列ブロックは異なるアルゴリズムを使用して圧縮される場合があります。
-
ページ: 各列ブロックは複数のページに分割されます. ページは最小のコーディング単位です. 同じ列ブロック内の異なるページは異なるコーディング方法を使用する場合があります.
2.2Parquet テーブルの構成プロパティ
-
parquet.block size: デフォルト値は 134217728 バイト (128 MB) で、メモリ内の行グループのブロック サイズを示します。この値を大きく設定すると、Parquet ファイルの読み取り効率が向上しますが、その分、書き込み時に多くのメモリが消費されます。
-
parquet.page:size: デフォルト値は 1048576byte の 1MB で、各ページ (ページ) のサイズを示します。これは特に圧縮されたページサイズを指し、ページのデータは読み取り時に最初に解凍されます。ページは Parquet 操作データの最小単位であり、データにアクセスするたびにデータのページ全体を読み取る必要があります。この値が小さすぎると、圧縮時にパフォーマンスの問題が発生します。
-
parquet.compression: デフォルト値は UNCOMPRESSED で、ページの圧縮方法を示します。"利用可能な圧縮方法は、UNCOMPRESSED、SNAPPY、GZP、および LZO です" .
-
parquet enable. dictionary: デフォルトは tue で、辞書エンコーディングが有効かどうかを示します。
-
parquet.dictionary page.size: デフォルト値は 1048576 バイトで、1 MB です。ディクショナリ エンコーディングを使用すると、Parquet の各行と列にディクショナリ ページが作成されます。ディクショナリ エンコーディングを使用すると、格納されたデータ ページに多くの繰り返しデータがある場合、圧縮効果が高くなり、各ページのメモリ占有量を減らすこともできます。
3. ORC と寄木細工の比較
同時に、「Hive Performance Tuning in Practice」の著者の事例から、ORC と Parquet のストレージ形式をそれぞれ使用する 2 つのテーブルに、同じデータをインポートし、SQL クエリを実行すると、「ORC を使用して読み取った行がは Parquet よりもはるかに小さい"ため、ORC をストレージとして使用すると、メタデータを利用して不要なデータをさらに除外でき、クエリに必要なクラスター リソースは Parquet よりも少なくなります。(より詳細なパフォーマンス分析については、https://blog.csdn.net/yu616568/article/details/51188479 に移動してください)
「つまり、ストレージに関しては ORC の方が優れているように見えます」
圧縮方法
フォーマット | 割り切れる | 平均圧縮速度 | テキストファイルの圧縮効率 | Hadoop 圧縮コーデック | Pure Java の実装 | ネイティブ | 述べる |
---|---|---|---|---|---|---|---|
gzip | 番号 | 素早い | 高い | org.apache.hadoop.io.compress.GzipCodec | はい | はい | |
イゾ | はい(使用するライブラリによって異なります) | とても早い | 中くらい | com.hadoop.compression.lzo.LzoCodec | はい | はい | 各ノードに LZO をインストールする必要があります |
bzip2 | はい | スロー | とても高い | org.apache.hadoop.io.compress.Bzip2Codec | はい | はい | 割り切れるバージョンには純粋な Java を使用する |
zlib | 番号 | スロー | 中くらい | org.apache.hadoop.io.compress.DefaultCodec | はい | はい | Hadoop のデフォルトの圧縮コーデック |
スナッピー | 番号 | とても早い | 低い | org.apache.hadoop.io.compress.SnappyCodec | 番号 | はい | Snappy には純粋な Java ポートがありますが、Spark/Hadoop では動作しません |
ストレージと圧縮の組み合わせを選択する方法
ORC と寄木細工の要件によると、一般的に
1. ORC 形式のストレージ、Snappy 圧縮
create table stu_orc(id int,name string)
stored as orc
tblproperties ('orc.compress'='snappy');
2、Parquet 形式のストレージ、Lzo 圧縮
create table stu_par(id int,name string)
stored as parquet
tblproperties ('parquet.compression'='lzo');
3、Parquet 形式のストレージ、Snappy 圧縮
create table stu_par(id int,name string)
stored as parquet
tblproperties ('parquet.compression'='snappy');
Hive の SQL は MR タスクに変換されるため、ファイルが ORC に格納されている場合、Snappy はそれを圧縮します.Snappy はファイル分割をサポートしていないため、圧縮されたファイルは「1 つのタスクでしか読み取られない」 .圧縮ファイルが大きい場合、その場合、ファイルのマップを処理するのに必要な時間は、通常のファイルのマップを読み取る時間よりもはるかに長くなります。これは、「ファイルを読み取るマップのデータ スキュー」と呼ばれることがよくあります。
このような状況を回避するには、データを圧縮する際に、bzip2 や Zip などのファイル分割をサポートする圧縮アルゴリズムを使用する必要があります。ただし、ORC は前述の圧縮方法をサポートしていません。そのため、大きなファイルに遭遇する可能性がある場合に、データの偏りを避けるために ORC を選択しないのはこのためです。
In the Hve on Spark approach, the same is true. 分散アーキテクチャとしての Spark は、通常、複数の異なるマシンから一緒にデータを読み取ろうとします。これを実現するには、各ワーカー ノードが新しいレコードの先頭を見つけられる必要があるため、ファイルを分割する必要がありますが、分割できない圧縮形式のファイルの中には、単一のノードですべてのデータを読み取る必要があるものがあります。これは簡単に行うことができます。パフォーマンスのボトルネックを作成します。