Amazon Athena に JDBC 接続する

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

ども、藤本です。

本日、re:Invent 2016 の Keynote で多くの新サービス発表がありました。

今回は新サービスの一つである Amazon Athena が JDBC 接続に対応しているということで早速試してみました。

Amazon Athena

Amazon Athena については既に弊社ブログのエントリで紹介されていますので、ご参照ください。

試してみた

それでは早速試してみました。

JDBCによる操作は下記ドキュメントに記載されています。

Accessing Amazon Athena with JDBC

今回利用するデータは Amazon Athena にデフォルトで用意されているデータベース「sampledb」のテーブル「elb_logs」を利用します。レスポンスステータスコード毎のデータ件数を抽出します。

JDBCドライバ

Amazon Athena 用の JDBC ドライバは S3 で公開されています。下記、URLよりダウンロードできます。

https://s3.amazonaws.com/athena-downloads/drivers/AthenaJDBC41-1.0.0.jar

JDBC URLフォーマット

下記フォーマットで接続します。REGIONはリージョン名に置き換えてください。現在は Amazon Athena が利用可能なus-east-1us-west-2を利用できます。

jdbc:awsathena://athena.REGION.amazonaws.com:443

ドライバクラス名

ドライバクラス名は下記となります。

com.amazonaws.athena.jdbc.AthenaDriver

AWS SDK for Java

Amazon Athena への JDBC によるクエリはクレデンシャルを利用した認証となりますので、AWS SDK for Java が必要となります。

実装

ソースコードはほとんどドキュメントにあるサンプルコード通りです。

package athena;

import java.sql.*;
import java.util.Properties;


public class AthenaJdbc {

  static final String athenaUrl = "jdbc:awsathena://athena.us-east-1.amazonaws.com:443";

  public static void main(String[] args) {

      Connection conn = null;
      Statement statement = null;

      try {
          Class.forName("com.amazonaws.athena.jdbc.AthenaDriver");
          Properties info = new Properties();
          info.put("s3_staging_dir", "s3://athena-staging-backet/");
          info.put("log_path", "/tmp/athena.log");
          info.put("aws_credentials_provider_class","com.amazonaws.auth.profile.ProfileCredentialsProvider");

          System.out.println("Connecting to Athena...");
          conn = DriverManager.getConnection(athenaUrl, info);

          System.out.println("Listing tables...");
          String sql = "select elbresponsecode, count(*) as data_count from sampledb.elb_logs group by elbresponsecode";
          statement = conn.createStatement();
          ResultSet rs = statement.executeQuery(sql);

          while (rs.next()) {
              //Retrieve table column.
              String statusCode = rs.getString("elbresponsecode");
              int dataCount = rs.getInt("data_count");

              //Display values.
              System.out.println("Status code " + statusCode + " : " + dataCount);
          }
          rs.close();
          conn.close();
      } catch (Exception ex) {
          ex.printStackTrace();
      } finally {
          try {
              if (statement != null)
                  statement.close();
          } catch (Exception ex) {

          }
          try {
              if (conn != null)
                  conn.close();
          } catch (Exception ex) {
              ex.printStackTrace();
          }
      }
      System.out.printf("Finished connectivity test.");
  }
}

JDBC Option でs3_staging_dirの指定は必須となっています。s3_staging_dirは SQL の結果を保管する S3 のパスを指定します。バケット直下でもいいですし、フォルダーを切っても大丈夫です。ただし、指定する S3 バケットと、接続する Amazon Athena のリージョンが同じである必要があることはご注意ください。

上記、ソースコードを実行すると以下のような標準出力が返ってきます。

Connecting to Athena...
Listing tables...
Status code 304 : 60
Status code 302 : 13
Status code 500 : 22
Status code 301 : 23
Status code 404 : 3
Status code 200 : 4108
Finished connectivity test.

ステータスコードと、その件数が表示されました。

指定した S3 バケットにも csvファイル、およびメタデータファイルが作成されます。

# aws s3 ls s3://athena-staging-backet
2016-12-01 13:33:53         98 3031e41b-5cd8-424a-a675-8f66b469d7e2.csv
2016-12-01 13:33:53        140 3031e41b-5cd8-424a-a675-8f66b469d7e2.csv.metadata

# aws s3 cp s3://athena-staging-backet/3031e41b-5cd8-424a-a675-8f66b469d7e2.csv -
"elbresponsecode","data_count"
"304","60"
"302","13"
"500","22"
"301","23"
"404","3"
"200","4108"

SQL の結果が CSV形式で出力されています。

まとめ

いかがでしたでしょうか?

Athena を介して、簡単にプログラムから S3 オブジェクトのデータを取得することができました。JDBC に対応していますので様々なエコシステムと連携できそうですね。