PXF(Pivotal eXtension Framework)とは
PXFはHAWQが管理していないHDFS上のファイルやHiveのテーブル、HBaseへのアクセスを提供するフレームワークです。
名前に"フレームワーク"と付くようにJavaのプログラムから使用することもできますが、PXFが提供するサービスを利用してHDFS上のファイルを外部テーブルとして参照することができます。
PXFをインストールする前に
HAWQと同様にPXFはAmbariを使えば簡単にインストールできます。
しかし、AmbariはCDHに対応しておらず1、手動でインストールする手順も用意されていません。
でも、HAWQがCDHで動くのですからPXFも動くはずです。
Pivotalが配布しているPivotal HDBに含まれるPXFとAmbari Pluginを確認しながら、インストールを進めましょう。
なお、ダウンロードにはPivotal Networkへの登録が必要です。
PXFのインストール
CDHのHadoopクラスタにHAWQがインストール済みである前提で話を進めます。2
Ambari経由でPXFをインストールする手順はInstall HAWQ and PXF with Ambariにありますが、残念ながら手動でインストールする手順はありません。
ダウンロードしたtarファイルを解凍して、PXFサービスとPXF Pluginをインストールします。
PXFサービスはvFabric tc Server上で動作するWebアプリで、WebHDFSのようなREST APIを提供します。
余談ですが、vFabric tc ServerはTomcatベースのアプリケーションサーバで、Spring界隈で使われているものです。
PXF PluginはHDFS/Hive/HBase用が用意されていて、それぞれへのアクセス手段を提供します。
PXF Hive/HBase Pluginは、依存関係でHive/HBaseのインストールが必要です。
ホスト名の一覧を用意して、全ノードにインストールします。
# mkdir /opt/servers
# vi /opt/servers/all_hosts
hawq-ma01 # マスタ
hawq-sl01 # スレーブ
hawq-sl02 # 〃
:
# tar xvf PADS-1.3.1.1-19631-rhel5_x86_64.tgz
# gpscp -f /opt/servers/all_hosts PADS-1.3.1.1/{pxf*.rpm,vfabric-tc-server-standard-2.9.7-RELEASE.noarch.rpm} =:~/
# gpssh -f /opt/servers/all_hosts -e "rpm -ivh {pxf*.rpm,vfabric-tc-server-standard-2.9.7-RELEASE.noarch.rpm}"
インストールができたか確認します。
# gpssh -f /opt/servers/all_hosts -e "ls -l /usr/lib/gphd"
publicstage
pxf -> pxf-2.5.1.1
pxf-2.5.1.1
:
PXFサービスの初期化
Hadoopのjarファイルを設定ファイルに追加します。
Pivotal HDのパスが設定されているので、CDHのパスに修正しましょう。
Avroのjarにバージョン番号が付いていたり、細かな罠があるので注意してください。
hadoop-mapreduce-client-common.jarはMRVersionのエラーを避けるために必要です。
なお、HiveのMetastoreにLocal Metastoreを使用している場合は、MetastoreのDBのJDBCドライバとdatanucleus-rdbms-*[0-9].jarを追加する必要があります。
# vi /etc/gphd/pxf/conf/pxf-env.sh
:
export LD_LIBRARY_PATH=/usr/lib/hadoop/lib/native:${LD_LIBRARY_PATH}
# vi /etc/gphd/pxf/conf/pxf-private.classpath
:
/etc/gphd/pxf/conf
/etc/hadoop/conf
/etc/hbase/conf
/etc/hive/conf
/usr/lib/hadoop/client/hadoop-hdfs.jar
/usr/lib/hadoop/client/hadoop-mapreduce-client-core.jar
/usr/lib/hadoop/hadoop-auth.jar
/usr/lib/hadoop/hadoop-common.jar
/usr/lib/hadoop/lib/asm-*[0-9].jar
/usr/lib/hadoop/lib/avro.jar # 注意(バージョン番号なし)
/usr/lib/hadoop/lib/commons-cli-*[0-9].jar
/usr/lib/hadoop/lib/commons-codec-*[0-9].jar
/usr/lib/hadoop/lib/commons-collections-*[0-9].jar
/usr/lib/hadoop/lib/commons-configuration-*[0-9].jar
/usr/lib/hadoop/lib/commons-io-*[0-9].jar
/usr/lib/hadoop/lib/commons-lang-*[0-9].jar
/usr/lib/hadoop/lib/commons-logging-*[0-9].jar
/usr/lib/hadoop/lib/guava-*[0-9].jar
/usr/lib/hadoop/lib/hadoop-lzo-*[0-9].jar
/usr/lib/hadoop/lib/jackson-core-asl-*[0-9].jar
/usr/lib/hadoop/lib/jackson-mapper-asl-*[0-9].jar
/usr/lib/hadoop/lib/jetty-*.jar
/usr/lib/hadoop/lib/jersey-core-*[0-9].jar
/usr/lib/hadoop/lib/jersey-server-*[0-9].jar
/usr/lib/hadoop/lib/log4j-*[0-9].jar
/usr/lib/hadoop/lib/protobuf-java-*[0-9].jar
/usr/lib/hadoop/lib/slf4j-api-*[0-9].jar
/usr/lib/hadoop/lib/htrace-core*[0-9]-incubating.jar # 注意("htrace-core-*"ではなく"htrace-core*"。"incubating"のサフィックスあり)
/usr/lib/hadoop/lib/snappy-java-*[0-9].jar
/usr/lib/hbase/hbase-client.jar
/usr/lib/hbase/hbase-common.jar
/usr/lib/hbase/hbase-protocol.jar
/usr/lib/hbase/lib/htrace-core-*[0-9]-incubating.jar # 注意("incubating"のサフィックスあり)
/usr/lib/hbase/lib/netty-*[0-9].Final.jar
/usr/lib/zookeeper/zookeeper.jar
/usr/lib/hive/lib/antlr-runtime-*[0-9].jar
/usr/lib/hive/lib/datanucleus-api-jdo-*[0-9].jar
/usr/lib/hive/lib/datanucleus-core-*[0-9].jar
/usr/lib/hive/lib/hive-exec.jar
/usr/lib/hive/lib/hive-metastore.jar
/usr/lib/hive/lib/jdo-api-*[0-9].jar
/usr/lib/hive/lib/libfb303-*[0-9].jar
/usr/lib/hadoop-mapreduce/hadoop-mapreduce-client-common.jar # 注意(MRVersionのエラーを回避するため)
/usr/lib/gphd/pxf/pxf-hbase-*[0-9].jar
/usr/lib/gphd/pxf/pxf-hdfs-*[0-9].jar
/usr/lib/gphd/pxf/pxf-hive-*[0-9].jar
# user defined resources:
/usr/lib/gphd/publicstage
マスタの設定をスレーブにコピーします。
# vi /opt/servers/slave_hosts
hawq-sl01 # スレーブ
hawq-sl02 # 〃
:
# gpscp -f /opt/servers/slave_hosts /etc/gphd/pxf/conf/pxf-private.classpath =:/etc/gphd/pxf/conf
PXFサービスの初期化
全ノードのPXFサービスを初期化します。
これにより/var/gphd/pxf
ディレクトリにPXFサービスの環境が作成されます。
# gpssh -f /opt/servers/all_hosts -e "service pxf-service init"
Creating instance 'pxf-service' ...
:
Instance created
Connector summary
Port: 51200 Type: Blocking IO Secure: false
# gpssh -f /opt/servers/all_hosts -e "ls -l /var/gphd/pxf/pxf-service/"
README.txt
bin
conf
lib
logs
temp
webapps
work
なお、初期化をやり直す場合は/var/gphd/pxf
ディレクトリを削除して、service pxf-service init
を再実行します。
PXFサービスの起動
全ノードでPXFサービスを起動します。
# gpssh -f /opt/servers/all_hosts -e "service pxf-service start"
:
Checking if PXF webapp is up and running...
PXF webapp is up
PXF HDFS Pluginの利用
HAWQで外部テーブルを作成して、HDFS上のファイルを参照します。
詳細はAccessing HDFS File Data with PXFが参考になります。
まずはCSVファイルを用意して、HDFSに配置します。
# su - gpadmin
$ vi /tmp/ext_t_user.csv
1 ajis_ka
2 adachij2002
3 takeuchikzm
$ hdfs dfs -mkdir /user/gpadmin/ext_t_user
$ hdfs dfs -put /tmp/ext_t_user.csv /user/gpadmin/ext_t_user
次にHAWQから外部テーブルとして参照します。
LOCATIONで指定しているProfile=HdfsTextSimple
は、FRAGMENTER/ACCESSOR/RESOLVERを組み合わせたシンタックスシュガーです。3
$ psql hawq_db
hawq_db=#
CREATE EXTERNAL TABLE ext_t_user
(
id INTEGER,
name TEXT
)
LOCATION ('pxf://hawq-ma01:8020/user/gpadmin/ext_t_user?Profile=HdfsTextSimple')
FORMAT 'TEXT' (DELIMITER = E'\t');
CREATE EXTERNAL TABLE
hawq_db=# SELECT * FROM ext_t_user ORDER BY id;
id | name
----+-------------
1 | ajis_ka
2 | adachij2002
3 | takeuchikzm
(3 rows)
動きました!
PXF Hive Pluginの利用
続けて、HAWQからHiveのテーブルを参照します。
PXF Hive Pluginを使うためには、全ノードにHiveのインストールとHiveクライアントの設定が必要です。
詳細はAccessing Hive Data with PXFが参考になります。
CSVファイルを用意して、Hiveのテーブルにロードします。
# vi /tmp/t_city.csv
1 tokyo
2 beijing
3 newyork
# sudo -u hive hive
hive> CREATE DATABASE test_db;
hive> USE test_db;
hive>
CREATE TABLE t_city (
id INT,
name STRING)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
LINES TERMINATED BY '\n';
hive> LOAD DATA LOCAL INPATH '/tmp/t_city.csv' OVERWRITE INTO TABLE t_city;
hive> exit;
次にHAWQから外部テーブルとして参照します。
HiveのDBを使用する場合は、LOCATIONに<DB名>.<テーブル名>
の形式で指定する必要があります。
# su - gpadmin
$ psql hawq_db
hawq_db=#
CREATE EXTERNAL TABLE ext_t_city
(
id INTEGER,
name TEXT
)
LOCATION ('pxf://hawq-ma01:8020/test_db.t_city?Profile=Hive')
FORMAT 'CUSTOM' (FORMATTER='pxfwritable_import');
CREATE EXTERNAL TABLE
hawq_db=# SELECT * FROM ext_t_city ORDER BY id;
id | name
----+---------
1 | tokyo
2 | beijing
3 | newyork
(3 rows)
動きました!
まとめ
HAWQ単体ではHDFSの特定のディレクトリに独自の階層構造でファイルが格納されるため、他のエコシステムとの連携に難がありました。
PXFを組み合わせることでHDFS上のファイルやHiveのテーブルが利用できるようになります。
実はPXFを使用するとパフォーマンスに難があるのですが...それはまた別の機会に。
PostgreSQL互換のSQLで分析を楽しみましょう!