👼
RDBからBigQueryにデータを流したいのでGoでツールを作った

myuon

myuon

2023年12月10日

テーブルのデータを移行するツールとしてembulkを使っていたが、gallonというツールを新たに作った

この記事は matsuri technologies 株式会社 Advent Calendar 2023 の 10 日目の記事です。

# 動機

弊社では開発部が作っているデータを社内の人間が分析することがあります。 分析には BigQuery を基本的に使っているので、RDB や DynamoDB のテーブルのデータを BigQuery テーブルとして流す必要がありました。

現状はリアルタイム性などはそこまで考えず、1 日数回テーブルデータを読み込んで BigQuery に流すことを念頭においています。

# Embulk について

このような用途だと、Embulk というツールがあります。

Embulk は Java 製のツールで多くのプラグインが開発されています。 今までは基本的に Embulk を使っていたのですが、ログが JSON で出せないこと、0.11 移行がそれなりに大変そうなこと、JVM なのでどうしてもメモリ使用量が大きめなことなどが不満としてありました。

# Gallon について

上記のような問題があったため、Go で書いてみようと思い立ち、個人開発の一環として gallon というツールを作ってみました。 (大容量のデータを持ち運ぶと言う意味で、大きめの容積の単位である gallon という名前にしました)

Gallon は Go 製のツールで、Embulk と同様に MySQL や DynamoDB から BigQuery にデータを流せるようになっています。 yaml ファイルを書いて実行することで CLI ツールとして使えるほか、ライブラリとして go get してから実行する、ということもできます。

Go を使ったのはやはり goroutine があることによるものです。データの読み出しとデータの書き出しを concurrent に実行することで、大きなデータを扱うことができるようになっています。

# Gallon の設計について

コードを書いていて悩んだところとして、InputPlugin から OutputPlugin へのデータを受け渡す時にどういうデータ形式にするかというのがありました。結局、レコードを map[string]any の形にして channel 経由で受け渡しをするようにしました。

InputPlugin と OutputPlugin はこの形式のデータを serialize/deserialize する想定になっています。

一旦、プラグインは自力で書いているので一旦困っていないため、よしとしました。

# 実際に Gallon を利用してみた

実際に Gallon を実験的に利用してみました。 プロダクトでは扱うテーブルが 1 つではなく複数あるので、ソースコードの特定のディレクトリ以下にある yaml ファイルを全て集めてきて順に実行するといったコードを書いています。

また DB の接続情報なども yaml にハードコードしたくないため、Go の text/template 形式で書いておいて Go 側から正しい値に置き換える、というようなコードを書いています。

別件ですが、Gallon の mysql のプラグインで go-sql-driver を使っている関係で、DSN の形式がちょっと思っていたのと違ったりしたのも若干はまりどころでした。

それ以外は、JSON でログが出ることや、メモリ使用量が少ないこと、プラグインのバージョン管理などが必要ないことなどがあってかなり簡単に使えているので良いなと思っています。 特に JSON ログは何も設定をしなくても Datadog でログをパースできるようになり、ログレベルの設定なども不要になるので見やすくて良いです。

# まとめ

Go はこういった軽く使える便利ツールを作るのに向いている言語だなと再確認しました。 gallon の方もたまに手を入れていこうと思っています。