Speee DEVELOPER BLOG

Speee開発陣による技術情報発信ブログです。 メディア開発・運用、スマートフォンアプリ開発、Webマーケティング、アドテクなどで培った技術ノウハウを発信していきます!

GoのAthena用database/sqlドライバーをOSSでリリースした話

この記事はGo3 Advent Calendar 2020の22日目です。

こんにちは、Speeeでサーバーサイドエンジニアをしている@muroon01です。SpeeeではUZOUという広告配信プラットフォームの開発をしています。 今回はGoでAthenaにアクセスするOSSを開発しましたのでそちらの話をさせていただきます。

github.com

こちらは元々別の方々が作成されたものですが、 2年近くメンテナンスされてないようなので改修することにいたしました。

go-athena

go-athenaはdatabase/sqlパッケージのAthenaのdriverです。下記のように(初期化)importをして使用します。

import (
    "database/sql"
    _ "github.com/speee/go-athena"
)

func main() {
  db, _ := sql.Open("athena", "db=default&output_location=s3://results")
  rows, _ := db.Query("SELECT url, code from cloudfront")

  for rows.Next() {
    var url string
    var code int
    rows.Scan(&url, &code)
  }
}

追加機能

もともと上がっていたIssueのいくつかを取り込むことなどを含め下記の機能を追加しました。

  • Docker環境追加
  • reviewdog
  • DDL実行時のResultHeaderの削除
  • workgroupの使用
  • testの修正(各packageを最新にあわせる)
  • クエリのResult取得モードを新たに設ける

クエリのResultモードを設ける

アプリケーションからAthenaにクエリを投げてクエリの結果を取得するのに大きく2種類のAPIコールが必要です。

  • クエリの実行
  • クエリの実行した結果(SELECT文のRows)を取得

f:id:muroon:20201124212516j:plain
クエリの実行・結果取得の概要図

元々go-athenaGetQueryResults APIアクセスによりクエリ結果を取得してました。 GetQueryResult APIアクセスはクエリ結果を全件取得するためには取得レコード件数によっては複数回アクセスする場合もありました。 Athenaにはクエリ結果をファイルダウンロードする機能やCTASテーブルを作成・閲覧する機能があるのでそれらを使用してクエリの実行結果を取得するためにResultモードを設けました。

  • APIモード(default)
  • DLモード
  • GZIP DLモード

ただし、DLモード、GZIP DLモードはSelect文でのみ使用可能です

APIモード

結果取得にGetQueryResults APIにアクセスして結果を取得します。 このAPIアクセスはクエリ結果をAPIで返す場合はレスポンスで返せる件数に制限があります。クエリ結果が一定の件数(手動指定の場合は最大1000件)を超える場合は複数回のAPIアクセスにて全クエリ結果を取得します。

f:id:muroon:20201124204413j:plain
APIモードのRows取得

DLモード

Athenaはクエリ結果の全件をcsvファイル保存しています。それをダウンロード取得することによりクエリ結果の件数に関係なく1APIアクセスで取得が可能です。ただしcsvファイルは無圧縮です。この方法はPyAthenaでも使用されています。

f:id:muroon:20201124204427j:plain
DLモードのRows取得

GZIP DLモード

DLモードのcsvファイルは無圧縮のファイルダウンロードでした。 CTASテーブルを使用することによりダウンロードファイルをgzipに圧縮することが可能です。

  • クエリによるCTASテーブル作成(gzip指定)
  • CTASテーブルデータのダウンロード・解凍
  • CTASテーブルを削除

f:id:muroon:20201124204502j:plain
GZIP DLモードのRows取得

各モードのレスポンス時間

クエリ実行から結果全件取得までかかった時間の比較です。

f:id:muroon:20201130011552p:plain
取得件数のおけるレスポンスタイム実績

下記の傾向が言えるかと思います。

  • 少量の件数ではDLモード、APIモードが有効
  • 大量の件数ではGZIP DLモードが非常に有効

最後に

もしfork元のRopositoryのメンテナンスが復活したら

管理者の方が望まれるようであれば、Speee版を取り込んでもらえたらと考えております。

go-athnaパッケージはdatabase/sqlパッケージにてAthenaを使用できる点がGoの開発者にとってとてもなじみやすいのでいいパッケージだと思います。

Speee版は溜まっていたIssueの解決だけでなく新規の機能もございますので、オリジナルを作られた方々にも是非気に入っていただければ思っております。