自作のDB負荷テストツール qube を Zstandard Seekable Format に対応させた。
Zstandard Seekable Format is 何?
名前の通りシーク可能なZstandardのフォーマット。 ファイル末尾にシークテーブルをつけて解凍しなくても任意のオフセットからデコードしたデータを読み取れる。 シークテーブルは通常のzstdでは単純に無視されるので、zstdコマンドでも解凍可能。
こちらの記事が詳しい。
GoとRustの実装にはCLIもある。
Goのサンプルコードは以下の通り。
seekable-zstd-sample.go
qubeで何がうれしい?
qubeはクエリログをテストデータとしてDBの負荷テストを行うために開発したツールだが、テストデータは5〜10GBと大きくなりがちで取り回しが非常に悪い。(テストサーバへの転送に時間がかかる、jqでテストデータをフィルタリングしているとディスクが埋まる…etc)
なので圧縮ファイルを使えると便利なのだが、シーク可能である必要があったので、gzipやbz2が使えなかった。
なぜシークが必要かというと、データをメモリ上でシャッフルする代わりにランダムな行からデータの読み込みを行う機能をつけているので、ファイルの任意のオフセットにシークできる必要があった。
あと、ループ終了時の巻き戻しに io.Seeker など os.File と共通のインターフェースを使えた方がうれしい(seekable zstd では io.ReadSeekCloser でtxtファイルとzstファイルを抽象化できたので、だいぶ実装が楽になった)
テストデータをzstdseekで圧縮すると1/10になったが、qubeの使い勝手は変わらない。便利。 (クライアント側のCPU消費は増えると思う)
$ go install github.com/SaveTheRbtz/zstd-seekable-format-go/cmd/zstdseek@latest $ zstdseek -f data.jsonl -o data.jsonl.zst $ ls -lh data.jsonl* -rw-r--r--@ 1 sugawara staff 235M 7 13 09:28 data.jsonl -rw-r--r--@ 1 sugawara staff 23M 7 13 09:36 data.jsonl.zst $ qube -d 'root@tcp(127.0.0.1:13306)/employees' -f data.jsonl.zst -n 5 -t 10s --random 00:05 | 5 agents / exec 89821 queries, 0 errors (22555 qps) ... { "Options": { "DataFiles": [ "salaries.jsonl.zst"
結構便利なフォーマットなので今後も使う機会がありそう。