はじめに
こんにちは。データエンジニアリンググループでエンジニアをやっている@bandwagondagonです。
CETというプロジェクトで、分析をしたり機械学習活用のためのデータ基盤を開発したりしています。
業務の中で embulk を使ってETL()開発することがあり、その際にembulk-input-bigquery という plugin にPRを出すことが何度かありました。
そこで
- embulk-input-bigquery において以下のようなパフォーマンス面での問題点
- 上記のパフォーマンス問題を java 実装にすることで解決できるのではないかと思った
- せっかくなら、近年盛り上がりを見せている kotlin で plugin を書いてみたかった
という問題や想いが生まれたので、個人的に embulk-input-bigquery を kotlin で書き直してみることにしました。
本記事ではそこで得た知見として
- embulk の plugin を kotlin で書くための方法
- 実際に kotlin で実装した plugin embulk-input-bigquery-kotlin
を紹介しようと思います!
embulk とは?
embulk とは plugin 機構による柔軟なETL処理を実現している OSS の並列バルクデータローダーです。
plugin は
- input-plugin (入力のデータソース)
- filter-plugin (データ加工)
- output-plugin (データの出力先)
の3種類に分けられ、 jruby と java の好きな言語で書くことができます。
(もっと embulk について詳しく知りたいという方には@hiroysatoさんのFluentdのバッチ版Embulk(エンバルク)のまとめが、2015年のリリース当時の情報から直近の勉強会での発表情報まで非常に詳しく関連情報をまとめられているのでオススメです。)
embulk の plugin で kotlin で書くための方法
事前に必要なこと
STEP1 : java で plugin を書くための設定
embulk mkbundle
コマンドで生成される plugin のひな形は ruby で記述されているため、まず java で plugin を開発できる準備をします。
java で ビルドツールとして gradle を用いるのが一般的でしょうか。
embulk-input-jdbc の build.gradle などを参考にタスク定義を書くのも良さそうですが、ここでは
@kamatama41 さんの gradle-embulk-plugin を使用したいと思います。
- embulk-core の依存関係
- 新規plugin作成時のひな形生成からrubygemsへのpushなど、pluginの開発・公開に必要な様々なタスクの定義
などといったbuild.gradle
の設定をラップしてくれているため、以下のようにbuild.gradle
の設定を非常に簡潔にすることができます。
buildscript {
repositories {
mavenCentral()
maven { url 'http://kamatama41.github.com/maven-repository/repository' }
}
dependencies {
classpath "com.github.kamatama41:gradle-embulk-plugin:0.1.4"
}
}
apply plugin: "com.github.kamatama41.embulk"
repositories {
mavenCentral()
maven { url 'http://kamatama41.github.com/maven-repository/repository' }
}
embulk {
version = "0.8.39"
category = "input"
name = "embulk-input-bigquery-kotlin"
authors = ["Yuji Koyano"]
email = "yuji.koyano.800@gmail.com"
description = "embulk input plugin from bigquery written by kotlin."
licenses = ["MIT"]
homepage = "https://github.com/ykoyano/embulk-input-bigquery-kotlin"
}
また, gradle-embulk-plugin では java での plugin テンプレートを生成する newPluginというタスクをサポートしているため、これですぐに java で plugin の開発を始めることができます。
STEP2 : kotlin で plugin を書くための設定
前述の gradle-embulk-plugin を使用すれば kotlin の導入も非常に簡単に行うがことができます。
buildscript {
ext.kotlinVersion = '1.2.10' # 記事執筆時点で最新
repositories {
mavenCentral()
jcenter()
maven { url 'http://kamatama41.github.com/maven-repository/repository' }
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
classpath "com.github.kamatama41:gradle-embulk-plugin:0.1.4" # 記事執筆時点で最新
classpath "net.researchgate:gradle-release:2.6.0" # 記事執筆時点で最新
}
}
これだけで kotlin での embulk plugin の開発準備は完了しました。
参考記事
embulk-input-bigquery-kotlin
上記の build.gradle
設定を利用して、input ソースとして bigquery を扱う kotlin 実装の pluginembulk-input-bigquery-kotlin を作りました。
embulk-input-bigquery と比較してまだまだBQに関して設定できる項目や少なかったり、resume
・cleanup
タスクや一部のデータ型に対応していないなど未完成な部分はありますが、今後対応していく予定です。
jruby 実装と kotlin実装 の比較
Bigquery の public data を用いて embulk-input-bigquery と embulk-input-bigquery-kotlin の読み込みのパフォーマンスを比較してみました。
速度比較に使った task 設定の yaml は以下の通りです。
embulk-input-bigquery-kotlin
in:
type: bigquery
project: <PROJECT_NAME>
columns:
- {name: id, type: long}
- {name: author, type: string}
- {name: time, type: long}
- {name: text, type: string}
- {name: parent, type: long}
asynchronous_method: true
cache: false
standard_sql: true
sql: "SELECT id, author, time, text, parent FROM `bigquery-public-data.hacker_news.comments` LIMIT 10000"
out:
type: stdout
embulk-input-bigquery-kotlin
in:
type: bigquery-kotlin
columns:
- {name: id, type: INT64}
- {name: author, type: STRING}
- {name: time, type: INT64}
- {name: text, type: STRING}
- {name: parent, type: INT64}
sql: "SELECT id, author, time, text, parent FROM `bigquery-public-data.hacker_news.comments` LIMIT 10000"
out:
type: stdout
timeコマンドで計測した処理時間(秒)の結果
embulk-input-bigquery | embulk-input-bigquery-kotlin | |
---|---|---|
real[s] | 22.79 | 11.49 |
user[s] | 47.01 | 17.90 |
sys[s] | 1.39 | 0.80 |
実装を jruby から kotlin に変更するだけで、2倍近く処理時間に差が出ることが確認できました。
終わり
以上
- embulk の plugin を kotlin で書くための方法
- 実際に kotlin で実装した plugin embulk-input-bigquery-kotlin
の紹介でした。
embulk は jruby と java といった異なる言語での plugin 実装をサポートしているため、言語選択といった意味では、コントリビュートへの敷居 が低い OSS であると考えています。
また本記事で紹介したように kotlin での plugin 開発という選択肢も非常に面白いと思いますので、これ機会にぜひ皆さんも embulk の plugin 開発に参加してみて下さい!
また、もっとこう書いたらよいよ、などといったお話をコメントにてお待ちしております〜!