Apache Drill?
Apache Drillとは、さまざまなデータソースに対してクエリを実行できるソフトウェアです。
Apache Drill - Schema-free SQL for Hadoop, NoSQL and Cloud Storage
GoogleのDremelにインスパイアされて、開発されたということらしいです。
Dremel: Interactive Analysis of Web-Scale Datasets – Google AI
どういうデータソースにアクセスできるかというと、
Connect a Data Source Introduction - Apache Drill
と、いったように、以下のようなデータソースが対象です。
- ファイルシステム(ローカル/HDFS)
- HBase
- Hive
- RDBMS
- MongoDB
- Amazon S3
- Apache Kafka
- Apache Kudu
- OpenTSDB
- Azure Blob(JAR追加)
また、ファイルを読む場合、対応するファイルフォーマットとしてはこちら。
Data Sources and File Formats Introduction - Apache Drill
今回、このApache Drillを使って、ローカルファイルシステム上にあるCSVファイルに対してクエリを実行してみましょう。
環境
今回の環境は、こちら。
$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 18.04.3 LTS Release: 18.04 Codename: bionic $ java -version openjdk version "1.8.0_222" OpenJDK Runtime Environment (build 1.8.0_222-8u222-b10-1ubuntu1~18.04.1-b10) OpenJDK 64-Bit Server VM (build 25.222-b10, mixed mode)
Apache Drillの実行には、Oracle JDK 8またはOpenJDK 8が必要です。
以下を読み進めながら、インストール。
Apache Drillには2つの実行モードがあり、スタンドアロンで動かすのをEmbedded Mode、分散環境上で動作させるのを
Distributed Modeと呼びます。
今回は、スタンドアロンで動かすのでEmbedded Modeでインストールします。
Install Drill Introduction - Apache Drill
Embedded Mode Prerequisites - Apache Drill
Installing Drill on Linux and Mac OS X - Apache Drill
といっても、tar.gzファイルをダウンロードして解凍すればおしまいです。
$ wget https://www-us.apache.org/dist/drill/drill-1.16.0/apache-drill-1.16.0.tar.gz $ tar xf apache-drill-1.16.0.tar.gz $ cd apache-drill-1.16.0
起動。
Starting Drill on Linux and Mac OS X - Apache Drill
$ bin/drill-embedded Apache Drill 1.16.0 "Think different, think Drill." apache drill>
そのまま、インタラクティブシェルが起動し、クエリを実行することができます。
また、この時にWeb UIも起動しています。
Starting the Web UI - Apache Drill
「http://localhost:8047/」にアクセスしてみると、Web UIへアクセスできます。今回は、このWeb UIを中心に使っていきましょう。
CSVファイルにクエリを投げてみる
プレーンテキストにクエリを投げるためのドキュメントは、こちら。
Querying Plain Text Files - Apache Drill
CSVに対してクエリを実行するサンプルがあるので、実行してみましょう。こんなファイルを用意。
plays.csv
1599,As You Like It 1601,Twelfth Night 1594,Comedy of Errors 1595,Romeo and Juliet 1596,The Merchant of Venice 1610,The Tempest 1599,Hamlet
「Query」を選んで、以下のクエリを実行してみます。
select * from dfs.`/path/to/plays.csv`
結果は、こんな感じ。
「Query Profile」を押すと、クエリの実行計画を見たり、クエリを修正して再度実行させたりできます。
ただ、「Query Profile」を押すと、別タブが開くんですよね…。それにクエリを間違ったりすると修正できなくなったりするので、
UIとしてはもうちょっと良いものが欲しいかもですね。
同じクエリを、シェルで実行した場合はこうなります。
apache drill> select * from dfs.`/path/to/plays.csv`; +-----------------------------------+ | columns | +-----------------------------------+ | ["1599","As You Like It"] | | ["1601","Twelfth Night"] | | ["1594","Comedy of Errors"] | | ["1595","Romeo and Juliet"] | | ["1596","The Merchant of Venice"] | | ["1610","The Tempest"] | | ["1599","Hamlet"] | +-----------------------------------+ 7 rows selected (0.112 seconds)
ところで、クエリを実行した時にファイルパスの前に書いていた
select * from dfs.`/path/to/plays.csv`
この「dfs」というのはなんでしょう。
Web UIから、「Storage」というものを選んでみます。
ここに載っている「dfs」というやつですね。
これは、File System Storageです。
File System Storage Plugin - Apache Drill
設定を見ると、ローカルファイルシステムを対象にしています。from句に書いたファイルパスは、「workspace」と呼ばれるものからの
相対パスで指定するようです。今回は「/」がワークスペースに入っていますが。
{ "type": "file", "connection": "file:///", "config": null, "workspaces": { "tmp": { "location": "/tmp", "writable": true, "defaultInputFormat": null, "allowAccessOutsideWorkspace": false }, "root": { "location": "/", "writable": false, "defaultInputFormat": null, "allowAccessOutsideWorkspace": false } },
ここで、File System Storageの設定を変えてみることを考えてみます。
例えば、先ほどのクエリの実行結果は、列が「columns」というようにまとめられていましたが、以下のように「as」を使うことで
列に別名を与えることができます。まあ、通常のSQLの話ですね。
select columns[0] as c1, columns[1] as c2 from dfs.`/path/to/plays.csv`
これで、列に別名を与えて実行できます。
このようにクエリで列名を与えるのではなく、CSVファイルの中にヘッダーとして列名を書いていきたいと思います。
plays.csv
c1,c2 1599,As You Like It 1601,Twelfth Night 1594,Comedy of Errors 1595,Romeo and Juliet 1596,The Merchant of Venice 1610,The Tempest 1599,Hamlet
列名は、c1、c2としました。
このまま先ほどのクエリを実行すると、追加した列名は単なる値として扱われます。
ここで、CSVファイルにヘッダーがあることを指定します。これは、File System Storageプラグインの設定です。
"csv": { "type": "text", "extensions": [ "csv" ], "delimiter": ",", "extractHeader": true },
dfsファイルストレージの設定を、これで保存。
設定項目は、こちらに書かれています。
Text Files: CSV, TSV, PSV - Apache Drill
ところで、File System Storageプラグインの設定を見ると、拡張子「csvh」であればヘッダー行ありのCSVとして認識してくれるようです。
ケースによっては、こちらを使っても良いのかもしれません。
"csvh": { "type": "text", "extensions": [ "csvh" ], "extractHeader": true, "delimiter": "," },
Apache Drillでは、ファイルの拡張子とフォーマットが紐づくようですね。
クエリの実行結果。
ところで、デリミタなどの指定は可能なのですが、読み込むファイルのエンコーディングの指定はありません。
UTF-8でファイルが書かれていることが、前提になっているみたいですね。
2つのファイルをJOINしてみる
最後に、2つのCSVファイルをJOINしてみましょう。
以下のような2つのファイルを用意。
books.csv
isbn,title,price,category_id 978-4297100339,Docker/Kubernetes 実践コンテナ開発入門,3718,1 978-4798134888,詳解UNIXプログラミング 第3版,9130,2 978-4798053776,アプリケーションエンジニアのためのApache Spark入門,3740,3 978-4798152370,Apache Kafka 分散メッセージングシステムの構築と活用,3960,3 978-4774196077,Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識,3278,2
categories.csv
id,name 1,Docker 2,Linux 3,ビッグデータ
この2つのファイルを、JOINしてみます。
select book.isbn, book.title, book.price, category.name as category_name from dfs.`/path/to/books.csv` as book inner join dfs.`/path/to/categories.csv` as category on book.category_id = category.id order by book.price asc
結果。
OKそうです。
まとめ
今回は、Apache DrillをEmbedded Modeでインストールして、CSVファイルを読み、クエリを実行するところまでを試してみました。
他にもJSONファイルが読めたり、RDBMSやAmazon S3をデータソースにしたりといろいろできるのですが、それまたの機会に。