SlideShare a Scribd company logo
1 of 18
Download to read offline
golang profilingの基礎
CA.go#1 (2017/06/21)
株式会社AbemaTV 中澤優⼀郎
⾃⼰紹介
中澤 優⼀郎 (はせ)
経歴
•2012/06~ AmebaスマートフォンPF
•2014/01~ 『タップル誕⽣』
•2015/12~ 『AbemaTV』
Golang歴 2年
Profiling of golang
pprof (runtime/pprof)
• GolangのProfilingを⾏うパッケージ
• CPU・Memory・goroutineなどの情報を収集
• protocol buffer形式でプロファイルを保存
• `go tool pprof` によりプロファイルを分析
runtime/pprof
CPU Profiler
• 関数の実⾏時間をプロファイリング
• (UNIX) settimerを利⽤し10msごとに
SIGPROFシグナル送信
• サンプラはシグナルをハンドリングし
スタックトレースを保存
f,	err	:=	os.Create(*cpuprofile)

if	err	!=	nil	{

			log.Fatal("could	not	create	CPU	profile:	",	err)

}

if	err	:=	pprof.StartCPUProfile(f);	err	!=	nil	{

			log.Fatal("could	not	start	CPU	profile:	",	err)

}

defer	pprof.StopCPUProfile()
runtime/pprof
CPU Proflier以外のProfilerはLookupで呼び出し
f,	err	:=	os.Create("./mem.prof")	
if	err	!=	nil	{	
log.Fatal("could	not	create	memory	profile:	",	err)	
}	
defer	func()	{	
pprof.Lookup("heap").WriteTo(f,	0)	
				f.Close()	
}()
runtime/pprof
“heap” (Heap Profiler)
• メモリの情報(GCとアロケーション)をプロファイリング
“goroutine” (Goroutine Profiler)
• 実⾏中のgoroutineのプロファイリング
heap options
(go tool pprof -inuse_space mem.prof )
-inuse_space 利⽤中のメモリ領域
-inuse_objects メモリ利⽤中のオブジェクト数
-alloc_space 前回のGCからアロケートされたメモリ領域
runtime/pprof
“block” (Blocking Profiler)
※ runtime.SetBlockProfileRate を 1 以上に設定することで有効化
• 同期処理でwaitingしているgoroutineをプロファイリング
“mutex” (Mutex Profiler) ※go1.8から追加
※ runtime.SetMutexProfileFraction を 1 以上に設定することで有効化
• 同期処理をブロックする ”mutexのみ” をプロファイリング
• time.Tickerなどパフォーマンスに深刻な影響を与えない項⽬は表⽰されない
runtime/pprof
Custom Profilers
Profilerの実装によりカスタムプロファイラを作成可能
import	“runtime/pprof"	
prof	:=	pprof.New(“custom”)	
prof.Add(obj,	1)	
prof.Remove(1)
Relational Packages
runtime/pprof
net/http/pprof
•HTTP Server⽤のプロファイラ
github.com/pkg/profile
•`runtime/pprof` をより簡単に利⽤できるようなwrapper
•元はdevecheneyの `https://github.com/davecheney/profile`
net/http/pprof
Web Server向けpprofパッケージ
• http経由でプロファイリングを取得
• 2種類のバインド⽅法
• DefaultServeMuxにバインド (blank
import)
• ServeMuxをNewしてバインド
import	(	
		"net/http"	
		"net/http/pprof"	
		"runtime"	
)	
---	
		mux	:=	http.NewServeMux()	
		mux.Handle("/debug/pprof/",	http.HandlerFunc(pprof.Index))	
		mux.Handle("/debug/pprof/cmdline",	http.HandlerFunc(pprof.Cmdline))	
		mux.Handle("/debug/pprof/profile",	http.HandlerFunc(pprof.Profile))	
		mux.Handle("/debug/pprof/symbol",	http.HandlerFunc(pprof.Symbol))	
		mux.Handle("/debug/pprof/trace",	http.HandlerFunc(pprof.Trace))	
---	
		go	func()	{	
					log.Println(http.ListenAndServe("localhost:6060",	mux));		
		}	
