基礎勉強会#4 低レイヤの開発ツール
社内で行った基礎勉強会の第 4 回。低レイヤでの開発ツールの話。
gdb や valgrind などの低レイヤ、というか C/C++ での開発で使いそうなツールの話。半分以上 は gdb。 参加者が現在進行形で C を書いているというのでテーマに取り上げた。
gdb は調べてみると結構知らないことがあって驚いた。 C-x C-a で TUI にできたり、reverse-next できたり、Go や Rust にも対応していたり。 おまけに reverse-next とかの機能はもう 10 年くらい前にはもうあったらしい。gdb のうちではマイナーなコマンドかもしれないが、もうちょっと先に知っておきたかった。
発表としてはほぼツールを実際に使ってみてみせるだけなので、資料としてはかなり薄め。内容がない。 デモのためのコードも書いてみたが、gdb の watch コマンドの実演がいまいちうまくいかなかった。デモの練習が足りてない。
次回はデータ構造の話。ようやく基礎らしい話ができる。
Go Conference 2018 Autumn メモ
少し前の話になるが Go Conference 2018 autumn に参加した。 Go Conference 2018 autumn は 2018/11/25 に行われた Go 言語のイベントで、六本木の Google オフィスで行われた。
自分と Go との関わりだが、今現在のプロジェクトでは Go を使っているもののどうも妙な使い方をしている。 なので他のところでの話は機会があれば聞いておきたかった。
自分が聞いた範囲では GAE とマイクロサービスでの話が多かった。 やはりクラウド上でマイクロサービスを使う場合には、Go が有利なんじゃかないかと思う。
その他にも低レイヤよりの話や、パフォーマンスチューニング、導入事例など色々な話が聞けてよかった。
以下メモ。
キーノート by Steven Buss
キーノートは GAE/Go の 歴史的な変遷と最新の GAE の話。
以前は NaCl= Google Native Client で動いており、 ptrace を使ってシステムコールの呼び出しを検知しハンドリングすることで環境を独立させていた。 新しい世代の App Engine では gVisor を使っているのでそれらの必要がなくなった。
gVisor は Go で書かれた ユーザ空間カーネルで、 アプリケーションのシステムコールなどをハンドリングして環境を隔離し、セキュアにできる。
gVisor:
- Pros: 柔軟な必要リソース、低コストな仮想化、拡張可能なアーキテクチャ
- Cons: 互換性の減少、高オーバーヘッドなシステムコール、システムコールが実装されていないときにはよくわからないエラーになる
gVisor の構成:
2 つのプロセス間は 9P (Plan 9 Filesystem Protocol) で繋がれている。
将来的には Google のクラウドはすべて Go で作られる。
- gVisor
- Second-gen pp Engine runtimes
- Cloud functions
- k8s
- knative
- etc, etc
Mirroservices 実装ガイド in Go at Mercari by @_yagi5
メルカリでのマイクロサービスの話。
- サービスの追加手順
- プロトコルバッファの追加→サービスの実装の順序
- サービス間通信
- サービスのテンプレート
- エコーサーバ
- ミドルウェア
- grpc-echosystem/go_grpc_middleware の ServerChain の仕組みを使用
- ロギング(トレーシング)
- opencensus と zap(zapgrpc) を利用
- マイクロサービスでの Go のいいところ
- ネットワーク/ミドルウェアレイヤとの相性がいい
- 静的解析ツールで書き方を強制できる
OpenCensus による APM の実現と未来 by @munisystem
APM = Application Performance Management の話。
- APM
- APM = 「Service Level を維持するため app のパフォーマンスの継続的な監視をすること」
- 実現に必要
- performance の取得
- data の可視化、活用できる基盤の構築
- Tracing: サービス・サーバをまたいだイベントの追跡
- Metrics: なにが原因で悪くなったか調べるのに必要
- Logging: ログ
- Error reporting: エラーの調査
Go での APM 実現例として:
- Tracing: Stackdriver Trace /Datadog APM /Zipkin ?jaeger
- Metrics: Stackdriver Monitoring / Dtadog /Prometheus
- Loggin: zap / glog + fluentd
- Error repoirting: Hobeybadger /Sentry
だが上記のライブラリではクライアントライブラリと基盤が密になってしまっている。 APM 基盤はサービス、組織の規模で変更を楽にしたい。
OpenCensus * OSS 版 Census * APM のデータを収集→外部サービスに提供 * アプローチ *コレクターとエクスポーターの分離 * コレクター データの収集 * エクスポーター 変換と送信 * Cloud provider は expoorter だけ実装する * App はデータを収集するところだけ実装する * 欠点 * バックエンド固有の最適化のためのメタデータの付与が行えない←結合度が下がったため
Profiling Go Application by @orisano
Go アプリケーションの性能を改善した話。
- 画像変換サーバが OOM killer に殺された
- 調査
*
pprof, GODEBUG=allocfreetrace=1
- GC で参照グラフをダンプしてみた
- 問題点
- 同時変換数に制限がつけられてなかった
- 調査
*
- disintegration/imaging が 遅い
- boundary check elimination
- 添字チェック→安全だと判断できればコンパイラ側が削除してくれる
- boundary check elimination
kubelet でCPU負荷が高い
- 調査
- kubelet は pprof を imporot しているので pprof を使う
- 問題点
- String.Replacer が大量にあった
- 対策
- Write がたくさんある部分を1 Write にまとめることができる
- Readdir 遅い, -> goreaddir に入れ替え
- 調査
まとめ
- 普段使っているものでもカリカリにチューニングされているわけではない
- 遅いと思ったら自分で改善してみる
- 対策するには
- Benchmark を書く: bnechcmp or chenccomp
- Go はパフォーマンスチューニングしやすい
- ツール充実している
Biscuit Code Reading by @shibu_jp
Biscuit Code Reading - Google スライド
@shibu_jp さんは「Goならわかるシステムプログラミング」の著者の方で、 Biscuit をネタに主にブートシーケンスに関する低レイヤの話をしていただけた。
Biscuit は 並列・分散の研究ためのOS で Go で書かれている
- 論文
- Features
- multicore
- journaled FS with concurrent, deferred and group commit
- 中身
- ほぼ Go のところがある
- Biscuit のみの部分は buicuit/ 下に置いてある
- Kernel Space
- Bisucut / Go library / Shim
- shim -> systell call 置き換え
- Executable File Format は ELF
まとめ
- Go はコンピュータシステムを学ぶのによい教材
- Go 言語のランタイムは低レイヤから上まで Go で書かれている
- Goならわかるシステムプログラミングを読もう
基礎勉強会#3 並行・並列処理の基礎
社内で行った基礎勉強会の第3回目は並列・並行がテーマ。
なんだがテーマが前回・前々回から飛んだ感じはあるが、リクエストがあったしそのうちやったほうがいいと思ったのでこのテーマで話すことにした。
広く浅くという感じであるが、並列・並行処理に関する基礎知識にはそこそこ触れられたかな? 個人的にも概念を色々整理できたのはよかった。データ競合と競合状態はちょっとごっちゃに覚えていた気がするのでちゃんと調べてみてよかったと思う。
残念な点として、もうちょっとモダンな並行処理を取り上げたかったのはある。 リアクティブプログラミングとか話をしたかったが、資料が間に合わないのとちょっと自分でも知識が足りてない気がするので残念ながら見送った。 ただ若干反応が薄かったので、聞いていた人のニーズには合ってなかったかもしれない。
参考資料にも書いたが、Java Concurrency in Action は今読んでも結構いい内容になってる。
次回は gdb, valgrind など低レイヤでの各種ツールの話。 基礎なのか?という気はするが、話を聞きに来てくれている人がCを書いている人しかいないので需要は満たしている。
ドキュメント作成用の Makefile
ドキュメント用の Makefile
仕事で Markdown 形式のドキュメントをつくることになったので、 そのための Makefile を作った。 pdf 生成と redpen でのチェックをするようにしたい。
.PHONY: help clean redpen docs .DEFAULT_GOAL = help # define docker container for each targets # container.redpen = ainoya/redpen container.redpen = pandoc container.docs = pandoc all: docs help: @grep -E '^[a-zA-Z%_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' docs: golang.pdf python.pdf ## generate pdf files %.pdf: %.md pandoc $< --toc --from=gfm -t html5 -o $@ docker-%: ## run make in the Docker container (ex, 'make docker-docs' runs 'make docs' on the docker container) $(eval target = $(subst docker-,,$@)) docker run -v `pwd`:/root/docs -it $(container.$(target)) $(option.$(target)) /bin/bash -c "cd /root/docs; make $(target)" install-dev-mac: ## install developer's file brew install pandoc brew install redpen brew install graphviz brew install plantuml brew cask install wkhtmltopdf redpen: redpen --conf redpen-conf.xml --format markdown --result-format plain2 -L ja *.md clean: rm -rf *.pdf
ポイントとしては、自己文書化していることと Docker 上で走らせられるようにしてあることの 2 点がある。
自己文書化のアイディアはhttps://postd.cc/auto-documented-makefile/から持ってきている。
make help
を実行すると次のように表示される。
docker-% run make in the Docker container (ex, 'make docker-docs' runs 'make docs' on the docker container) docs generate pdf files install-dev-mac install developer's file
また docker-
をルールの前に付けると、そのルールを Docker 上で実行する。
Docker で環境を共有するようにしたほうがいいかと思ったが、これについてはオーバースペックと言われた。
他にも色々出来そうだが、文章を書くことが優先事項なので後は手が空いたら改良したい。
社内基礎勉強会 #2
社内で行った勉強会第2回はソフトウェアテストを扱った。
最初はテスト駆動開発だけを取り上げるつもりだったが、新人向けに内容を考えていくうちにこんな形になった。 おまけに時間切れでテスト駆動開発の話は全然できてない。
社内の事情として、新人はとりあえずテストの担当(場合によっては手動でテストし、テストケースはエクセル)をするということが多い。 それにも関わらず実際テストについて学ぶ機会はあまりないので、テストに関する知識は共有するべきだと思ってた。 なお周りに新人がいなくなって久しいので、新人の教育事情はちょっと認識と合ってないかもしれない。
テスト計画については、プロジェクトの三角形は自分の新人研修時に聞いた覚えがあったのでそれに倣って3つの要素からなるように書いてみた。 若干無理やり詰め込んだ感じはあるが、社内のワークフローを考えると間違ったことは言ってないと思う。
ソフトウェアテスト技法については、同値分割、境界値分析の他、ディシジョンテーブルについて詳しく解説を入れた。 というのも以前周囲の誰かが知っときゃよかった、と言ってたのを聞いていた気がするので。 組み合わ絵テストについては自分が詳しくないのであまりいい説明ができたとは思えない。入れなくても良かったかも。
テストコードについては、実践JUnit で紹介されていた FIRST が、覚えやすそうなのもあって説明に使うことにした。内容的にも非常に同意できるのもある。 アンチパターンは軽く紹介するくらいにとどめた。説明を書くのが間に合わなかったのもある。 「失敗しないテスト」については言及している書籍はなかったが、自分が何回かした失敗なのもあって加えることにした。テストファーストを紹介する導入にもなるかと思う。
テスト駆動開発についてはデモと合わせて説明するつもりだったが、ちょっと時間がたりず説明が足りてない。うーむ。
次回は並列・並行処理にをテーマにすることになった。
Docker Meetup Tokyo #26 に参加してきたメモ
Docker Meetup Tokyo #26
いま参加しているプロジェクトでは Docker を使っているのだが、自分は割と雰囲気で使っているところがあり、 また他のプロジェクトで Docker を使っているところは知らない。
ということで他のところでどういう使い方をしているのか知りたくて、ちょうどやってた Docker Meetup (https://dockerjp.connpass.com/event/106358/) に参加してきた。
スポンサーセッション (@algas)
負荷テストツール LOCUST の紹介。
LOCUST は分散して負荷をかけることができるツールで、同期実行の問題などを解決している。 Python から利用可能で、レポート機能もあり。ただしレコード機能はなく、プロトコルとしては http(s) しか対応していないことに注意。 Google Cloud から使うこともでき、簡単に構築できる。
負荷テストのときの注意点としては、ユーザ数は徐々に大きくし Hatch rate (= ユーザ増加率) は小さくすること。 一度に大きな負荷がかかることを避けることができる。
KubeCon China参加報告 (KubeCon China Recap) Kazuki Suda (@superbrothers)
中国で行われた KubeCon China のレポート。
普段は欧州やサンフランシスコで行われているが、中国でも開催されるようになった。 Alibaba などのコントリビュートは結構多いのにちょっと驚いた。 CNCF (クラウドネイティブな OSS 技術の推進を行う団体。k8s もこの団体がホスティングしている) の3つのサンドボックスプロジェクトが中国企業からの貢献で進められている。
キーノートでの話だと、k8s はすでに多くの企業で本番利用されていて、安心してビジネスに利用できる段階になっているとのこと。
あとセッションでは k8s をコントロールするのに k8s を使うという話が多かったらしい。これはどうなんだろ?わざわざ問題を作り出しているようにも思える。
いま話題のいろいろなコンテナランタイムを比較してみた (Comparison of several container runtimes) Kohei Tokunaga (@TokunagaKohei)
タイトルの通りいろいろなコンテナランタイムを主に性能面で比較した話。
コンテナには高レイヤと低レイヤの2種類がある。 高レイヤコンテナは kubelet からの指示で pod などを作るもので、 低レイヤコンテナは docker から直接作られるものと分類されている。
取り上げられたランタイムは:
- 高レイヤ: containerd, cri-o, rkt
- 低レイヤ: rnc, runsc(gVisor), runnc(nabla containers), kata-runtime (Kata containers)
まずコンテナにこれほど種類があるのは知らなかったので勉強になった。
Docker Swarm-mode Kohei Ota (@inductor)
あまり人気のない Docker の Swarm Mode の話。
NW 周りがしょぼい、Docker CE だと CNI (=Container Network Interface)使えないなど制限はあるものの、Docker を普段から使っていれば k8s に比べて Swarm の導入はかなり楽にできる。 なので大規模なコンテナの運用が必要でない場合には、 Swarm mode も検討してみるのがよいのでは、という話をしていた。
Docker v18.09の新機能の紹介 (Docker v18.09 new features) Akihiro Suda (@AkihiroSuda)
Docker 18.09 は 11/8 にリリースされ、BuildKit がの正式採用された。 BuildKit は新しい docker build のコマンドで、並列、早い、便利。
仕組みとして Dockerfile を DAG 付きの中間言語 LLB に変換して、並列実行可能な箇所を検出してくれるらしい。
また新しい Dockerfile のシンタックスが追加された。 これは Dockerfile 先頭に
# syntax = docker/dockefile:1.0-experimental
と書いておけば使えるようになり、RUN
が次のようなオプションを持つようになる。
RUN --mount=type=cache
: ビルド時にキャッシュを使うRUN --mout=type=secret
: 鍵を安全におけるRUN --mout=type=ssh
: クライアントの ssh-agent に接続
加えてリモートの Docker ホストに ssh 接続ができるようになった。環境変数を次のように設定する。
export DOCKER_HOST=ssh://user@host`
Docker が動いているホストに ssh で接続するのではなく、Docker 自体に接続するので手元の設定ファイルや認証情報が適用できる利点がある。
Multi-stage Docker Build @orisano
BuildKit 以前の話だが、Docker のビルドの話で、17.05 から導入された multi-stage build の使ったビルドパターンの紹介。 CI でどのようにしたらよいかがあったので、それも参考になった。
ただ BuildKit で結構変わるので、18.09 からまた事情が変わるようである。
感想
k8s の話もあって、インフラ視点寄りの話が多かった。 Docker ビルドの話から、他のところでの Docker の使い方が垣間見えたが、 現プロジェクトはやはりちょっとちがう使い方をしているように思える。 Docker イメージを作る際もスクリプトを通してなんとなくやってしまっているが、 他のところのやり方を聞くのはかなり参考になった。
18.09 の機能は良さそうだs使いたいが、出たばかりだしプロジェクトで使うのは先になりそうなのがちょっと残念。
あとやっぱり中国の勢いすごいな。中国語のドキュメントを読むのもそう遠くないのかも。 なんかまた中国でカンファレンスがあるんだったら近いし行ってみたい。
kubernetes に加えて Docker ももうちょっとまじめに使えるようにしておきたい。
社内基礎勉強会 #1
社内で行った勉強会の資料
他に社内で勉強会が走っているし、自分が勉強会に取り上げたいテーマで人が集まりそうなテーマが思いつなかった。 なので基礎勉強会という形で、再度初めから勉強し直したくはないが復習はしておきたいトピックで初心者にも受けが良さそうなものを紹介していく形の勉強会にした。 (どのみち人は集まらなかったが…)
Git の方は楽にスライド作れそうだし、現在のエンジニアは必須の知識だろうと思って最初のテーマに取り上げた。 楽に作れるかと思っていたが、「基礎」的な部分の定義がブレブレでどういうことを書くべきがかなり迷ってしまった。 Git について語りたいことは山ほどあったが、基礎的な話かというとそうでもない場合が多い。 結局結構スライドを削ることにした。脇道にそれるのはいけない。
次回についての要望がなかったので、独断でテスト駆動開発について話したいと思う。 TDD is dead と言われて久しいが、テストを先に書いたほうが良い場合は結構あるはずなので、うまいところ話しておきたい。