2016/12/01に、Amazon S3上のデータにアドホックにSQLクエリを投げられるサービスであるAmazon Athenaがリリースされました。
Athenaの概要に関しては以下をどうぞ。
Amazon Athena – Amazon S3上のデータに対話的にSQLクエリを
Amazon Athenaを使ってみました #reinvent
Amazon AthenaをBigQueryと比較してみた
自分で軽く使ってみた感じだと、SaaSなので管理コストが低い上にクエリのパフォーマンスもかなり良く、非常に可能性を感じるサービスだという印象です。
というわけでAmazon Athenaをもっと使っていきたいので、OSSのBIツールであるre:dashからAmazon Athenaにクエリを投げられるようにしました。皆さんも良かったらやってみてください。
コメント欄にもありますが、re:dash作者の@arikfrさんが既に公式でのAthenaサポートを作成中だそうです!リリースされましたらそちらを使った方が楽ですね。
##環境
- Ubuntu14.04
- Python 2.7.6
##作業手順
###py4jのインストール
Athenaは現状ではJDBC経由の接続しかサポートしていないので、pythonから接続するには一手間いります。
今回はPythonからjarを実行するために、別プロセスで起動しているjavaとソケット通信経由で連携するpy4jを使う事にしました。pipでインストールできます。
$ sudo pip install py4j
###Java8のインストール
Athenaとの接続を行うためにはJava8以上が必須です。
$ sudo apt-add-repository ppa:openjdk-r/ppa
$ sudo apt-get update
$ sudo apt-get install openjdk-8-jdk
$ java -version
openjdk version "1.8.0_111"
OpenJDK Runtime Environment (build 1.8.0_111-8u111-b14-3~14.04.1-b14)
OpenJDK 64-Bit Server VM (build 25.111-b14, mixed mode)
また、自分はSSL関係でつまづき以下のコマンドも実行しました。
$ sudo dpkg --purge --force-depends ca-certificates-java
$ sudo apt-get install ca-certificates-java
$ sudo /var/lib/dpkg/info/ca-certificates-java.postinst configure
###Javaサーバプログラムの作成
Athenaとのコネクションを確立するためのJavaのサーバー用クラスを作成します。以下の記事を参考にさせていただきました。
CPythonからJavaのクラスを呼び出す(Py4J)
Accessing Amazon Athena with JDBC
public class J4Py {
public static void main(String[] args) {
J4Py app = new J4Py();
GatewayServer server = new GatewayServer(app);
server.start();
}
}
public class AthenaJDBCConnector {
Properties info;
String url;
public AthenaJDBCConnector(Properties info, String url) {
this.info = info;
this.url = url;
}
public Connection getConnection() {
try {
Class.forName("com.amazonaws.athena.jdbc.AthenaDriver");
Connection conn = DriverManager.getConnection(this.url, this.info);
return conn;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
}
###Jarファイル作成
先ほどのプログラムからJarファイルを作成します。
AthenaJDBC41-1.0.0.jar
は公式からダウンロードできます。
$ javac -cp AthenaJDBC41-1.0.0.jar AthenaJDBCConnector.java
$ jar cvf AthenaJDBCConnector.jar AthenaJDBCConnector.class
py4j0.10.4.jar
はpy4jインストール時に付いてきます。
Main-Class: J4Py
Class-Path: py4j0.10.4.jar AthenaJDBC41-1.0.0.jar
$ javac -cp py4j0.10.4.jar:AthenaJDBCConnector.jar:AthenaJDBC41-1.0.0.jar J4Py.java
$ jar cvfm J4Py.jar manifest.mf J4Py.class
J4Py.jar
の作成が終了しました。サブプロセスでJ4Py.jar
を立ち上げれば以下のようにしてpythonからAthenaのクエリが投げられます。
$ java -jar J4Py.jar
from py4j.java_gateway import JavaGateway
gateway = JavaGateway()
info = gateway.jvm.java.util.Properties()
info.setProperty("s3_staging_dir", 'xxx')
info.setProperty("user", 'yyy')
info.setProperty("password", 'zzz')
host = 'jdbc:awsathena://athena.us-west-2.amazonaws.com:443/'
connector = gateway.jvm.AthenaJDBCConnector(info, host)
conn = connector.getConnection()
statement = conn.createStatement()
rs = statement.executeQuery(query)
###re:dashへのデータソース追加
re:dashはデータソースをプラガブルに追加可能です。先ほどのpythonファイルの要領でBaseQueryRunnerを継承したクラスを作成します。少し長くなったので外部に置きます。
作成したクラスをquery_runner/直下に追加し、以下のように/opt/redash/.env
に追記してre:dashを再起動すればOKです。事前にJ4Py.jar
プロセスを立ち上げるのを忘れないようにしてください。(re:dashはsupervisordで管理されているので、そこに相乗りさせると良いかもしれません)
export REDASH_ADDITIONAL_QUERY_RUNNERS=redash.query_runner.athena
###クエリ実行
データソースを追加したら画面上から設定が行えるようになりますので、必要な項目を入力してクエリを投げてみます。
無事にクエリが投げられました!
##終わり
re:dashとAthenaを使えば低コストで簡単にデータの可視化が行えますので、是非試してみてください!
今回のソースは
https://github.com/kakakazuma/redash/tree/feature/athena
にコミットしてあります。
Athenaの需要はあると思うのでプルリクを出したいのですが、Java8が必須だったり別プロセスでJavaを走らせる必要があったりと少し複雑になってしまうので、フォーラムで相談してみます。
公式で既に作成中のようなので、問題なさそうです!