import	_	"net/http/pprof"	
go	func()	{	
		log.Println(http.ListenAndServe("localhost:6060",	nil))	
}()
github.com/pkg/profile
runtime/pprofをシンプルなインターフェースで提供
• shutdown signalのハンドリング
以下のプロファイラを利⽤可能
• CPU Profiler
• Heap Profiler
• Block Profiler
• Trace Profiler (runtime/trace)
package	main	
import	(	
		"github.com/pkg/profile"	
)	
func	main()	{	
		 defer	profile.Start(profile.BlockProfile).Stop()	
}
go test profiling
テストコードのプロファイリング
テストオプションに指定することによりプロファイリング可能
-blockprofile block.out : Block Profileの取得
-cpuprofile cpu.out : CPU Profileの取得
-memprofile mem.out : Heap Profileの取得
-mutexprofile mutex.out : Mutex Profileの取得
Go tool pprof
$	go	tool	pprof	--text	mpeg-probe	sample.prof/cpu.pprof	
108.45s	of	112.28s	total	(96.59%)	
Dropped	148	nodes	(cum	<=	0.56s)	
						flat		flat%			sum%								cum			cum%	
				78.03s	69.50%	69.50%					78.18s	69.63%		syscall.Syscall	
					8.47s		7.54%	77.04%						8.47s		7.54%		runtime.mach_semaphore_wait	
					7.19s		6.40%	83.44%						7.19s		6.40%		runtime.mach_semaphore_signal	
					3.43s		3.05%	86.50%						3.43s		3.05%		runtime.mach_semaphore_timedwait	
					3.02s		2.69%	89.19%						3.02s		2.69%		runtime.memclrNoHeapPointers
プロファイリングの集計・可視化
• `go tool pprof` を利⽤して
• コマンドラインでの実⾏と、インタラクティブシェルを提供
Go tool pprof
(pprof) web
• svg形式で吐き出されたプロファイルをwebブラウザで表⽰
• function名の指定で絞り込み
• graphvizのインストールが必要
$	go	tool	pprof		mpeg-probe	sample.prof/cpu.pprof	
Entering	interactive	mode	(type	"help"	for	commands)	
(pprof)	web	main
Go tool pprof
(pprof) top
• 取得したプロファイルの上位N件の表⽰
• `-FIELD` 指定によりソート
(pprof)	top	5	-flat	
100.14s	of	112.28s	total	(89.19%)	
Dropped	148	nodes	(cum	<=	0.56s)	
Showing	top	5	nodes	out	of	92	(cum	>=	3.02s)	
						flat		flat%			sum%								cum			cum%	
				78.03s	69.50%	69.50%					78.18s	69.63%		syscall.Syscall	
					8.47s		7.54%	77.04%						8.47s		7.54%		runtime.mach_semaphore_wait	
					7.19s		6.40%	83.44%						7.19s		6.40%		runtime.mach_semaphore_signal	
					3.43s		3.05%	86.50%						3.43s		3.05%		runtime.mach_semaphore_timedwait	
					3.02s		2.69%	89.19%						3.02s		2.69%		runtime.memclrNoHeapPointers
flat : 関数の使⽤した値
flat% : flat値の全体の占める割合
sum% : 現在のソート順でのflat値の累計値
cum : 関数の他の関数の呼び出しも含めた値
cum% : cum値の全体に占める割合
Go tool pprof
(pprof) list
• go tool実⾏時にバイナリファイルの指定が必要
• ソースコード上でのflat,cum値を表⽰
(pprof)	list	io.Copy	
Total:	1.87mins	
ROUTINE	========================	io.Copy	in	/usr/local/Cellar/go/1.8.1/libexec/src/io/io.go	
									0			1.09mins	(flat,	cum)	58.15%	of	Total	
									.										.				355://	If	src	implements	the	WriterTo	interface,	
									.										.				356://	the	copy	is	implemented	by	calling	src.WriteTo(dst).	
									.										.				357://	Otherwise,	if	dst	implements	the	ReaderFrom	interface,	
									.										.				358://	the	copy	is	implemented	by	calling	dst.ReadFrom(src).	
									.										.				359:func	Copy(dst	Writer,	src	Reader)	(written	int64,	err	error)	{	
									.			1.09mins				360:	 return	copyBuffer(dst,	src,	nil)	
									.										.				361:}	
									.										.				362:	
									.										.				363://	CopyBuffer	is	identical	to	Copy	except	that	it	stages	through	the	
									.										.				364://	provided	buffer	(if	one	is	required)	rather	than	allocating	a
Check Point
runtime.mallocgc
• メモリアロケーションが多く発⽣している
runtime.chanrecv, sync.Mutex
• ロック処理により多くの待ちが発⽣している
syscall Read / Write
• ioの読み書きが⼤量に発⽣している
GCコンポーネント
• ヒープサイズの⼩ささにより、GCの発⽣が頻繁に発⽣している
Go Debug Options
Memory Allocator Trace
- GODEBUG=allocfreetrace=1
Garbage Collector Trace
- GODEBUG=gctrace=1 .
Scheduler Trace
- GODEBUG=schedtrace=1000 ./

