2020年 02月の投稿を表示しています

Google Cloud Spanner のスロークエリ(的なもの)を集める spanner-query-stats-collector を作った

こちらです。
sters/spanner-query-stats-collector: Google Cloud Spanner's query stats collector


Google Cloud Spanner には発行されたクエリがどれくらい CPU をつかったのか、どれだけのスキャンをしたかといった情報が記録されていくテーブルがあります。
Query statistics tables | Cloud Spanner | Google Cloud

このテーブルは GCP コンソール Spanner 上からでも参照できますし、実際に存在しているテーブルのようなので SELCT して取得することもできます MySQL でいうところのスローログをテーブルに書き出しているような状態です。
これを見ることによって CPU をよく使うクエリが出ていないか、スキャンが多すぎるのでインデックスの最適化ができるのではないか、などといった Spanner を利用することに関して改善していくことができるようになります。または、開発/検証環境として使える Spanner データベースがあれば、そこでの様子を定期的にウォッチすることで、本番に出す前のクエリの怪しさも一定見ることができる、かもしれません。
(本番の場合はレコード数や発行回数が異なりすぎて、参考にならないかもしれませんが。。)

と、いうところから、これを作りました。

cmd 以下の main では 1 分おきに 1 分間のクエリ統計テーブルを参照し JSON で標準出力へと書き出します Dockerfile として作ったものはそれの docker 化したものです。
Credential さえ入ればクエリが発行できるので、例えば GCP の各種コンピューティングリソース(GCE GKE CloudRun などなど)からの利用は容易にできるはずです Spanner を参照できる権限を付与したサービスアカウントがあれば使えると思います(手元の認証情報でしか試してないので。。)

LTSV なデータを SQL で探索する ltsvq を作った

sters/ltsvq: ltsvq is LTSV Queryer that written in Go

Labeled Tab-separated Values (LTSV) なアクセスログのデータをパースし、少しだけ複雑な条件で集計する必要があった。
ELKStackなんかで集計する仕組みを整えて構築するよりも、さくっとできるソリューションでよかった。
ぱっと調べても便利に使えそうなのはなさそうに見えたので、ぱっとひらめいたアイデアで行けるかどうか、おためし的に作った。

実装は GitHub - Songmu/go-ltsvGitHub - mattn/go-sqlite3: sqlite3 driver for go using database/sql がほぼすべて。
パースした結果を SQLite にオンメモリで入れて、リクエストされたクエリを実行し、取れたものを再び LTSV になおして出力する。
SQLite でできることはできるので、絞り込みも並び替えも、集計だってできる。

と、まあ作ること自体はすぐだったのだが GitHub - goreleaser/goreleaser: Deliver Go binaries as fast and easily as possible でリリースを作ろうとしたら数時間積んでいた。
色々調べた結果、必要なライブラリが詰まった Docker イメージを準備し、その上でスタティックリンクになるように ldflags を指定してビルドするのが正解らしい CGO も効いているはず、きいてないと mattn/go-sqlite3 が動かんのでは…?

このあたり cmd/go: build: add -static flag · Issue #26492 · golang/go

ストリーミングなデータの tail -f みたいなずっと流れてくるデータをパイプして使うようなものは、どうしたらいいのかわからなかったので諦めてしまった。また今度挑戦してみよう。