闇のBashをGoに置き換える技術 / golang.tokyo #11
by
nashiox
Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
闇のBashをGoに 置き換える技術 @nashiox 2017/12/11 golang.tokyo #11
Slide 2
Slide 2 text
@nashiox 水野 拓 (Taku MIZUNO) - インフラエンジニア@リブセンス - オンプレ/クラウドのサーバ構築・運用 - Go歴 - 約3年 - 最近のGo実装 - Mackerel プラグイン - Packer プラグイン
Slide 3
Slide 3 text
身の回りにこんなスクリプト ありませんか?
Slide 4
Slide 4 text
怖くて触れないけどなぜか 動いているBashスクリプト
Slide 5
Slide 5 text
インフラ運用に携わるとよく見かけます - 運用で利用するシェルスクリプト - 長い間メンテナンスされてない - メンテナーがいるかすらわからない - 読み解ける人がいない - 怖くて触れないけどなぜか動いている - Ex - サーバ構築スクリプト - 便利CLI - バッチスクリプト
Slide 6
Slide 6 text
リブセンスにもありました
Slide 7
Slide 7 text
10年を超える運用で積み重なった闇 - なにがどこで行われてるかわからない - けれどなぜか動いてる - それを実行しないと仕事にならない - どこを直せば良いのかすらわからない - 作成者はすでにいない - etc…
Slide 8
Slide 8 text
10年を超える運用で積み重なった闇 - なにがどこで行われてるかわからない - けれどなぜか動いてる - それを実行しないと仕事にならない - どこを直せば良いのかすらわからない - 作成者はすでにいない - etc… 闇を感じていただけたでしょうか?
Slide 9
Slide 9 text
気合を入れて直しています
Slide 10
Slide 10 text
リブセンスの場合 - 積み重なった闇のBash群 - サーバ構築スクリプト - Bash -> Chef -> Ansible と変遷 - 便利CLI - PythonやGoに置き換え - バッチスクリプト - Goに置き換え
Slide 11
Slide 11 text
リブセンスの場合 - 積み重なった闇のBash群 - サーバ構築スクリプト - Bash -> Chef -> Ansible と変遷 - 便利CLI - PythonやGoに置き換え - バッチスクリプト <- 今日はここの話 - Goに置き換え
Slide 12
Slide 12 text
強敵のバッチスクリプト
Slide 13
Slide 13 text
その名も開発DB構築スクリプト
Slide 14
Slide 14 text
こんな動作をします
Slide 15
Slide 15 text
10 ファイル 2128 行におよぶ Bashスクリプト
Slide 16
Slide 16 text
※ 事実ではありません
Slide 17
Slide 17 text
読めるわけがない
Slide 18
Slide 18 text
スクリプトの動作 - データ加工 - 元データのリストア - 並行で加工処理 - ダンプ - データ加工後のデータをテーブルごとに並行でダンプ - DBを一度に作れるフルダンプも生成 - インポート - フルダンプからの開発DB生成 - 日次更新が必要なテーブルを並行で部分インポート
Slide 19
Slide 19 text
他にはこんなことをしています - 失敗した時点から再実行するためのファイルキュー - Bashで書かれたファイルキュー実装 - それを利用したリトライ処理 - GNU parallel を使った並行実行 - データ加工 - ダンプ - インポート
Slide 20
Slide 20 text
※ 事実ではありません
Slide 21
Slide 21 text
読めるわけがない
Slide 22
Slide 22 text
よしGoに置き換えよう 読めるわけがないと言ったが読むしかない
Slide 23
Slide 23 text
Goの選定理由 - 並行実行の実装が容易 - Goroutineを使うだけで並行処理の実装が可能 - バッチなのでGoroutineのコストを気にしなくていい - Goの言語仕様のシンプルさ - 実装も利用するのもインフラエンジニア - コードを書くことが本職ではない - 複雑な実装が出来るよりも制約されるほうがいい - go testが言語仕様に組み込まれてるのもよい - IDEが使える - 補完・コードジャンプは重要
Slide 24
Slide 24 text
リプレースの方針 - いきなり全部Goに置き換えない - 読み解ける範囲、置き換えやすいところから - 難しいところはos/execでのBashの実行を許容 - Goらしさよりもまずは読み解けることを優先 - 置き換え中はBashっぽくなることを許容 - 徐々にGoらしく置き換えていく
Slide 25
Slide 25 text
ファイルキュー実装(Bash版)
Slide 26
Slide 26 text
ファイルキュー実装(Go版)
Slide 27
Slide 27 text
並行実行実装(Bash版)
Slide 28
Slide 28 text
並行実行実装(Go版)
Slide 29
Slide 29 text
Bash実行 - パイプ・リダイレクトに対応するためbash -cを使用
Slide 30
Slide 30 text
Bash実行(ログつき)
Slide 31
Slide 31 text
最近ハマった - io.MultiReader() は複数Readerの”連結” - stdoutとstderrを時系列順でログに吐きたかった - “連結”なのでstdoutがcloseされてからstderrを書く - stdoutがほとんど出ないコマンドを実行していた - 実行後30分ほどたってドバっとログが吐かれた
Slide 32
Slide 32 text
初回リプレースから約9ヶ月 - 動作は順調 - 問題なく動いています - 開発・リプレースも順調 - 現在 v0.0.8 - 読める・手を入れやすくなったため、変更が容易 - 外部コマンドに頼っていた部分もリプレース開始 - ダンプ・インポート部分(mysqldump) - Pure Goで実装してOSSとして出すつもり - (今日に実装間に合わなかった)
Slide 33
Slide 33 text
まとめ - 闇のBashをGoに置き換えたのは良い選択だった - 読みやすい・書きやすいことは大事 - 無理に全部置き換えようとしないのはもっと大事 - Goroutineのパワーすごい - 1バイナリになるので管理も楽 - 最近自前RPM化もした - メンテナンス出来るって素晴らしい - 動き続けてても放置はダメ - 先々を考えた技術選定も大切