More Related Content

What's hot

rsyncのちょっとイイ話
rsyncのちょっとイイ話rsyncのちょっとイイ話
rsyncのちょっとイイ話
Kazuhiro Oinuma
 

What's hot (20)

Dockerの期待と現実~Docker都市伝説はなぜ生まれるのか~
Dockerの期待と現実~Docker都市伝説はなぜ生まれるのか~Dockerの期待と現実~Docker都市伝説はなぜ生まれるのか~
Dockerの期待と現実~Docker都市伝説はなぜ生まれるのか~
 
Marp Tutorial
Marp TutorialMarp Tutorial
Marp Tutorial
 
テスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるなテスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるな
 
イミュータブルデータモデル(入門編)
イミュータブルデータモデル(入門編)イミュータブルデータモデル(入門編)
イミュータブルデータモデル(入門編)
 
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Dockerからcontainerdへの移行
Dockerからcontainerdへの移行
 
At least onceってぶっちゃけ問題の先送りだったよね #kafkajp
At least onceってぶっちゃけ問題の先送りだったよね #kafkajpAt least onceってぶっちゃけ問題の先送りだったよね #kafkajp
At least onceってぶっちゃけ問題の先送りだったよね #kafkajp
 
DockerとPodmanの比較
DockerとPodmanの比較DockerとPodmanの比較
DockerとPodmanの比較
 
分散システムについて語らせてくれ
分散システムについて語らせてくれ分散システムについて語らせてくれ
分散システムについて語らせてくれ
 
エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織
 
WebSocket / WebRTCの技術紹介
WebSocket / WebRTCの技術紹介WebSocket / WebRTCの技術紹介
WebSocket / WebRTCの技術紹介
 
ゼロから作るKubernetesによるJupyter as a Service ー Kubernetes Meetup Tokyo #43
ゼロから作るKubernetesによるJupyter as a Service ー Kubernetes Meetup Tokyo #43ゼロから作るKubernetesによるJupyter as a Service ー Kubernetes Meetup Tokyo #43
ゼロから作るKubernetesによるJupyter as a Service ー Kubernetes Meetup Tokyo #43
 
例外設計における大罪
例外設計における大罪例外設計における大罪
例外設計における大罪
 
PlaySQLAlchemy: SQLAlchemy入門
PlaySQLAlchemy: SQLAlchemy入門PlaySQLAlchemy: SQLAlchemy入門
PlaySQLAlchemy: SQLAlchemy入門
 
PFN のオンプレML基盤の取り組み / オンプレML基盤 on Kubernetes 〜PFN、ヤフー〜
PFN のオンプレML基盤の取り組み / オンプレML基盤 on Kubernetes 〜PFN、ヤフー〜PFN のオンプレML基盤の取り組み / オンプレML基盤 on Kubernetes 〜PFN、ヤフー〜
PFN のオンプレML基盤の取り組み / オンプレML基盤 on Kubernetes 〜PFN、ヤフー〜
 
