はじめに
この実験では、Hive の設定と基本操作を学びます。SQL の基礎知識がある方を対象に、Hive のアーキテクチャ、基本的な導入方法と使い方を理解することを目的としています。
ドキュメント内のサンプルコードは、できるだけコピー&ペーストせず、自分で入力してください。実際に入力することで、コードへの理解が深まります。問題が発生した場合は、ドキュメントをよく確認してください。フォーラムで質問したり、ほかのユーザーと情報交換したりすることもできます。
Hive の概要
このステップでは、Apache Hive が Hadoop に保存された大規模データセットのクエリや分析に SQL インターフェースを提供する仕組みを学びます。まず、Hive のアーキテクチャと主な機能を確認しましょう。
Hive のアーキテクチャ
- コンポーネント:Hive は、テーブルとストレージを管理する
HCatalogと、MapReduce タスクや Pig クエリの実行、REST API を介した Hive メタデータとのやり取りを行うWebHCatで構成されます。 - 機能:
- ETL、データ分析、レポート作成など、データウェアハウス向けの SQL クエリに対応しています。
- データは HDFS や HBase などのストレージシステムに保存されます。クエリ処理は Tez、Spark、MapReduce などの計算エンジンが実行します。
- Hive LLAP、YARN、Slider のサポートを利用して、手続き型言語や HPL-SQL、サブクエリによるデータ取得に対応しています。
Hive の基本データ単位
- データベース:名前空間として機能し、名前の競合を防ぎ、セキュリティを強化します。
- テーブル:同じスキーマを持つデータ単位です。たとえば、
page_viewsテーブルには timestamp、userid、page_url などの列を格納できます。 - パーティション:キーに基づいてデータを分割し、効率的にデータを取得できるようにします。
- バケット:ハッシュ関数の値に基づいてパーティション内のデータを分割し、クエリの効率を高めます。
Hive のデータ型
- プリミティブ型と複合型に対応しています。詳細はHive のデータ型に関するドキュメントを参照してください。
Hive はオンライン・トランザクション処理(OLTP)ではなく、データウェアハウスの処理を目的として設計されています。スケーラビリティ、パフォーマンス、信頼性、フォールトトレランスを重視し、さまざまな入力形式に対応しています。また、異なる形式のコネクタを使って拡張できます。ビッグデータ分析で Hive の機能を活用するには、そのアーキテクチャ、データ単位、データ型を理解することが重要です。
Hive のインストールとデプロイ
このステップでは、ディレクトリ構成、環境変数、メタストア、システムパラメーターなど、Hive のインストールとデプロイに関する内容を確認します。
まず、以降の操作を行うために hadoop ユーザーに切り替えます。デスクトップで Xfce ターミナルをダブルクリックして開き、次のコマンドを入力してください。
su - hadoop
ヒント:ユーザー hadoop のパスワードは hadoop です。
次に、wget コマンドを使って Hive の安定版をダウンロードします。この実験では Hive 2.3.3 を使用します。
sudo wget https://labexfile.oss-us-west-1.aliyuncs.com/courses/144/apache-hive-2.3.3-bin.tar.gz
ダウンロードしたインストールパッケージを展開します。ターミナルで次のコマンドを実行してください。
tar -zxvf apache-hive-2.3.3-bin.tar.gz
展開したディレクトリを /opt に移動します。/opt への書き込みには sudo 権限が必要です。
sudo mv /home/hadoop/apache-hive-2.3.3-bin /opt/hive-2.3.3
ディレクトリを移動したら、Hive のディレクトリの所有者とグループを hadoop に変更します。ターミナルで次のコマンドを実行してください。
sudo chown -R hadoop:hadoop /opt/hive-2.3.3
ヒント:別のターミナルを開き、そこで sudo 権限を使って上記の操作を行うこともできます。
labex:~/ $ ls -al /opt/
total 24
drwxrwxr-x 10 hadoop hadoop 4096 Mar 3 12:01 hive-2.3.3
...
環境変数の設定
このステップでは、Hive の環境変数を設定し、HIVE_HOME が Hive のインストールディレクトリを指すようにします。
まず、vim エディターで hadoop ユーザーの .bashrc ファイルを開きます。ターミナルで次のコマンドを実行してください。
vim /home/hadoop/.bashrc
ファイルの末尾に次の内容を追加します。PATH の設定は、現在の実験環境に合わせて調整してください。$PATH は既存の内容を参照します。PATH 環境変数の末尾に :$HIVE_HOME/bin を追加してください。
export HIVE_HOME=/opt/hive-2.3.3
export PATH=$PATH:$HIVE_HOME/bin
編集が終わったら、ファイルを保存してエディターを終了します。続いて source コマンドを実行し、環境変数を有効にします。
この実験環境には Hive があらかじめインストールされているため、環境変数を source で読み込む必要はありません。実際に Hive をインストールする場合は、状況に応じてこの手順を実行してください。
設定
このステップでは、事前にインストールされた Hive の設定を確認し、チェックに必要な設定ファイルを作成します。
メタストアの設定
Hive を使用する前に、メタデータの保存先を設定する必要があります。Hive はデフォルトで、メタ情報を組み込みの Derby データベースに保存します。ディスク上の保存場所は、Hive の設定ファイル conf/hive-default.xml にある設定項目 javax.jdo.option.ConnectionURL で指定します。デフォルトの保存場所は ./metastore_db です。
この実験では、メタデータの保存先として MySQL を使用します。そのため、Hive の設定ファイルを編集します。
vim エディターで、使用する設定ファイルを作成して開きます。
vim /opt/hive-2.3.3/conf/hive-site.xml
<configuration>
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://localhost:3306/hive_metastore1?createDatabaseIfNotExist=true</value>
</property>
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.cj.jdbc.Driver</value>
</property>
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>hiveuser1</value>
</property>
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>123qweQWE...</value>
</property>
</configuration>
上記の設定項目を編集したら、ファイルを保存してエディターを終了します。
MySQL データベースの作成
sudo mysql コマンドで MySQL Server を起動し、データベース hive_metastore を作成します。
CREATE DATABASE hive_metastore1;
CREATE USER 'hiveuser1'@'localhost' IDENTIFIED BY '123qweQWE...';
GRANT ALL PRIVILEGES ON hive_metastore1.* TO 'hiveuser1'@'localhost';
FLUSH PRIVILEGES;
exit;
続いて MySQL JDBC ドライバーをダウンロードし、/opt/hive-2.3.3/lib ディレクトリにコピーします。
cp /usr/local/hive/lib/mysql-connector-j-8.3.0.jar /opt/hive-2.3.3/lib
Hive のシステムパラメーターの設定
メタストアの設定後、Hive が Hadoop の場所や内部設定ファイルのパスなどを認識できるように、Hive 内部の設定項目を設定します。
まず、cp コマンドを使って設定テンプレートをコピーし、設定ファイルを有効にします。
ターミナルで次のコマンドを実行してください。
cp /opt/hive-2.3.3/conf/hive-env.sh.template /opt/hive-2.3.3/conf/hive-env.sh
次に、vim エディターで hive-env.sh ファイルを開きます。
vim /opt/hive-2.3.3/conf/hive-env.sh
48 行目の HADOOP_HOME に Hadoop のインストールパスを設定します。
HADOOP_HOME=/home/hadoop/hadoop
上記の設定項目を編集したら、ファイルを保存してエディターを終了します。
メタストアの初期化
このステップでは、Hive のメタストアを初期化し、Hive が必要とする Hadoop サービスを起動します。
以降の操作で使用するデータは HDFS に保存するため、あらかじめ HDFS を起動します。ターミナルで次のコマンドを実行してください。
start-dfs.sh
start-yarn.sh
jps コマンドを実行して、サービスの状態を確認します。
hadoop:~/ $ jps [17:31:43]
8960 Jps
3153 NodeManager
2823 SecondaryNameNode
3017 ResourceManager
2570 DataNode
2428 NameNode
Hadoop を初めて使用する場合は、Hadoop のデータを削除してから hdfs namenode -format で初期化する必要があります。
この実験では、事前にインストールされた Hive を初期化済みのデータベースで初期化しています。自分でダウンロードした Hive を初期化する場合は、次のコマンドを実行してください。
/opt/hive-2.3.3/bin/schematool -initSchema -dbType mysql
Initialization script completed
schemaTool completed
ここで、ダウンロードした Hive を初めて初期化する場合は、~/.bashrc の HIVE_HOME をインストールした Hive のパスに変更し、source コマンドを実行して設定を反映する必要があります。ただし、Hive に関する以降のテストは事前にインストールされた Hive を使うため、変更しないことをおすすめします。
初期化が完了したことを示すメッセージが表示されたら、hive コマンドで Hive のコマンドラインに入ります。ターミナルで次のコマンドを実行してください。
hive
ヒント:事前にインストールされた Hive のシェルで hive と入力すると、事前インストール済みの Hive が起動します。今設定した Hive のシェルを起動するには、絶対パスを指定してください。
Hive Session ID = 3eee2693-175d-4452-82d2-47f1b639d9d5
Logging initialized using configuration in jar:file:/usr/local/hive/lib/hive-common-3.1.3.jar!/hive-log4j2.properties Async: true
Hive-on-MR is deprecated in Hive 2 and may not be available in the future versions. Consider using a different execution engine (i.e. spark, tez) or using Hive 1.X releases.
Hive Session ID = 68d0d345-92c3-4eb1-8393-7ee34f56363f
hive>
Hive の基本操作
このステップでは、Hive テーブルの基本操作を学びます。Hive の各種文は、Language Manualでも確認できます。
テーブルの作成
まず、データを用意します。この実験で使用するデータは、NginX サーバーのログを模したファイルです。Web サイトのページビューを分析するために使用します。
ターミナルをもう一度開き、次のコマンドを実行してサンプルデータをダウンロードします。
su hadoop
cd ~
wget http://labfile.oss-cn-hangzhou.aliyuncs.com/courses/567/log_example.csv
次に、ファイルを HDFS にアップロードします。
hdfs dfs -mkdir -p /user/data/staging/page_view
hdfs dfs -put /home/hadoop/log_example.csv /user/data/staging/page_view
データを用意したら、まずテーブルを作成します。上記のデータ用に page_view テーブルを作成するには、Hive のコマンドラインで次の文を実行します。
CREATE TABLE page_view(viewTime INT, userid BIGINT,
Page_url STRING, referrer_url STRING,
Ip STRING COMMENT 'IP Address of the User')
COMMENT 'This is the page view table'
PARTITIONED BY(dt STRING, country STRING)
STORED AS SEQUENCEFILE;
この例では、各列に適切な型を指定しています。列とテーブルの両方にコメントを付けることもできます。また、PARTITIONED BY 句では、データ列とは別のパーティション列を定義します。パーティション列はデータ列と一緒には保存されません。このようにパーティション列を指定した場合、各行の区切り文字には改行文字が使われます。
データが上記の形式と異なる場合は、次の例のようにフィールド区切り文字を指定できます。
次の文は説明用です。hive シェルでは実行しないでください。
CREATE TABLE page_view1(viewTime INT, userid BIGINT,
Page_url STRING, referrer_url STRING,
Ip STRING COMMENT 'IP Address of the User')
COMMENT 'This is the page view table'
PARTITIONED BY(dt STRING, country STRING)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '1'
STORED AS SEQUENCEFILE;
行の区切り文字は Hive ではなく Hadoop システム側で決まるため、手動で変更することはできません。
通常、列データで構成されたテーブルはバケットに格納します。これにより、データセットのクエリで効率よくサンプリングできます。バケットを使わない場合、テーブルのランダムサンプリング自体はできますが、データ全体をスキャンする際に効率よくサンプリングできません。次の例では、userid 列を使って page_view テーブルのバケットストレージを有効にします。
次の文は説明用です。hive シェルでは実行しないでください。
CREATE TABLE page_view2(viewTime INT, userid BIGINT,
Page_url STRING, referrer_url STRING,
Ip STRING COMMENT 'IP Address of the User')
COMMENT 'This is the page view table'
PARTITIONED BY(dt STRING, country STRING)
CLUSTERED BY(userid) SORTED BY(viewTime) INTO 32 BUCKETS
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '1'
COLLECTION ITEMS TERMINATED BY '2'
MAP KEYS TERMINATED BY '3'
STORED AS SEQUENCEFILE;
この例では、テーブルの userid 列の値をハッシュ関数で 32 個のバケットに分けます。各バケット内のデータは、viewTime の昇順で並べ替えられます。この方法でデータを整理すると、集約対象の列(ここでは userid 列)を効率よくサンプリングできます。また、データをソートしておくと、データ管理者がより適切なデータ構造を使ってクエリを効率的に評価できます。
次の文は説明用です。hive シェルでは実行しないでください。
CREATE TABLE page_view3(viewTime INT, userid BIGINT,
Page_url STRING, referrer_url STRING,
Friends ARRAY<BIGINT>, properties MAP<STRING, STRING>,
Ip STRING COMMENT 'IP Address of the User')
COMMENT 'This is the page view table'
PARTITIONED BY(dt STRING, country STRING)
CLUSTERED BY(userid) SORTED BY(viewTime) INTO 32 BUCKETS
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '1'
COLLECTION ITEMS TERMINATED BY '2'
MAP KEYS TERMINATED BY '3'
STORED AS SEQUENCEFILE;
この例では、テーブルの各行の形式を列名と型で定義しています。他のプログラミング言語での型定義とよく似ています。テーブル名と列名では大文字と小文字が区別されません。IP Address of the User と下の COMMENT 文から、列とテーブルの両方にコメントを追加できることがわかります。また、前述のとおり、PARTITIONED BY 句で定義するパーティション列はデータ列とは異なり、実際にはデータを保存しません。CLUSTERED BY 句では、バケット分割に使用する列とバケット数を指定します。ROW FORMAT DELIMITED 句では、Hive テーブルの行の保存方法を指定します。区切り形式の場合、この文でフィールドの区切り文字、コレクション(array または map)内の要素の区切り文字、map のキーの区切り文字を指定します。ここで指定する数値は ASCII コードです。STORED AS SEQUENCEFILE は、HDFS 上にデータをバイナリー形式(具体的には Hadoop の SequenceFile 型)で保存することを示します。なお、ROW FORMAT 句と STORED AS 句の設定には、現在 Hive が使用しているデフォルト値が使われます。そのため、最初にテーブルを作成した文では明示的に指定していません。
テーブルとパーティションの確認
データベース内の既存テーブルを一覧表示するには、次の文を実行します。
SHOW TABLES;
テーブル数が多いと、上記の文は大量の結果を返します。プレフィックスを指定すると、対象を絞り込めます。たとえば、page で始まるテーブルを一覧表示するには、次の文を実行します。
SHOW TABLES 'page.*';
この文では正規表現と同じルールが使われ、ピリオド(.)はワイルドカードを表します。
テーブルのパーティションを一覧表示するには、次の文を実行します。パーティション分割されていないテーブルの場合、結果は返されません。
SHOW PARTITIONS page_view;
テーブルの列と各列の型を確認するには、DESCRIBE 文を使います。
DESCRIBE page_view;
列とその他すべてのプロパティを一覧表示するには、EXTENDED キーワードを追加します。多くの情報が出力されるため、通常はデバッグに使用します。
DESCRIBE EXTENDED page_view;
テーブルの変更
既存テーブルの名前を変更するには、ALTER TABLE 文と RENAME TO を使います。変更後の名前を持つテーブルがすでに存在する場合は、エラーが返されます。次の文は例示用です。この実験では実行しないでください。次のステップでも、作成した page_view テーブルを使用します。
ALTER TABLE page_view RENAME TO new_page_view;
実行結果は次のようになります。
hive> ALTER TABLE page_view RENAME TO new_page_view;
OK
Time taken: 0.124 seconds
hive> show tables;
OK
new_page_view
...
Time taken: 0.021 seconds, Fetched: 4 row(s)
既存テーブルの列名を変更することもできます。ただし、既存の各列に対応するレコードを含め、列の型を同じにする必要があります。
ALTER TABLE new_page_view REPLACE COLUMNS (viewTime INT, userid BIGINT, page_url STRING, referrer_url STRING, ipaddr STRING COMMENT 'IP Address of the User');
既存テーブルに新しい列を追加することもできます。
ALTER TABLE new_page_view ADD COLUMNS (new_column INT COMMENT 'a new int column');
列の追加などスキーマを変更しても、テーブルの古いパーティションのスキーマは保持されます。そのため、古いパーティションがパーティションテーブルではなくなることはありません。古いパーティションに対してこれらの列にアクセスするクエリを実行すると、列の値として暗黙的に null または指定されたデフォルト値が返されます。
テーブルとパーティションの削除
Hive はデータウェアハウス向けに設計されているため、データの破棄は常に避けるべき操作です。そのため、テーブルの削除には少し注意が必要です。テーブルに対して DROP コマンドを実行すると、そのテーブルに作成されたインデックスも暗黙的に削除されます。
次の例はテーブルを削除します。この実験では実行しないでください。
DROP TABLE new_page_view;
データのロードとクエリ
このステップでは、ステージングデータをパーティション分割された Hive テーブルにロードし、結果をクエリします。
データのロード
Hive テーブルにデータをロードする方法はいくつかあります。特定の HDFS 上の場所を参照する外部テーブルを作成できます。この方法では、HDFS の put コマンドまたは copy コマンドでデータファイルを指定した場所にコピーし、その場所を参照するテーブルを作成します。このテーブルには、行の形式に関する情報も設定します。
テーブルを作成した後、データを変換して別の Hive テーブルに挿入できます。ここでは、最初に log_example.csv ファイルを HDFS にアップロードし、ファイル名を page_view に変更しています。このデータを対応するパーティションの page_view テーブルにロードするには、次のコマンドを実行します。
まず、外部テーブルを作成し、指定したファイルに関連付けます。
CREATE EXTERNAL TABLE page_view_stg(viewTime INT, userid BIGINT,
Page_url STRING, referrer_url STRING,
Ip STRING COMMENT 'IP Address of the User',
Country STRING COMMENT 'country of origin')
COMMENT 'This is the staging page view table'
ROW FORMAT DELIMITED FIELDS TERMINATED BY '44' LINES TERMINATED BY '\n' STORED AS TEXTFILE
LOCATION '/user/data/staging/page_view';
次に、データの最終保存先となる page_view テーブルを作成します。
CREATE TABLE page_view(viewTime INT, userid BIGINT,
Page_url STRING, referrer_url STRING,
Ip STRING COMMENT 'IP Address of the User')
COMMENT 'This is the page view table'
PARTITIONED BY(dt STRING, country STRING)
STORED AS SEQUENCEFILE;
この小規模な練習用データセットでは、分散 YARN ジョブを実行する必要はありません。この実験環境の仮想マシン内で INSERT を安定して実行できるよう、今回の Hive セッションで Hadoop のローカルジョブランナーを設定します。
SET mapreduce.framework.name=local;
最後に、外部テーブルから page_view テーブルへデータを挿入します。
FROM page_view_stg pvs
INSERT OVERWRITE TABLE page_view
PARTITION(dt='2015-05-17', country='us')
SELECT pvs.viewTime, pvs.userid, pvs.page_url, pvs.referrer_url, pvs.ip
WHERE pvs.country = 'us';
ローカルジョブは数秒以内に完了し、一致する行が page_view のパーティションにロードされます。
...
Loading data to table default.page_view partition (dt=2015-05-17, country=us)
MapReduce Jobs Launched:
Stage-Stage-1: HDFS Read: ... HDFS Write: ... SUCCESS
Total MapReduce CPU Time Spent: 0 msec
OK
Time taken: ... seconds
簡単なクエリ
データを挿入したら、簡単なクエリを実行できます。一般的な SQL 文と同じように、Hive のコマンドラインインターフェースで次の文を実行してください。
SELECT * FROM page_view WHERE userid = 0 LIMIT 10;
次のように、クエリ結果としてレコードが表示されます。
hive> select * from page_view;
OK
NULL 490 /downloads/product_1 /archives/webroot 217.168.17.5 2015-05-17 us
NULL 490 /downloads/product_2 /archives/webroot 217.168.17.5 2015-05-17 us
NULL 3316 /downloads/product_2 /archives/webroot 217.168.17.5 2015-05-17 us
...
サービスの停止
このステップでは、Hive を終了して Hadoop サービスを停止します。さらに学習する場合は、次の資料を参照してください。
Hive の使用を終えたら、quit コマンドで Hive のコマンドラインインターフェースを終了します。
quit;
HDFS サービスも忘れずに停止してください。ターミナルで次のコマンドを実行します。
stop-yarn.sh
stop-dfs.sh
まとめ
この実験では、Hive のアーキテクチャ、インストールとデプロイ、基本的な HQL 文を学びました。また、サンプルデータを使ったデータのインポートも行いました。
主な学習内容は次のとおりです。
- Hive のアーキテクチャ
- Hive の基本データ単位
- Hive のデプロイ方法
- Hive の HQL 言語
Hive はデータウェアハウス用のソフトウェアパッケージであり、その機能を活用するには、さらに学習を続ける必要があります。技術資料を積極的に確認する習慣を身につけ、次のコースでも学習を続けましょう。



