Go Conference 2014 Springに行ってきた
まずは主催者の方のまとめブログがあるので紹介。スライド資料のリンクもあります。
http://ymotongpoo.hatenablog.com/entry/2014/06/01/124350
さて、以下はカンファレンスのメモですが、メモ書きレベルなので、読んでも意味わからないところがあるかもしれません。ちゃんとした内容はスライド資料見てください。ここでは雰囲気を掴んでもらえればいいかなと。あと英語のセッションはちゃんとメモれてないかも。
感想としては、goroutine と channelを使うとハイパフォーマンスなプログラムが作れるという話が印象に残った。
Date: 2014/5/31
Place: Gran Tokyo South Tower 41F
Academy Hall of the Recruit Life Style Company
Go Tutorial
講師: tenntenn
if,for,map,sliceなどの基本的なお作法、
インタフェース、継承について学ぶ。
そこで作成したコード
https://github.com/pandazx/go_test
ここでやった内容とは違うけど、興味がある人は、A Tour of Goをやればいい。
http://go-tour-jp.appspot.com/#1
Keynote: Go: 90% Perfect, 100% of the time
Brad Fitzpatrick
script is eacy but slow for computer
C is fast but read difficult for human
language map
y: Fun vs. fast(perl, python, LL)
x: Computer(c)
Java is middle. But don't like it.
(middleはx,yの両方をいい感じに満たしているという意味。Bladがそう言ったわけではなく、自分のメモのために便宜上、使った言葉)
Go is middle, but it is easy more than Java
Speed is same as Java.
Perlythonubyscript
(各種スクリプト言語まとめた略記)
language map 2
y: Concurrency and performance
x: Beautiful, staraight code
Erlang is middle(Callback hellがないから?)
Go is middle and Concurrency higher than Erlang
Goが使われているシーン
Image processing
Crypto
replacing shell scripts
- os/exec, goroutine
Camlistore
- web handlers
- web APIs
- pure Go
Controlling flying drones
Mobile
- Go runs on ARM
- minux's iOS port of Go
Audio synthesis
Cloud Infrastructure
- docker, packer
- CoreOS's etcd and fleet
Load balancers & servers
Raspberry Pi GPIO
他にこれだけの場所すべてで使える言語があるか?
Go built-in tools
- testing
- benchmarking
- profiling(CPU, memory, blocking)
- race detector
Generics(cons)
- No generics
- No algorithms in stdlibs
Data races can happen
- use channels
- but documentation is cheap
- be careful
Code generation
- ARM上でコンパイルすると、たまにpretty dumb codeを作ることがある
gccgo
- lacks escape analysis, パフォーマンス悪い
- 32bit
Compiling to JavaScript isn't great yet
- TADRIS Go Compiler
Limited Mobile Support
他の言語で呼び出すことが出来ない(no embed in other language environment)
no shared library
- 対応優先度はlow priority
Garbage collector
- Pauses:
- Precision
Hot stack splits
- 1.3でだいたい修正されたが、残りは1.4で
自分のプロジェクトにおいて、2012年頃からはほとんどGoだけを使っている
Session 1:社内システムをGoで書き直した話
App EngineアプリのPythonからGoへの移行
Rui Ueyama(Google Inc)
当初、話すつもりだったが、ボツネタになったGo標準ライブラリの話
- 標準ライブラリのパッチを送った話
- Google Docs(code?)にUPしてあり、読めるらしい
以下、本題。
2010年にPythonで作ったシステムを
2013年にGoで書き直した話
App Engineのストレージ
- Datastore(NoSQL)
- Blobstore(binary database for big file)
- Memcache
App Engineアプリのアップグレード方法
- version X,Y
- Xが稼働中にYをアップロード
- テスト
- GUIからYにスイッチするだけ
- 新しいバージョンでデータモデルを変更する場合
- 旧バージョンで存在しないデータがあるので、
その場合はデフォルトの処理を記述する必要がある
Go bindingではUserが定義されておらず、Pythonバージョンで
Userのメールアドレスを別フィールドにコピーする必要があった。
これを移行してから、新バージョンに移行。
HTTP Handlerで90秒の接続制限があったので、
1000件取得ずつ処理して、8時間かかった。
実はApp EngineはDatastoreに対してMapReduceが実行できたらしい。。。
全面的にリライトしているので、traffic splittingを活用。
App Engineでは複数のバージョンにトラフィックを分割できる。
10%->50%->100%と段階的に新バージョンへのトラフィックを増やして移行した。
ソースコード量はPythonからGoに移行して1.3倍?程度
増えたのはGoには閉じカッコがあるからと思われる。実質はほぼ変わらない。
移行メリット
- CPU, memoryが減った
- 静的な型付けによる安心感
Session 2: Five features that make Go fast
Dave Cheney
Go Community Management Leader in Sydney
Values
- Goではint32を4byteで扱える
- Pythonでは2014を24byte
- Javaでは32bitで16byte, 64bitで24byte
- データが小さいということはCPU cacheを効率よく使えて、パフォーマンスが向上する
Inlining
Escape analysis
Goroutines
- process switching cost
Copying Stacks
- hot splits
Session 3: Go in Production At Makerel.io
@stanaka(はてな)
Makerel
- ServerにAgentを入れて、クラスタ環境のリソース使用量を可視化
- Licence: APL2
why go
- need to support various environmens -> cross compiler
- easy setup -> one binary
- works quietly as possible -> usage memory: 6MB
1分ごとに起動
goroutineで多重起動しないように制御
取得したメトリクス情報は文字列処理して、色々なフォーマットに対応
(一番大変だった)
multi architectures
packaging
- dockerを使って、clean environmentでパッケージを作っている
agentのデーモン起動はnohupで
detect memory leak
- net/http/??? を使っている
Pros
- channel and goroutine is GREAT
- Easy to support various architectures
Cons
- String processing(parse)
- Q&Aでそれほど大変ではないと思っている人もいた。慣れの問題か。
- JSON parseも大変.静的言語の宿命だが
今後、色々使っていきたい
clash dumpの取得機能はまだない
メトリクスの収集失敗情報も取得できるようにしたい
Session 4: お仕事とgolang
非公開内容のため、省略
Session 5: 300万人をGoで捌いた話
@y_matsuwitter, Gunosy Inc.
ピークでのアクセスに対応できていない状況だった
System Architecuture
ELB
Nginx
Ruby on Rails
20-60req/sec
最初の改善後
ELB
Nginx
Rails | Sinatra
RDS | Redis
200req/sec
ここでTV CM開始
様々な技術を試行した
- Haskell -> 扱いづらい。メンテナンス大変。技術者いないし
- Node.js -> 高速。Goがなければ、これだった
- OpenResty -> ルアーつらい。ルアー?
Go導入後
ELB
Nginx
Rails | Sinatra | Go
RDS | Redis
2000req/sec(m1.large)
サーバ周り:net/http + gorilla/mux
DB周り:sql + Gorp
以下、goroutineを活用して様々なサービスを作った話。ただ、スクラッチから必要最低限の機能だけを作ったっぽい。
Goroutine as Cache DB
- Redis accessがボトルネックだった
- cache用のgoroutineを作って、DBからfetchさせておく
- channelやshared memoryをcache DBとして使う
- 結果
- network越しから、同プロセス内になった
- single core -> multi core
- データ形式はGoオブジェクトそのまま. パース不要
Goroutine as Message Queue
- どうしても直列化したい処理があった
- 重いのでブロックしたくない
- Pros
- 導入コストが低い
- パフォーマンス
- Cons
- Retry機構がない
ピーク負荷が異常に高いAPIに対してGoは非常に有効
GoroutineとChannelの組み合わせは有用
Q&A
プロセス再起動でキャッシュクリアされるが、それはどうしている?
今は起動後、数秒でロードできるので問題になっていない。
監視は?
httpを使って出来る
Session 6: Go駆動開発で超速Pushエンジンを作った話
@plan9user, フェンリル(受託開発部)
受託開発にGo導入。
対象:保守なしの短期利用アプリ
最初はPHPで実装
2000req/secが限界
設計がまずかった
net/rpc packageを使用
4000req/secまで向上
性能測定
- 実際のAPNs/GCMを使ってのベンチマークは難しい
- 端末を用意するのが難しい
- APNsは同一端末から数万件送るとInternalServerError
- Fake APNs/GCMを用意してベンチマークした
結果
- 並列数が10以上でレスポンス30秒程度でスケールした
Pros
Goがあって良かったことはあるが、
Goであって困ったことはなかった。
Q&A
- すべてGo標準ライブラリを使用
Session 7: pt & Goroutins
@monochromegane, GMO Pepabo, Inc.
自作したptの話。
文字列検索には色々ある
SJIS,EUC-JPファイルにも対応
agなどはskipされてしまう
検索の処理フロー
1.ファイル検索
2.文字列検索
3.表示
Approach 1: 最初は普通に直列で実装
Approach 2:各処理をgo f()で並行化
goroutine
- 軽量、並行処理を実現(not 並列)
channels
- goroutine間のメッセージング
- これを使って各処理の結果を次の処理に渡す
goroutine & channnelsでやったら逆に遅くなった
Approach 3:
channelの受付容量を変更
- ch := make(chan 型, 容量)
- 容量超えると送信側は待ちになってしまう
これでも、まだ遅い
もっと並行にしよう
grepの部分はfindから来た複数ファイルに対して
1つのgrepを実行するので、これをファイルごとにgrep groutine起動
結果、open too many files...
channelについて、MAX同時並行数を決めておき、
それを越えてはgrep goroutineが待ちになるように修正
Approach 4: 並列にしよう
GOMAXPROCS
- goroutineの並列度
- CPUコア数だけ設定する
やっとApproach 1よりも速くなった
今回の開発で、go f()による並行だけでは足りず、並列化する必要があるということがわかった。
残り後2つセッションがあったが、予定があったため、途中退場。残念。