PHPからCloudera Impalaに繋いでみた
最近ビッグデータ()系のサーバに対してあれこれやってるんですが、ひょんなことから調べる必要が出てきたのでざっくりまとめてみました。
間違ってる所があれば、指摘をお願いします;-)
CDHとは
CDH(Cloudera's Distribution Including Apache Hadoop)は、Cloudera社から提供されているオープンソースなApache Hadoopディストリビューションの1つで、Apache HadoopやApache HBase、Apache Hive、Apache Pigなどのパッケージが含まれています。
とりあえず、CDHについては以下のページをざっと読むと良いかと。
今回テストでCDH 4.6を使いましたが、最近CDH5がリリースされたようです。
また、Cloudera社のサイトからVMイメージ(Cloudera QuickStart VM)もダウンロードできます。
Cloudera Impalaとは
Cloudera Impalaは、CDHと同様、Cloudera社から提供されているHiveの上位互換のSQLが利用できる分散クエリエンジンです。
Impalaについては以下のページをざっと読むと良いかと。
- Apache Impala supported by Cloudera Enterprise
- 機械学習 | 分析 | クラウド - Cloudera
- HadoopのSQL対応分散クエリエンジン「Cloudera Impala」。Clouderaがオープンソースで公開 - Publickey
- Cloudera Impalaのアーキテクチャ | Tech Blog
CDH 5からCDHに組み込まれるようになったようです。
ODBC経由でCloudera Impalaに接続する
Cloudera社からCloudera Impala用のODBCドライバがダウンロードできますが、それだけだとPHPから利用できないので、今回はドライバマネージャとしてiODBCを使い、Cloudera ODBC Driver 2.5 for Impalaで接続してみました。
- iODBC
- Connector Documentation(「Cloudera ODBC Driver for Impala」のリンクから)
1. iODBCのインストール
ダウンロード後、いつも通りのconfigure/make/make installでOKです。
$ wget http://downloads.sourceforge.net/project/iodbc/iodbc/3.52.9/libiodbc-3.52.9.tar.gz
$ sudo tar zxf libiodbc-3.52.9.tar.gz
$ cd libiodbc-3.52.9/
$ configure
$ make
$ sudo make install
$
2. Cloudera ODBC Driver 2.5 for Impalaのインストール
Cloudera ODBC Driver 2.5 for Impalaの方ですが、rpm形式で提供されているので、rpmコマンドでインストールします。cyrus-sasl系やopenssl系など依存関係にあるパッケージは別途yumなどでインストールしておいてください。
$ sudo rpm -ivh ClouderaImpalaODBC-2.5.13.1013-1.el6.x86_64.rpm $
また、ODBC接続に必要なiniファイルもrpmパッケージに含まれていますので、確認しておきます。
$ ls /opt/cloudera/impalaodbc/Setup/
cloudera.impalaodbc.ini odbc.ini odbcinst.ini
$
3. ODBCの設定
基本的な流れにはインストールガイド(pdf)にある通りです。
今回はテスト用ディレクトリを作ってそこにiniファイルを配置してみます。
$ mkdir test $ cd test/ $ cp /opt/cloudera/impalaodbc/Setup/*.ini . $
デフォルトだと、カレントディレクトリにある各iniファイルを読みに行かないので、環境変数を設定しておきます。iniファイルの検索順序の詳細については、インストールガイド(pdf)を参照してください(p.10の終わり頃から)。
$ export ODBCINI=`pwd`/odbc.ini # フルパスの必要あり $ export ODBCSYSINI=`pwd`/ $ export SIMBAINI=`pwd`/cloudera.impalaodbc.ini # フルパスの必要あり $
続いて、接続用のDSNを定義します。コピーしたodbc.iniにも定義されていますので、それを使っても良いと思います。最低限、
- HOST(Cloudera Impalaが稼働しているサーバのIPアドレスもしくはホスト名)
- PORT(ODBC接続の場合は21050)
- Driver(libclouderaimpalaodbc64.soへのフルパス)
を定義しておけばOKです。まあ、接続時に指定してもいいんですけどね。。。今回は以下の内容をodbc.iniの最後に追加しました。
[Impala] HOST=localhost PORT=21050 Driver=/opt/cloudera/impalaodbc/lib/64/libclouderaimpalaodbc64.so
4. LD_LIBRARY_PATHの設定
ドライバマネージャであるiODBCとODBCドライバであるCloudera ODBC Driver 2.5 for Impalaの各ライブラリへのパスをLD_LIBRARY_PATHに設定します。
$ export LD_LIBRARY_PATH=/usr/local/lib:/opt/cloudera/impalaodbc/lib/64/ $
5. PHPスクリプトを作成
基本的にはODBC関数を使ったコードであれば良いはずです。今回は次のようなテーブル一覧を出力するスクリプト(test.php)を作ってみました。
<?php $connection = odbc_connect("DSN=Impala;", '', ''); $query = "show tables"; $rs = odbc_exec($connection, $query); while ($row = odbc_fetch_array($rs)) { echo (isset($row['name']) ? $row['name'] : null) . PHP_EOL; } odbc_free_result($rs); odbc_close($connection);
PDO ODBCの場合は次のような感じで。
<?php try { $dbh = new PDO('odbc:DSN=Impala;', '', ''); foreach($dbh->query('show tables') as $row) { echo (isset($row['name']) ? $row['name'] : null) . PHP_EOL; } $dbh = null; } catch (PDOException $e) { die($e->getMessage()); }
6. 実行してみる
PHPにodbc拡張が組み込まれていることを確認して実行します。今回はconfigure時に
--with-iodbc=shared --with-pdo-odbc=shared,iODBC
を付けてbuildしたPHPを使いました。これで作成したテーブル一覧が表示されればOKです。
$ /path/to/php -ddate.timezone=Asia/Tokyo -dextension=/path/to/odbc.so test.php : $
PDO ODBCの場合。
$ /path/to/php -ddate.timezone=Asia/Tokyo -dextension=/path/to/pdo.so -dextension=/path/to/pdo_odbc.so test.php : $
あとは、SELECT文をいろいろ試してみましょう:-)
ThriftでCloudera Impalaに接続する
先日のHBaseへの接続の際にも使用したThriftですが、Cloudera Impalaにも接続できます。ポート番号は21000です。
GitHubにいくつかライブラリが公開されているようなので、今回は次の2種類を試してみました。
- GitHub - rmcfrazier/php_impala_phar: PHP Impala client... can't let the Java and the Ruby guys have all of the fun !!!
- https://github.com/RJMetrics/php-impala/
a. PHP+php_impala_pharでCloudera Impalaに接続する
まずは、コード一式をダウンロードして展開します。
$ wget https://github.com/rmcfrazier/php_impala_phar/archive/master.zip -O php_impara_phar-master.zip $ unzip php_impara_phar-master.zip $ cd php_impara_phar-master/ $
直下にtest.phpがありますので、ホスト名の部分('<impala_host>')を適宜修正して実行します。以下の様な内容が出力されればOKです。
$ perl -i -p -s -e "s/<impala_host>/localhost/g" test.php $ /path/to/php -ddate.timezone=Asia/Tokyo test.php object(Results)#10 (5) { ["ready"]=> bool(true) ["columns"]=> array(1) { [0]=> string(6) "string" } ["data"]=> : } ["start_row"]=> int(0) ["has_more"]=> bool(false) } $
b. PHP+php-impalaでCloudera Impalaに接続する
php_impara_pharと同様、コード一式をダウンロードして展開します。
$ cd ../ $ wget https://github.com/RJMetrics/php-impala/archive/master.zip -O php-impala-master.zip $ unzip php-impala-master.zip $ cd php-impala-master/ $
やはり直下にtest.phpがありますので、ホスト名の部分(127.0.0.1)とポート番号(50000)を適宜修正して実行します。同様に、以下の様な内容が出力されればOKです。なお、返されるオブジェクトの名前空間が、php_impara_pharとは異なることに注意です。
$ perl -i -p -s -e "s/50000/21000/g" test.php $ /path/to/php -ddate.timezone=Asia/Tokyo test.php object(Beeswax\Results)#10 (5) { ["ready"]=> bool(true) ["columns"]=> array(1) { [0]=> string(6) "string" } ["data"]=> : } ["start_row"]=> int(0) ["has_more"]=> bool(false) } $
thriftファイルからPHPコードを出力したい
php-impalaにはthriftファイルが含まれています(zipファイルを展開した直下にthriftディレクトリ)ので、Thriftに食わせてPHPコードを生成することができます。手順はhttp://d.hatena.ne.jp/shimooka/20130828/1377686595にもありますが、以下の様な感じになります。
$ for fn in php-impala-master/thrift/*.thrift; do thrift --gen php $fn; done $
まとめ
またまた「繋げられましたよー」で終わっちゃいます。。。(汗)
Cloudera ImpalaはUPDATEやDELETEなどデータを更新する機能はないので使いどころが問題になってくると思いますが、HBaseと異なり、SQLっぽいクエリ(ほぼSQL)を投げられますのでHBaseよりは親近感がわきますね(笑)。また、100万件レベルの検索でもかなりパフォーマンスが良いです(サーバ構成等に依存するとは思いますが)。データがもうちょっと溜まってきた時(億単位以上)にどうなるかは見てみたいですね。
PHPからも意外と手軽に接続できますし、SQLを投げられる=ORM使ってモデルクラスやアクセスクラスなどの自動生成も可能じゃないかと思います。