Slide 1

Slide 1 text

gobpfでPostgreSQLを動的トレーシングする Jun Uchino @ Sansan, Inc.

Slide 2

Slide 2 text

自己紹介 • Twitter: @u3jun, Github: @ujun • インフラエンジニア @Sansan株式会社 • 法人向け名刺管理サービス Sansan • 普段はPython(2多め 好きなモジュールはclickやconcurrent.futures) • Goは書いてない • PostgreSQL9.6 on AWS EC2 の運用 • さまざまな理由からマネージドDBに移行できない • 業務外だと最近は複雑ネットワーク推し

Slide 3

Slide 3 text

BPFとは • Linux 4.* から 導入された (RHELはで8から) • 特定のカーネル内のイベントにフックして任意の処理を簡単に書けます • 各種MW等で定義されたトレーシング用のエントリポイント(USDT)にフックしていろいろ できる(Dtrace SystemTapと同じ様) • Nginx • Python • MySQL • PythonやLuaやGoなど各種言語でBPFを容易に扱えるフレームワークが開発されてお りそれを使う

Slide 4

Slide 4 text

PostgtrSQLが動的トレース用に定義したエントリポイントにフッ クしてGoのコードを実行することができる BPF Map BPF Program PostgreSQL Events BPF Hook smgr-md-read-done transaction-start query-plan-start userland kernel Go Frontend ① ② ③ ④ ① 動的トレースポイントにアタッチしてイベン トを捕捉したいBPFプログラムを書く(大抵C) ② 捕捉したい対象のエントリポイント(プロー ブ)に①をアタッチする ③ BPFプログラムが受け取りたいメトリクスを ユーザランドに持ってくる ④ 採取したデータを用いて任意の処理をす る

Slide 5

Slide 5 text

現時点でのgobpfでPostgreSQLのUSDTを触る(面倒) BPF Map BPF Program Go Frontend query_blk_read.go --- // cgoでごりごり書く必要がある /* #cgo CFLAGS: -I/usr/include/bcc/compat #cgo LDFLAGS: -lbcc #include #include */ import "C" // インラインでCのBPF Program(query_blk_read)を書く int query_blk_read(struct pt_regs *ctx) {…} ・・・ // BPF Programの結果を受け取る structを書く type readlineEvent struct {…} ・・・ // プローブ(smgr__md__read__done)にたいしてフックする関数(query_blk_read)をアタッチする context := C.bcc_usdt_new_frompid(C.int(2228), nil) C.bcc_usdt_enable_probe(context, C.CString("smgr__md__read__done"), C.CString("query_blk_read")) usdt_text := C.bcc_usdt_genargs(&context, 1) m := C.bpf_module_create_c_from_string(usdt_text, C.uint(0), nil, C.int(0), C.bool(false) ① ② ③

Slide 6

Slide 6 text

gobpfの今の課題(主観)とまとめ • カーネルイベントの捕捉は簡単にできる • まだUSDTへアクセスするAPIがサポートされていない • Python, Luaではサポート済み • できるようになればプロファイリングツールをガンガン書いてこれらのプロファイリングが 捗り、トラブルシュートがスムーズになるはず • 今後なんとかしていきたいところ • (私はgobpfのコントリビュータでもなんでもないですが) 改善しましょう