このブログ投稿は、Clouderaとの統合前にHortonworks.comで公開されていました。一部のリンク、リソース、または参照は、正確でなくなる可能性があります。
これは、HBaseテーブルとの対話にHiveを使用することを検討している2つの投稿の最初の投稿です。 2番目の投稿はこちらです。
よく聞かれるのは、ApacheHiveのHBaseの使い方です。それを行う方法だけでなく、何が機能するか、どれだけうまく機能するか、そしてそれをうまく活用する方法。私はこの分野で少し調査を行ったので、これが私以外の誰かにも役立つことを願っています。これは、HBase in Actionで取り上げなかったトピックです。おそらく、これらのメモが第2版の基礎になるでしょう😉これらのメモは、HBase0.94.xと組み合わせて使用されるHive0.11.xに適用されます。まだすべてをテストしていませんが、0.12.x+0.96.xにほぼ適用できるはずです。
ハイブプロジェクトには、HBaseとやり取りするためのオプションのライブラリが含まれています。ここに、2つのシステム間のブリッジレイヤーが実装されます。 HiveクエリからHBaseにアクセスするときに使用する主要なインターフェースは、BaseStorageHandler
と呼ばれます。 。入力形式と出力形式を介してHBaseテーブルを直接操作することもできますが、ハンドラーはよりシンプルで、ほとんどの用途で機能します。
HiveのHBaseテーブル
HBaseStorageHandler
を使用します HBaseテーブルをHiveメタストアに登録します。オプションで、HBaseテーブルをEXTERNAL
として指定できます。 、この場合、Hiveはそのテーブルを直接ドロップするように作成しません。そのためには、HBaseシェルを使用する必要があります。
[sql]
CREATE [EXTERNAL] TABLE foo(…)
STORED BY'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
TBLPROPERTIES('hbase.table.name' =' bar');
[/ sql]
上記のステートメントは、bar
という名前のHBaseテーブルを登録します Hiveメタストア内。foo
という名前でHiveからアクセスできます。 。
内部的には、HBaseStorageHandler
HBaseテーブルとの相互作用をHiveHBaseTableInputFormat
に委任しています およびHiveHBaseTableOutputFormat
。必要に応じて、これらのクラスを直接使用して、HBaseテーブルをHiveに登録できます。上記のステートメントは、おおよそ次のようになります。
[sql]
CREATE TABLE foo(…)
STORED AS
INPUTFORMAT'org.apache.hadoop.hive.hbase.HiveHBaseTableInputFormat'
OUTPUTFORMAT'org.apache.hadoop.hive .hbase.HiveHBaseTableOutputFormat'
TBLPROPERTIES(' hbase.table.name'=' bar');
[/ sql]
HiveHFileOutputFormat
も提供されます つまり、Hiveからバルクロード用のHFileを生成することも可能であるはずです。実際には、これをエンドツーエンドで機能させることはできません(HIVE-4627を参照)。
スキーママッピング
テーブルの登録は最初のステップにすぎません。その登録の一部として、列マッピングも指定する必要があります。これは、Hiveの列名をHBaseテーブルの行キーと列にリンクする方法です。 hbase.columns.mapping
を使用してこれを行います SerDeプロパティ。
[sql]
CREATE TABLE foo(rowkey STRING、a STRING、b STRING)
STORED BY'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES('hbase.columns .mapping'=':key、f:c1、f:c2')
TBLPROPERTIES(' hbase.table.name'=' bar');
…
[/sql]
マッピングプロパティで提供される値は、ハイブテーブルの列名と1対1で対応します。 HBaseの列名は列ファミリーによって完全に修飾されており、特別なトークン:key
を使用します 行キーを表します。上記
例では、HBaseテーブルのbar
から行を作成します Hiveテーブルfoo
から利用可能 。 foo
列rowkey
HBaseのテーブルの行キーa
にマップします c1
へ f
で 列ファミリー、およびb
c2
へ 、f
にもあります 家族。
HiveのMAP
を関連付けることもできます HBase列ファミリーへのデータ構造。この場合、STRING
のみ ハイブタイプを使用しています。現在サポートされている他のHiveタイプは、BINARY
です。 。その他の例については、wikiページを参照してください。
データとのやり取り
列マッピングを定義すると、他のHiveデータと同じようにHBaseデータにアクセスできるようになります。現在サポートされているのは、単純なクエリ述語のみです。
[sql]
SELECT * FROMfooWHERE…;
[/ sql]
Hiveを使用してHBaseテーブルにデータを入力することもできます。これは、INTO
の両方で機能します およびOVERWRITE
条項。
[sql]
FROM source_hive_table INSERT INTO TABLE my_hbase_table
SELECTsource_hive_table。*WHERE…;
[/ sql]
Hive 0.12.0には、この機能を壊すリグレッションがあることに注意してください。HIVE-5515を参照してください。
実際には
実行時にすべてを適切に接続するには、まだ少し精巧さが必要です。 HBaseインタラクションモジュールは完全にオプションであるため、HBaseの依存関係がHiveのクラスパスで利用可能であることを確認する必要があります。
[bash]
$ exportHADOOP_CLASSPATH=…
$hive -e“ CREATETABLE…STOREDBY‘org.apache…HBaseStorageHandler'”
[/ bash]
インストール環境は、ユーザーにとってこれをより適切に処理できる可能性がありますが、当面は自分で管理する必要があります。理想的にはhive
binスクリプトは、HBaseの存在を検出し、必要なCLASSPATH
を自動的に作成できます。 調整。この機能強化は、HIVE-2055で追跡されているようです。ラストマイルはディストリビューション自体によって提供され、環境変数がhive
に設定されていることを確認します 。この機能は、BIGTOP-955によって提供されます。
また、Hiveステートメントを実行するときに、必要なjarがMapReduceジョブに送信されていることを確認する必要があります。 Hiveは、auxjars機能を介して追加のジョブ依存関係を出荷するためのメカニズムを提供します。
[bash]
$ exportHIVE_AUX_JARS_PATH=…
$hive -e“ SELECT *FROM…”
[/ bash]
HIVE_AUX_JARS_PATH
のユーザー指定の値をマスクするHDP-1.3ビルドの小さなバグを発見しました。 。管理者権限を使用すると、hive-env.sh
の行を修正することで簡単に修正できます。 既存の価値を尊重します。
ユーザースクリプトの回避策は、SET
を使用することです。 HiveCLIを起動したら値を提供するステートメント。
[bash]
SEThive.aux.jars.path=…
[/bash]
Hiveは、必要なjarを検出し、それ自体を追加できる必要があります。 HBaseは、TableMapReduceUtils#addDependencyJars
を提供します この目的のための方法。これは、少なくともHIVE-2379によると、hive-0.12.0で行われているようです。
今後の作業
述語プッシュダウン(HIVE-1643、HIVE-2854、HIVE-3617、
HIVE-3684)とデータ型認識(HIVE-1245、HIVE-2599)の適切なサポートについて多くのことが言われています。これらは、述語のセマンティクスが動作するタイプの観点から定義されているため、密接に関連しています。 MapsやStructsなどのHiveの複雑なデータ型をHBase列ファミリー(HIVE-3211)にマッピングするためにさらに多くのことができる可能性があります。 HBaseタイムスタンプのサポートは少し面倒です。粒度のレベルが高いHiveアプリケーション(HIVE-2828、HIVE-2306)では使用できません。ユーザーが行う唯一のやり取りは、すべての操作でカスタムタイムスタンプを作成するためのストレージハンドラー設定を介したものです。
パフォーマンスの観点から、HBaseを利用するためにHiveが今日できること(つまり、データ型に依存しないこと)があります。また、HBase対応のHiveがHBaseテーブルを中間ストレージロケーション(HIVE-3565)として利用し、HBaseにロードされたディメンションテーブルに対するマップ側の結合を容易にする可能性もあります。 Hiveは、HBaseの自然なインデックス構造(HIVE-3634、HIVE-3727)を利用して、大量のスキャンを節約できる可能性があります。現在、ユーザーは実行されるスキャンを(何も)制御できません。ジョブごと、または少なくともテーブルごとの構成を有効にする必要があります(HIVE-1233)。これにより、HBaseに精通したユーザーが、HBaseとの対話方法に関するヒントをHiveに提供できるようになります。 HBaseはすでにテーブルのパーティションを管理しているため、HBaseテーブルの単純な分割サンプリング(HIVE-3399)のサポートも簡単に実行できます。
その他のアクセスチャネル
これまでに説明したことはすべて、HiveがオンラインのHBaseRegionServerと対話する必要がありました。アプリケーションは、HDFSに永続化されたHBaseデータと直接対話することで、スループットを大幅に向上させ、柔軟性を高めることができます。これには、HiveワークロードがオンラインのSLAにバインドされたHBaseアプリケーションに干渉するのを防ぐという利点もあります(少なくとも、タスク間のQOS分離でHBaseの改善が見られるまではHBASE-4441)。
前述のように、HiveHFileOutputFormat
があります 。 HIVE-4627を解決すると、Hiveは一括読み込み用のHFileを生成する簡単な方法になります。 Hiveを使用してHFilesを作成した後も、
LoadIncrementalHFiles
を実行する最後のステップがあります。 それらをリージョンにコピーして登録するユーティリティ。このため、HiveStorageHandler
インターフェースは、作成時にクエリプランに影響を与え、ステップを追加できるようにするために、なんらかのフックが必要になります。配置が完了すると、SET
が可能になります。 ランタイムフラグ、INSERT
を切り替えます バルクロードを使用する操作。
HBaseは最近、テーブルスナップショット機能を導入しました。これにより、ユーザーは、HDFSに永続化されたテーブルの永続化されたポイントインタイムビューを作成できます。 HBaseは、テーブルをスナップショットから以前の状態に復元し、既存のスナップショットからまったく新しいテーブルを作成することができます。 Hiveは現在、HBaseスナップショットからの読み取りをサポートしていません。さらに言えば、この機能は進行中の作業ですが、HBaseはスナップショットに対するMapReduceジョブをまだサポートしていません(HBASE-8369)。
結論
HBaseとHiveの間のインターフェースは若いですが、素晴らしい可能性を秘めています。物事をより簡単かつ迅速に行うために拾うことができる、ぶら下がっている果物がたくさんあります。実際のアプリケーション開発を除いて最も明白な問題は、Hiveの型付きの高密度スキーマとHBaseの型なしのスパーススキーマの間のインピーダンスの不一致です。これは、技術的な問題と同じくらい認知的な問題です。ここでのソリューションでは、パフォーマンスの改善など、多くの改善を行うことができます。データ型をHBase(HBASE-8089)に追加する作業を継続することで、このギャップを埋めることができると期待しています。
基本的な操作は、少なくとも基本的な方法で、ほとんど機能します。 Hiveを使用して、HBaseからデータを読み取り、HBaseにデータを書き戻すことができます。環境の構成は不透明で手動のプロセスであり、初心者がツールを採用するのを妨げる可能性があります。一括操作の問題もあります。Hiveを使用したHFilesの書き込みとHBaseスナップショットの読み取りのサポートは、現時点では完全に不足しています。そしてもちろん、いたるところにバグが散らばっています。最近の最大の改善点は、HCatalogのインターフェースの廃止であり、使用するインターフェースに関する必要な事前の決定が削除されています。
Hiveは、HBase上に非常に使いやすいSQLインターフェースを提供します。これは、多くの既存のETLワークフローに簡単に統合できます。このインターフェースでは、HBaseが提供するBigTableセマンティクスの一部を簡素化する必要がありますが、その結果、HBaseをより多くのユーザーに開放することができます。 Hiveの相互運用機能は、Phoenixが提供するエクスペリエンスを非常によく補完します。 Hiveには、そのシステムで現在必要とされている展開の複雑さを必要としないという利点があります。タイプの一般的な定義により、無料の将来が可能になることを願っています。