実践!OpenTelemetry と OSS を使った Observability 基盤の構築(CloudNative Days Tokyo 2022 発...
実践!OpenTelemetry と OSS を使った Observability 基盤の構築(CloudNative Days Tokyo 2022 発...実践!OpenTelemetry と OSS を使った Observability 基盤の構築(CloudNative Days Tokyo 2022 発...
実践!OpenTelemetry と OSS を使った Observability 基盤の構築(CloudNative Days Tokyo 2022 発...
 
ストリーム処理勉強会 大規模mqttを支える技術
ストリーム処理勉強会 大規模mqttを支える技術ストリーム処理勉強会 大規模mqttを支える技術
ストリーム処理勉強会 大規模mqttを支える技術
 
rsyncのちょっとイイ話
rsyncのちょっとイイ話rsyncのちょっとイイ話
rsyncのちょっとイイ話
 
関数型プログラミングのデザインパターンひとめぐり
関数型プログラミングのデザインパターンひとめぐり関数型プログラミングのデザインパターンひとめぐり
関数型プログラミングのデザインパターンひとめぐり
 
AWSとオンプレミスを繋ぐときに知っておきたいルーティングの基礎知識(CCSI監修!)
AWSとオンプレミスを繋ぐときに知っておきたいルーティングの基礎知識(CCSI監修!)AWSとオンプレミスを繋ぐときに知っておきたいルーティングの基礎知識(CCSI監修!)
AWSとオンプレミスを繋ぐときに知っておきたいルーティングの基礎知識(CCSI監修!)
 
Grafana LokiではじめるKubernetesロギングハンズオン(NTT Tech Conference #4 ハンズオン資料)
Grafana LokiではじめるKubernetesロギングハンズオン(NTT Tech Conference #4 ハンズオン資料)Grafana LokiではじめるKubernetesロギングハンズオン(NTT Tech Conference #4 ハンズオン資料)
Grafana LokiではじめるKubernetesロギングハンズオン(NTT Tech Conference #4 ハンズオン資料)
 

Similar to golang profiling の基礎

Similar to golang profiling の基礎 (20)

Programming camp Codereading
Programming camp CodereadingProgramming camp Codereading
Programming camp Codereading
 
Optuna Dashboardの紹介と設計解説 - 2022/12/10 Optuna Meetup #2
Optuna Dashboardの紹介と設計解説 - 2022/12/10 Optuna Meetup #2Optuna Dashboardの紹介と設計解説 - 2022/12/10 Optuna Meetup #2
Optuna Dashboardの紹介と設計解説 - 2022/12/10 Optuna Meetup #2
 
AWS Security JAWS 経済的にハニーポットのログ分析をするためのベストプラクティス?
AWS Security JAWS 経済的にハニーポットのログ分析をするためのベストプラクティス?AWS Security JAWS 経済的にハニーポットのログ分析をするためのベストプラクティス?
AWS Security JAWS 経済的にハニーポットのログ分析をするためのベストプラクティス?
 
Gocon2017:Goのロギング周りの考察
Gocon2017:Goのロギング周りの考察Gocon2017:Goのロギング周りの考察
Gocon2017:Goのロギング周りの考察
 
Pyconjp2014_implementations
Pyconjp2014_implementationsPyconjp2014_implementations
Pyconjp2014_implementations
 
Goでかんたんソースコードの静的解析
Goでかんたんソースコードの静的解析Goでかんたんソースコードの静的解析
Goでかんたんソースコードの静的解析
 
Djangoフレームワークの紹介
Djangoフレームワークの紹介Djangoフレームワークの紹介
Djangoフレームワークの紹介
 
Perl/CGI 入門
Perl/CGI 入門Perl/CGI 入門
Perl/CGI 入門
 
どこでも動くゲームを作るためのベタープラクティス
どこでも動くゲームを作るためのベタープラクティスどこでも動くゲームを作るためのベタープラクティス
どこでも動くゲームを作るためのベタープラクティス
 
78tch
78tch78tch
78tch
 
20130824 Lightweight Language "Go" @LL matsuri
20130824 Lightweight Language "Go" @LL matsuri20130824 Lightweight Language "Go" @LL matsuri
20130824 Lightweight Language "Go" @LL matsuri
 
JJUG CCC 20150411 grails3 Spring-boot
JJUG CCC 20150411 grails3 Spring-bootJJUG CCC 20150411 grails3 Spring-boot
JJUG CCC 20150411 grails3 Spring-boot
 
Kanazawa.js.Next
Kanazawa.js.NextKanazawa.js.Next
Kanazawa.js.Next
 
runC概要と使い方
runC概要と使い方runC概要と使い方
runC概要と使い方
 
JavaScript.Next
JavaScript.NextJavaScript.Next
JavaScript.Next
 
UE4におけるLoadingとGCのProfilingと最適化手法
UE4におけるLoadingとGCのProfilingと最適化手法UE4におけるLoadingとGCのProfilingと最適化手法
UE4におけるLoadingとGCのProfilingと最適化手法
 
Drone programming with ArduPilot
Drone programming  with ArduPilotDrone programming  with ArduPilot
Drone programming with ArduPilot
 
Ocamlでpfffを拡張した話
Ocamlでpfffを拡張した話Ocamlでpfffを拡張した話
Ocamlでpfffを拡張した話
 
Pythonによる非同期プログラミング入門
Pythonによる非同期プログラミング入門Pythonによる非同期プログラミング入門
Pythonによる非同期プログラミング入門
 
Project Sumatra - JavaOne2012報告会 #j1rep
Project Sumatra - JavaOne2012報告会 #j1repProject Sumatra - JavaOne2012報告会 #j1rep
Project Sumatra - JavaOne2012報告会 #j1rep
 

golang profiling の基礎