SlideShare a Scribd company logo
1 of 47
Download to read offline
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
Yasuharu GOTO (@ono_matope)
2017/03/25
Goでヤフーの分散オブジェクトストレージを作った話
Go Conference 2017 Spring
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
About me
名前: Yasuharu GOTO
Twitter: @ono_matope
Github: @matope
所属: ヤフー株式会社 データプラットフォーム開発本部
Go歴:3年
コントリビューション:
Expect:100-Continueのクライアント実装 (Go1.6)
2
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
Agenda
• Goでヤフーの基盤ストレージ Dragon を作った話
• Goでの耐障害性向上テクニック
3
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.Copyright © 2017 Yahoo Japan Corporation. All Rights Reserved.
Dragon
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
Dragon
• ヤフーで開発している分散オブジェクトストレージ
• デザインゴール:高速、高スケーラビリティ、高可用性、低コスト
• Go言語
• S3 互換 API
• 2016年1月 リリース (14ヶ月の本番稼働実績)
5
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
Why we built a new Object Storage?
6
• Octagon(2011-)
• 最初の内製オブジェクトストレージ
• 諸々の技術的課題から、代替を検討
• 遅い・不安定・運用しづらい・レガシー・etc...
• 既存のOSS?
• Riak CS : 一部で導入するも、性能がサービス要件を満たさず
• OpenStack Swift : スケーラビリティに不安
• パブリッククラウド?
• 自社DCと比べてコスト面で不利
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
Why we built a new Object Storage?
7
じゃあ作ろう
2014年 実装スタート
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.8
クラスタ数: 2
格納オブジェクト数: 100億
格納データ量: 9PB
サービス利用多数(右)
その他社内システム多数
Presto (in experiment)
利用規模
Yahoo!オークション (画像)
Yahoo!ニュース・トピックス/個人 (画像)
Yahoo!ディスプレイアドネットワーク (画像/動画)
Yahoo!ブログ (画像)
Yahoo!スマホきせかえ (画像)
Yahoo!トラベル (画像)
Yahoo!不動産 (画像)
Yahoo!知恵袋 (画像)
Yahoo!飲食店予約 (画像)
Yahoo!みんなの政治 (画像)
Yahoo!ゲーム (コンテンツ)
Yahoo!ブックストア (コンテンツ)
Yahoo!ボックス (データ)
ネタりか (記事画像)
etc...
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
Performance (with Riak CS/参考値)
• Dragon: API*1, Storage*1,Cassandra*3
• Riak CS: haproxy*1, stanchion*1, Riak (KV+CS)*3
• CassandraとStanchion以外はすべて同一構成のHWを使用。
9
0
500
1000
1500
2000
2500
3000
3500
1 5 10 50 100 200 400
Requests/sec
# of Threads
GET Object 10KB Throughput
Riak CS
Dragon
0
100
200
300
400
500
600
700
800
900
1000
1 5 10 50 100 200 400
Requests/sec
# of Threads
PUT Object 10KB Throughput
Riak CS
Dragon
Copyright © 2017 Yahoo Japan Corporation. All Rights Reserved.
10
Architecture
API Nodes
HTTP (S3 API)
Storage Node Storage Node Storage Node Storage Node Storage Node Storage Node
...
Storage Node Storage Node Storage Node Storage Node Storage Node Storage Node
Storage Cluster
Blob
Metadata Meta DB
Copyright © 2017 Yahoo Japan Corporation. All Rights Reserved.
11
Architecture
API Nodes
HTTP (S3 API)
Storage Node Storage Node Storage Node Storage Node Storage Node Storage Node
...
Storage Node Storage Node Storage Node Storage Node Storage Node Storage Node
Storage Cluster
Blob
Metadata Meta DB
Copyright © 2017 Yahoo Japan Corporation. All Rights Reserved.
12
Upload
API Nodes
HTTP PUT
Storage Node Storage Node Storage Node Storage Node Storage Node Storage Node
Meta DB
...
Storage Node Storage Node Storage Node Storage Node Storage Node Storage Node
格納位置を含む
オブジェクトメタデータ
HTTP PUT
Copyright © 2017 Yahoo Japan Corporation. All Rights Reserved.
13
Download
API Nodes
HTTP GET
Storage Node Storage Node Storage Node Storage Node Storage Node Storage Node
Meta DB
...
Storage Node Storage Node Storage Node Storage Node Storage Node Storage Node
Storage Cluster
格納位置を含む
オブジェクトメタデータ
HTTP GET
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
Architecture
• シンプル is ベスト
• ブラックボックスを減らす
• メタDBとしてCassandraを利用
• 十分な可用性とスケーラビリティ
• 他にもいろいろな工夫が
• 今日は省略
14
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.Copyright © 2017 Yahoo Japan Corporation. All Rights Reserved.
Go Failure Tlerance Tips:
1. Circuit Breaker
2. Timeout for Streaming
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.Copyright © 2017 Yahoo Japan Corporation. All Rights Reserved.
Go Tips 1: Circuit Breaker
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
Circuit Breaker
Storage Nodeが障害で停止・ネットワーク断の場合
• ストレージへのリクエストがコネクションタイムアウトの間ブロック
• 他ノードにフェイルオーバーするまでのレイテンシがユーザーリクエストに影響
• 落ちているノードへのリクエストは避けたい
17
API Node
Storage Nodes
数秒間ブロック数秒間ブロック
😢
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.18
Circuit Breaker
Circuit Breakerパターン
ある処理のエラー頻度が閾値をこえたら、
しばらくは処理を省略(Circuit Open)して
即座にエラーを返すパターン
タイムアウト待ちを省略してエラーを返せる
Remote Server
Success
Error!(1)
Error!(2)
Trip
Error!(3)
Circuit Open!
Circuit Breaker
Trip
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
Circuit Breaker
http://github.com/rubyist/circuitbreaker
19
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
API Node
20
Circuit Breaker
Dragonでは、Circuit Breakerを
HTTPクライアントのDialContextに適用
• 接続先アドレスのDialをCBで管理
• n回連続でDialに失敗したNodeは
Circuit Openし、一定期間Dialしない
• 即座にフォールバック可能
Storage NodesCircuit
Breakers
node1
node2
node3
node4
node5
client := http.Client{
Transport: &http.Transport{
DialContext:
(&CircuitDialer{}).DialContext,
},
}
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
type CircuitDialer struct {
mu sync.Mutex
dialer net.Dialer
breakers map[string]*circuit.Breaker
}
func (d *CircuitDialer) DialContext(ctx context.Context, network, addr string) (conn net.Conn, err error) {
d.mu.Lock()
if d.breakers == nil {
d.breakers = map[string]*circuit.Breaker{}
}
if _, ok := d.breakers[addr]; !ok {
d.breakers[addr] = circuit.NewConsecutiveBreaker(4)
}
cb := d.breakers[addr]
d.mu.Unlock()
err = cb.CallContext(ctx, func() error {
conn, err = d.dialer.DialContext(ctx, network, addr)
return err
}, 0)
return conn, err
}
Circuit Breaker
21
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
type CircuitDialer struct {
mu sync.Mutex
dialer net.Dialer
breakers map[string]*circuit.Breaker
}
func (d *CircuitDialer) DialContext(ctx context.Context, network, addr string) (conn net.Conn, err error) {
d.mu.Lock()
if d.breakers == nil {
d.breakers = map[string]*circuit.Breaker{}
}
if _, ok := d.breakers[addr]; !ok {
d.breakers[addr] = circuit.NewConsecutiveBreaker(4)
}
cb := d.breakers[addr]
d.mu.Unlock()
err = cb.CallContext(ctx, func() error {
conn, err = d.dialer.DialContext(ctx, network, addr)
return err
}, 0)
return conn, err
}
Circuit Breaker
22
接続先ごとにCircuitBreakerを用意
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
type CircuitDialer struct {
mu sync.Mutex
dialer net.Dialer
breakers map[string]*circuit.Breaker
}
func (d *CircuitDialer) DialContext(ctx context.Context, network, addr string) (conn net.Conn, err error) {
d.mu.Lock()
if d.breakers == nil {
d.breakers = map[string]*circuit.Breaker{}
}
if _, ok := d.breakers[addr]; !ok {
d.breakers[addr] = circuit.NewConsecutiveBreaker(4)
}
cb := d.breakers[addr]
d.mu.Unlock()
err = cb.CallContext(ctx, func() error {
conn, err = d.dialer.DialContext(ctx, network, addr)
return err
}, 0)
return conn, err
}
Circuit Breaker
23
接続先のCircuitBreaker
がなければ作成
接続先ごとにCircuitBreakerを用意
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
type CircuitDialer struct {
mu sync.Mutex
dialer net.Dialer
breakers map[string]*circuit.Breaker
}
func (d *CircuitDialer) DialContext(ctx context.Context, network, addr string) (conn net.Conn, err error) {
d.mu.Lock()
if d.breakers == nil {
d.breakers = map[string]*circuit.Breaker{}
}
if _, ok := d.breakers[addr]; !ok {
d.breakers[addr] = circuit.NewConsecutiveBreaker(4)
}
cb := d.breakers[addr]
d.mu.Unlock()
err = cb.CallContext(ctx, func() error {
conn, err = d.dialer.DialContext(ctx, network, addr)
return err
}, 0)
return conn, err
}
Circuit Breaker
24
接続先のCircuitBreaker
がなければ作成
DialContextにCircuitBreakerを適用
接続先ごとにCircuitBreakerを用意
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
API Node
Circuit Breaker
Circuit Breakerパターンにより、ノード障害時のリクエストレイテンシを保護
25
Storage Nodes
Circuit
Dialer
😄
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.Copyright © 2017 Yahoo Japan Corporation. All Rights Reserved.
Go Tips 2: I/O Timeout for Streaming
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
Download
27
func (s *Server) Download(w http.ResponseWriter, r *http.Request) error {
// ...
resp, err := s.HTTPClient.Get(blobURL)
if err != nil {
return err
}
defer resp.Body.Close()
_, err = io.Copy(w, resp.Body)
return err
}
バックエンドストレージに
HTTP GETリクエストを発行
ストレージからのレスポンスボディを
io.CopyでResponseWriterに転送
単純化したダウンロードハンドラ実装
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
Download
28
• io.Copy(dest io.Writer, src io.Reader)
• src (io.Reader) を dest (io.Writer) にコピーする関数
• 内部では32KBバッファ bufを確保し、
src.Read(buf), dest.Write(buf)を繰り返し呼ぶ
API Node
io.Copy
dest.Write() src.Read() GET Response.BodyResponseWriter
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
Case1: Storage Blocking on Download
29
1. もしストレージノードにNW障害やHW障害が起こると、
Response.Bodyが流れてこなくなる
2. io.Copy()内のsrc.Read()が無限にブロックする
3. ダウンロード転送が止まる!
API Node
io.Copy
dest.Write() src.Read() GET Response.BodyResponseWriter
😢
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
Case2: Client Blocking on Download
30
1. 逆に、何らかの問題で、クライアントがレスポンスのダウンロードを止めると、
ResponseWriter.Write() が無限にブロックする
2. io.Copy()が進まず、ダウンロード転送が止まる
3. リソースリーク!
API Node
io.Copy
dest.Write() src.Read() GET Response.BodyResponseWriter
😢
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
Upload
31
アップロードもio.Copyを使っている。
src: クライアントRequest.Body
dest: 3ノードへのPUTリクエストのBody(MultiWriterとPipeを経由)
API Node
PUT Request.Body
io.Copy Multi
WriterRequest.Body src.Read() dest.Write()
PUT Request.Body
PUT Request.BodyWriter – Pipe - Reader
Writer – Pipe - Reader
Writer – Pipe - Reader
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
Case3: Storage Blocking on Upload
32
API Node
PUT Request.Body
io.Copy Multi
WriterRequest.Body src.Read() dest.Write()
PUT Request.Body
PUT Request.BodyWriter – Pipe - Reader
Writer – Pipe - Reader
Writer – Pipe - Reader
1. ストレージノードに障害が起こると、リクエストBodyが送れなくなる
io.Copy()内のsrc.Read()が無限にブロックする
2. アップロード転送が止まる!
😢
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
Timeout for Stream
33
• まとめると…
• ストレージ、クライアントどちらかでデータ転送が止まると、
Read()またはWrite()が無限にブロックする
• ダウンロード、アップロードのストリームが止まったままになる
• リソースリークが起こる
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
Timeout for Stream
34
• なんとかしてI/Oのブロックを検知して、
タイムアウトエラーとしてハンドリングしたい
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
Timeout for Stream
35
• net.Conn.SetDeadline() ?
• net.ConnのRead(),Write()に時間制限を指定する機能
• http.ServeHTTPはクライアントのnet.Connにアクセスできない
• http.TimeoutHandler ?
• データサイズやユーザーの通信帯域がバラバラなので
固定のタイムアウト値が設定できない
• サイズ:1Byte〜5GB、帯域:100Kbps 〜 10Gbps
• The complete guide to Go net/http timeouts
• https://blog.cloudflare.com/the-complete-guide-to-golang-net-http-timeouts/
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
Our approach
36
• タイムアウト機能付きの io.Reader, io.Writerを実装して、
すべてのストリーム経路に仕掛ける
Request
.Body
Request
.Body
API Node
io.Copy GET Response.BodyResponseWriter
io.CopyRequest.Body
Request
.Body
Writer – Pipe - Reader
Writer – Pipe - Reader
Writer – Pipe - Reader
Multi
Writer
On Download
On Upload
Timeout
Writer
Timeout
Writer
Timeout
Writer
Timeout
Writer
Timeout
Reader
Timeout
Reader
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
TimeoutWriter/Reader
• Write()がTimeout時間で完了しなかったら関数 Fn が実行されるWriteラッパー
• シンプル!
• TimeoutReaderも同様に定義
37
type TimeoutWriter struct {
W io.Writer
Timeout time.Duration
Fn func()
}
func (w *TimeoutWriter) Write(p []byte) (int, error) {
timer := time.AfterFunc(w.Timeout, w.Fn)
defer timer.Stop()
return w.W.Write(p)
}
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
Timeout for Streaming
38
func (s *Server) Download(w http.ResponseWriter, r *http.Request) error {
// ...
blob, _ := s.GetBlobStream(ctx, object, byteRange)
n, err := io.Copy(w,blob)
return err
}
適用前
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
Timeout for Streaming
39
func (s *Server) Download(w http.ResponseWriter, r *http.Request) error {
// ...
blob, _ := s.GetBlobStream(ctx, object, byteRange)
timeoutCh := make(chan struct{}, 1)
resultCh := make(chan resultAndError, 1)
go func() {
tw := TimeoutWriter{
W: w,
Timeout: 10 * time.Second,
Fn: func() { timeoutCh <- struct{}{} },
}
n, err := io.Copy(tw,blob)
resultCh <- resultAndError{n:n, err:err}
}()
select {
case <-timeoutCh:
return RequestTimeoutError
case result := <-resultCh:
return result.err
}
}
Copyを別Goroutineに
適用後
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
Timeout for Streaming
40
func (s *Server) Download(w http.ResponseWriter, r *http.Request) error {
// ...
blob, _ := s.GetBlobStream(ctx, object, byteRange)
timeoutCh := make(chan struct{}, 1)
resultCh := make(chan resultAndError, 1)
go func() {
tw := TimeoutWriter{
W: w,
Timeout: 10 * time.Second,
Fn: func() { timeoutCh <- struct{}{} },
}
n, err := io.Copy(tw,blob)
resultCh <- resultAndError{n:n, err:err}
}()
select {
case <-timeoutCh:
return RequestTimeoutError
case result := <-resultCh:
return result.err
}
}
ResponseWriterを
TimeoutWriterでラップ。
io.Copyのdestをtwに
適用後
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
Timeout for Streaming
41
func (s *Server) Download(w http.ResponseWriter, r *http.Request) error {
// ...
blob, _ := s.GetBlobStream(ctx, object, byteRange)
timeoutCh := make(chan struct{}, 1)
resultCh := make(chan resultAndError, 1)
go func() {
tw := TimeoutWriter{
W: w,
Timeout: 10 * time.Second,
Fn: func() { timeoutCh <- struct{}{} },
}
n, err := io.Copy(tw,blob)
resultCh <- resultAndError{n:n, err:err}
}()
select {
case <-timeoutCh:
return RequestTimeoutError
case result := <-resultCh:
return result.err
}
}
Writeが10秒間ブロックしたら
timeoutChに送信
適用後
ServeHTTPを抜けると、
wはClose()してCopyはエラーに
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
Timeout for Streaming
42
func (s *Server) Download(w http.ResponseWriter, r *http.Request) error {
// ...
blob, _ := s.GetBlobStream(ctx, object, byteRange)
timeoutCh := make(chan struct{}, 1)
resultCh := make(chan resultAndError, 1)
go func() {
tw := TimeoutWriter{
W: w,
Timeout: 10 * time.Second,
Fn: func() { timeoutCh <- struct{}{} },
}
n, err := io.Copy(tw,blob)
resultCh <- resultAndError{n:n, err:err}
}()
select {
case <-timeoutCh:
return RequestTimeoutError
case result := <-resultCh:
return result.err
}
}
io.Copyが終了したら
resultChに送信
適用後
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
Performance Impact?
43
• io.Read(), io.Write()のタイムアウトをシンプルな実装でハンドルできた😄
• でも遅いんでしょう?
• すべてのRead()/Write()にタイマーを仕掛けるなんて…
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
Performance Impact?
44
性能インパクトは僅少
• 100KB ダウンロード スループット: -2% 〜 0%
• 100KB アップロード スループット: +3% 〜 -5%
0
2000
4000
6000
8000
10000
12000
20 50 100 200 400 800
Requests/sec
# of Threads
GET Object 100KB Throughput
No Timeout
Timeout
0
500
1000
1500
2000
2500
3000
3500
4000
20 50 100 200 400 800
Requests/sec
# of Threads
PUT Object 100KB Throughput
No Timeout
Timeout
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
Go Failure Tlerance Tips
45
大規模な分散システムに要求される耐障害性をシンプルに実装
• CircuitBreaker
• Timeout Read/Write
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.Copyright © 2017 Yahoo Japan Corporation. All Rights Reserved.
Conclusion
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
Conclusion
• ヤフーではGoで大規模な分散オブジェクト
ストレージDragonを開発・運用中です
• サービス基盤のモダン化を進行中
• We’re Hiring
• Thank you!
47

More Related Content

What's hot

マイクロにしすぎた結果がこれだよ!
マイクロにしすぎた結果がこれだよ!マイクロにしすぎた結果がこれだよ!
マイクロにしすぎた結果がこれだよ!mosa siru
 
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Kohei Tokunaga
 
開発速度が速い #とは(LayerX社内資料)
開発速度が速い #とは(LayerX社内資料)開発速度が速い #とは(LayerX社内資料)
開発速度が速い #とは(LayerX社内資料)mosa siru
 
目grep入門 +解説
目grep入門 +解説目grep入門 +解説
目grep入門 +解説murachue
 
Twitterのsnowflakeについて
TwitterのsnowflakeについてTwitterのsnowflakeについて
Twitterのsnowflakeについてmoai kids
 
マイクロサービスバックエンドAPIのためのRESTとgRPC
マイクロサービスバックエンドAPIのためのRESTとgRPCマイクロサービスバックエンドAPIのためのRESTとgRPC
マイクロサービスバックエンドAPIのためのRESTとgRPCdisc99_
 
マイクロサービス時代の認証と認可 - AWS Dev Day Tokyo 2018 #AWSDevDay
マイクロサービス時代の認証と認可 - AWS Dev Day Tokyo 2018 #AWSDevDayマイクロサービス時代の認証と認可 - AWS Dev Day Tokyo 2018 #AWSDevDay
マイクロサービス時代の認証と認可 - AWS Dev Day Tokyo 2018 #AWSDevDay都元ダイスケ Miyamoto
 
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)Takuto Wada
 
ドメイン駆動設計 本格入門
ドメイン駆動設計 本格入門ドメイン駆動設計 本格入門
ドメイン駆動設計 本格入門増田 亨
 
イミュータブルデータモデル(入門編)
イミュータブルデータモデル(入門編)イミュータブルデータモデル(入門編)
イミュータブルデータモデル(入門編)Yoshitaka Kawashima
 
ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方増田 亨
 
WebSocketのキホン
WebSocketのキホンWebSocketのキホン
WebSocketのキホンYou_Kinjoh
 
ドメイン駆動設計のためのオブジェクト指向入門
ドメイン駆動設計のためのオブジェクト指向入門ドメイン駆動設計のためのオブジェクト指向入門
ドメイン駆動設計のためのオブジェクト指向入門増田 亨
 
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話Koichiro Matsuoka
 
ユーザーストーリー駆動開発で行こう。
ユーザーストーリー駆動開発で行こう。ユーザーストーリー駆動開発で行こう。
ユーザーストーリー駆動開発で行こう。toshihiro ichitani
 
3層アーキテクチャとMVCモデル -LaravelにおけるMVCモデルの流れ-
 3層アーキテクチャとMVCモデル -LaravelにおけるMVCモデルの流れ- 3層アーキテクチャとMVCモデル -LaravelにおけるMVCモデルの流れ-
3層アーキテクチャとMVCモデル -LaravelにおけるMVCモデルの流れ-yoshitaro yoyo
 
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)NTT DATA Technology & Innovation
 
DDDのモデリングとは何なのか、 そしてどうコードに落とすのか
DDDのモデリングとは何なのか、 そしてどうコードに落とすのかDDDのモデリングとは何なのか、 そしてどうコードに落とすのか
DDDのモデリングとは何なのか、 そしてどうコードに落とすのかKoichiro Matsuoka
 

What's hot (20)

マイクロにしすぎた結果がこれだよ!
マイクロにしすぎた結果がこれだよ!マイクロにしすぎた結果がこれだよ!
マイクロにしすぎた結果がこれだよ!
 
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Dockerからcontainerdへの移行
Dockerからcontainerdへの移行
 
開発速度が速い #とは(LayerX社内資料)
開発速度が速い #とは(LayerX社内資料)開発速度が速い #とは(LayerX社内資料)
開発速度が速い #とは(LayerX社内資料)
 
目grep入門 +解説
目grep入門 +解説目grep入門 +解説
目grep入門 +解説
 
Twitterのsnowflakeについて
TwitterのsnowflakeについてTwitterのsnowflakeについて
Twitterのsnowflakeについて
 
マイクロサービスバックエンドAPIのためのRESTとgRPC
マイクロサービスバックエンドAPIのためのRESTとgRPCマイクロサービスバックエンドAPIのためのRESTとgRPC
マイクロサービスバックエンドAPIのためのRESTとgRPC
 
マイクロサービス時代の認証と認可 - AWS Dev Day Tokyo 2018 #AWSDevDay
マイクロサービス時代の認証と認可 - AWS Dev Day Tokyo 2018 #AWSDevDayマイクロサービス時代の認証と認可 - AWS Dev Day Tokyo 2018 #AWSDevDay
マイクロサービス時代の認証と認可 - AWS Dev Day Tokyo 2018 #AWSDevDay
 
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
 
OAuth 2.0のResource Serverの作り方
OAuth 2.0のResource Serverの作り方OAuth 2.0のResource Serverの作り方
OAuth 2.0のResource Serverの作り方
 
ドメイン駆動設計 本格入門
ドメイン駆動設計 本格入門ドメイン駆動設計 本格入門
ドメイン駆動設計 本格入門
 
イミュータブルデータモデル(入門編)
イミュータブルデータモデル(入門編)イミュータブルデータモデル(入門編)
イミュータブルデータモデル(入門編)
 
ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方
 
WebSocketのキホン
WebSocketのキホンWebSocketのキホン
WebSocketのキホン
 
ドメイン駆動設計のためのオブジェクト指向入門
ドメイン駆動設計のためのオブジェクト指向入門ドメイン駆動設計のためのオブジェクト指向入門
ドメイン駆動設計のためのオブジェクト指向入門
 
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
 
ユーザーストーリー駆動開発で行こう。
ユーザーストーリー駆動開発で行こう。ユーザーストーリー駆動開発で行こう。
ユーザーストーリー駆動開発で行こう。
 
3層アーキテクチャとMVCモデル -LaravelにおけるMVCモデルの流れ-
 3層アーキテクチャとMVCモデル -LaravelにおけるMVCモデルの流れ- 3層アーキテクチャとMVCモデル -LaravelにおけるMVCモデルの流れ-
3層アーキテクチャとMVCモデル -LaravelにおけるMVCモデルの流れ-
 
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
 
分散トレーシング技術について(Open tracingやjaeger)
分散トレーシング技術について(Open tracingやjaeger)分散トレーシング技術について(Open tracingやjaeger)
分散トレーシング技術について(Open tracingやjaeger)
 
DDDのモデリングとは何なのか、 そしてどうコードに落とすのか
DDDのモデリングとは何なのか、 そしてどうコードに落とすのかDDDのモデリングとは何なのか、 そしてどうコードに落とすのか
DDDのモデリングとは何なのか、 そしてどうコードに落とすのか
 

Viewers also liked

Goをカンストさせる話
Goをカンストさせる話Goをカンストさせる話
Goをカンストさせる話Moriyoshi Koizumi
 
My client wanted their apps synced, and I made it with Go
My client wanted their apps synced, and I made it with GoMy client wanted their apps synced, and I made it with Go
My client wanted their apps synced, and I made it with GoToru Furukawa
 
Coding in the context era
Coding in the context eraCoding in the context era
Coding in the context eralestrrat
 
Go conference 2017 Lightning talk
Go conference 2017 Lightning talkGo conference 2017 Lightning talk
Go conference 2017 Lightning talkmokelab
 
20171105 go con2017_lt
20171105 go con2017_lt20171105 go con2017_lt
20171105 go con2017_ltKeigo Suda
 
Gocon2017:Goのロギング周りの考察
Gocon2017:Goのロギング周りの考察Gocon2017:Goのロギング周りの考察
Gocon2017:Goのロギング周りの考察貴仁 大和屋
 
GOCON Autumn (Story of our own Monitoring Agent in golang)
GOCON Autumn (Story of our own Monitoring Agent in golang)GOCON Autumn (Story of our own Monitoring Agent in golang)
GOCON Autumn (Story of our own Monitoring Agent in golang)Huy Do
 
条件式評価器の実装による管理ツールの抽象化
条件式評価器の実装による管理ツールの抽象化条件式評価器の実装による管理ツールの抽象化
条件式評価器の実装による管理ツールの抽象化Takuya Ueda
 

Viewers also liked (9)

Goをカンストさせる話
Goをカンストさせる話Goをカンストさせる話
Goをカンストさせる話
 
My client wanted their apps synced, and I made it with Go
My client wanted their apps synced, and I made it with GoMy client wanted their apps synced, and I made it with Go
My client wanted their apps synced, and I made it with Go
 
go 1.8 net/http timeouts
go 1.8 net/http timeoutsgo 1.8 net/http timeouts
go 1.8 net/http timeouts
 
Coding in the context era
Coding in the context eraCoding in the context era
Coding in the context era
 
Go conference 2017 Lightning talk
Go conference 2017 Lightning talkGo conference 2017 Lightning talk
Go conference 2017 Lightning talk
 
20171105 go con2017_lt
20171105 go con2017_lt20171105 go con2017_lt
20171105 go con2017_lt
 
Gocon2017:Goのロギング周りの考察
Gocon2017:Goのロギング周りの考察Gocon2017:Goのロギング周りの考察
Gocon2017:Goのロギング周りの考察
 
GOCON Autumn (Story of our own Monitoring Agent in golang)
GOCON Autumn (Story of our own Monitoring Agent in golang)GOCON Autumn (Story of our own Monitoring Agent in golang)
GOCON Autumn (Story of our own Monitoring Agent in golang)
 
条件式評価器の実装による管理ツールの抽象化
条件式評価器の実装による管理ツールの抽象化条件式評価器の実装による管理ツールの抽象化
条件式評価器の実装による管理ツールの抽象化
 

Similar to Goでヤフーの分散オブジェクトストレージを作った話 Go Conference 2017 Spring

FluentdとRedshiftの素敵な関係
FluentdとRedshiftの素敵な関係FluentdとRedshiftの素敵な関係
FluentdとRedshiftの素敵な関係moai kids
 
AWS SDK for Smalltalk
AWS SDK for SmalltalkAWS SDK for Smalltalk
AWS SDK for SmalltalkSho Yoshida
 
Dataworks Summit 2017 SanJose StreamProcessing - Hadoop Source Code Reading #...
Dataworks Summit 2017 SanJose StreamProcessing - Hadoop Source Code Reading #...Dataworks Summit 2017 SanJose StreamProcessing - Hadoop Source Code Reading #...
Dataworks Summit 2017 SanJose StreamProcessing - Hadoop Source Code Reading #...Yahoo!デベロッパーネットワーク
 
Inside mobage platform
Inside mobage platformInside mobage platform
Inside mobage platformToru Yamaguchi
 
Microsoft open tech night 2020 feb18
Microsoft open tech night 2020 feb18Microsoft open tech night 2020 feb18
Microsoft open tech night 2020 feb18Masatomo Ito
 
Network as a Service - Data plane evolution and abstraction by NSM
Network as a Service - Data plane evolution and abstraction by NSMNetwork as a Service - Data plane evolution and abstraction by NSM
Network as a Service - Data plane evolution and abstraction by NSMMiya Kohno
 
Dockerの利用事例
Dockerの利用事例Dockerの利用事例
Dockerの利用事例maebashi
 
Tech summit 2018_ad15_ver_1106
Tech summit 2018_ad15_ver_1106Tech summit 2018_ad15_ver_1106
Tech summit 2018_ad15_ver_1106Shotaro Suzuki
 
泥臭い運用から、プログラマブルインフラ構築(に行きたい)
泥臭い運用から、プログラマブルインフラ構築(に行きたい) 泥臭い運用から、プログラマブルインフラ構築(に行きたい)
泥臭い運用から、プログラマブルインフラ構築(に行きたい) Akihiro Kuwano
 
Node.jsアプリの開発をモダン化するために取り組んできたこと
Node.jsアプリの開発をモダン化するために取り組んできたことNode.jsアプリの開発をモダン化するために取り組んできたこと
Node.jsアプリの開発をモダン化するために取り組んできたことbitbank, Inc. Tokyo, Japan
 
Python におけるドメイン駆動設計(戦術面)の勘どころ
Python におけるドメイン駆動設計(戦術面)の勘どころPython におけるドメイン駆動設計(戦術面)の勘どころ
Python におけるドメイン駆動設計(戦術面)の勘どころJunya Hayashi
 
QoS for ROS 2 Dashing/Eloquent
QoS for ROS 2 Dashing/EloquentQoS for ROS 2 Dashing/Eloquent
QoS for ROS 2 Dashing/EloquentHideki Takase
 
成長を加速する minne の技術基盤戦略
成長を加速する minne の技術基盤戦略成長を加速する minne の技術基盤戦略
成長を加速する minne の技術基盤戦略Hiroshi SHIBATA
 
Airflowを広告データのワークフローエンジンとして運用してみた話
Airflowを広告データのワークフローエンジンとして運用してみた話Airflowを広告データのワークフローエンジンとして運用してみた話
Airflowを広告データのワークフローエンジンとして運用してみた話Katsunori Kanda
 
サーバーレスで ガチ本番運用までやってるお話し
サーバーレスで ガチ本番運用までやってるお話しサーバーレスで ガチ本番運用までやってるお話し
サーバーレスで ガチ本番運用までやってるお話しAkira Nagata
 
DockerCon参加報告 (`docker build`が30倍以上速くなる話など)
DockerCon参加報告 (`docker build`が30倍以上速くなる話など)DockerCon参加報告 (`docker build`が30倍以上速くなる話など)
DockerCon参加報告 (`docker build`が30倍以上速くなる話など)Akihiro Suda
 
drecomにおけるwinning the metrics battle
drecomにおけるwinning the metrics battledrecomにおけるwinning the metrics battle
drecomにおけるwinning the metrics battleMitsuki Kenichi
 

Similar to Goでヤフーの分散オブジェクトストレージを作った話 Go Conference 2017 Spring (20)

FluentdとRedshiftの素敵な関係
FluentdとRedshiftの素敵な関係FluentdとRedshiftの素敵な関係
FluentdとRedshiftの素敵な関係
 
AWS SDK for Smalltalk
AWS SDK for SmalltalkAWS SDK for Smalltalk
AWS SDK for Smalltalk
 
activerecord-turntable
activerecord-turntableactiverecord-turntable
activerecord-turntable
 
Dataworks Summit 2017 SanJose StreamProcessing - Hadoop Source Code Reading #...
Dataworks Summit 2017 SanJose StreamProcessing - Hadoop Source Code Reading #...Dataworks Summit 2017 SanJose StreamProcessing - Hadoop Source Code Reading #...
Dataworks Summit 2017 SanJose StreamProcessing - Hadoop Source Code Reading #...
 
Inside mobage platform
Inside mobage platformInside mobage platform
Inside mobage platform
 
Spring Boot on Kubernetes : Yahoo!ズバトク事例 #jjug_ccc
Spring Boot on Kubernetes : Yahoo!ズバトク事例 #jjug_cccSpring Boot on Kubernetes : Yahoo!ズバトク事例 #jjug_ccc
Spring Boot on Kubernetes : Yahoo!ズバトク事例 #jjug_ccc
 
DBpedia Japanese
DBpedia JapaneseDBpedia Japanese
DBpedia Japanese
 
Microsoft open tech night 2020 feb18
Microsoft open tech night 2020 feb18Microsoft open tech night 2020 feb18
Microsoft open tech night 2020 feb18
 
Network as a Service - Data plane evolution and abstraction by NSM
Network as a Service - Data plane evolution and abstraction by NSMNetwork as a Service - Data plane evolution and abstraction by NSM
Network as a Service - Data plane evolution and abstraction by NSM
 
Dockerの利用事例
Dockerの利用事例Dockerの利用事例
Dockerの利用事例
 
Tech summit 2018_ad15_ver_1106
Tech summit 2018_ad15_ver_1106Tech summit 2018_ad15_ver_1106
Tech summit 2018_ad15_ver_1106
 
泥臭い運用から、プログラマブルインフラ構築(に行きたい)
泥臭い運用から、プログラマブルインフラ構築(に行きたい) 泥臭い運用から、プログラマブルインフラ構築(に行きたい)
泥臭い運用から、プログラマブルインフラ構築(に行きたい)
 
Node.jsアプリの開発をモダン化するために取り組んできたこと
Node.jsアプリの開発をモダン化するために取り組んできたことNode.jsアプリの開発をモダン化するために取り組んできたこと
Node.jsアプリの開発をモダン化するために取り組んできたこと
 
Python におけるドメイン駆動設計(戦術面)の勘どころ
Python におけるドメイン駆動設計(戦術面)の勘どころPython におけるドメイン駆動設計(戦術面)の勘どころ
Python におけるドメイン駆動設計(戦術面)の勘どころ
 
QoS for ROS 2 Dashing/Eloquent
QoS for ROS 2 Dashing/EloquentQoS for ROS 2 Dashing/Eloquent
QoS for ROS 2 Dashing/Eloquent
 
成長を加速する minne の技術基盤戦略
成長を加速する minne の技術基盤戦略成長を加速する minne の技術基盤戦略
成長を加速する minne の技術基盤戦略
 
Airflowを広告データのワークフローエンジンとして運用してみた話
Airflowを広告データのワークフローエンジンとして運用してみた話Airflowを広告データのワークフローエンジンとして運用してみた話
Airflowを広告データのワークフローエンジンとして運用してみた話
 
サーバーレスで ガチ本番運用までやってるお話し
サーバーレスで ガチ本番運用までやってるお話しサーバーレスで ガチ本番運用までやってるお話し
サーバーレスで ガチ本番運用までやってるお話し
 
DockerCon参加報告 (`docker build`が30倍以上速くなる話など)
DockerCon参加報告 (`docker build`が30倍以上速くなる話など)DockerCon参加報告 (`docker build`が30倍以上速くなる話など)
DockerCon参加報告 (`docker build`が30倍以上速くなる話など)
 
drecomにおけるwinning the metrics battle
drecomにおけるwinning the metrics battledrecomにおけるwinning the metrics battle
drecomにおけるwinning the metrics battle
 

More from Yahoo!デベロッパーネットワーク

ヤフーでは開発迅速性と品質のバランスをどう取ってるか
ヤフーでは開発迅速性と品質のバランスをどう取ってるかヤフーでは開発迅速性と品質のバランスをどう取ってるか
ヤフーでは開発迅速性と品質のバランスをどう取ってるかYahoo!デベロッパーネットワーク
 
データの価値を最大化させるためのデザイン~データビジュアライゼーションの方法~ #devsumi 17-E-2
データの価値を最大化させるためのデザイン~データビジュアライゼーションの方法~ #devsumi 17-E-2データの価値を最大化させるためのデザイン~データビジュアライゼーションの方法~ #devsumi 17-E-2
データの価値を最大化させるためのデザイン~データビジュアライゼーションの方法~ #devsumi 17-E-2Yahoo!デベロッパーネットワーク
 
ヤフーを支えるセキュリティ ~サイバー攻撃を防ぐエンジニアの仕事とは~ #yjtc
ヤフーを支えるセキュリティ ~サイバー攻撃を防ぐエンジニアの仕事とは~ #yjtcヤフーを支えるセキュリティ ~サイバー攻撃を防ぐエンジニアの仕事とは~ #yjtc
ヤフーを支えるセキュリティ ~サイバー攻撃を防ぐエンジニアの仕事とは~ #yjtcYahoo!デベロッパーネットワーク
 
Yahoo! JAPANのIaaSを支えるKubernetesクラスタ、アップデート自動化への挑戦 #yjtc
Yahoo! JAPANのIaaSを支えるKubernetesクラスタ、アップデート自動化への挑戦 #yjtcYahoo! JAPANのIaaSを支えるKubernetesクラスタ、アップデート自動化への挑戦 #yjtc
Yahoo! JAPANのIaaSを支えるKubernetesクラスタ、アップデート自動化への挑戦 #yjtcYahoo!デベロッパーネットワーク
 
ヤフーのAIプラットフォーム紹介 ~AIテックカンパニーを支えるデータ基盤~ #yjtc
ヤフーのAIプラットフォーム紹介 ~AIテックカンパニーを支えるデータ基盤~ #yjtcヤフーのAIプラットフォーム紹介 ~AIテックカンパニーを支えるデータ基盤~ #yjtc
ヤフーのAIプラットフォーム紹介 ~AIテックカンパニーを支えるデータ基盤~ #yjtcYahoo!デベロッパーネットワーク
 
新技術を使った次世代の商品の見せ方 ~ヤフオク!のマルチビュー機能~ #yjtc
新技術を使った次世代の商品の見せ方 ~ヤフオク!のマルチビュー機能~ #yjtc新技術を使った次世代の商品の見せ方 ~ヤフオク!のマルチビュー機能~ #yjtc
新技術を使った次世代の商品の見せ方 ~ヤフオク!のマルチビュー機能~ #yjtcYahoo!デベロッパーネットワーク
 
PC版Yahoo!メールリニューアル ~サービスのUI/UX統合と改善プロセス~ #yjtc
PC版Yahoo!メールリニューアル ~サービスのUI/UX統合と改善プロセス~ #yjtcPC版Yahoo!メールリニューアル ~サービスのUI/UX統合と改善プロセス~ #yjtc
PC版Yahoo!メールリニューアル ~サービスのUI/UX統合と改善プロセス~ #yjtcYahoo!デベロッパーネットワーク
 
モブデザインによる多職種チームのコミュニケーション改善 #yjtc
モブデザインによる多職種チームのコミュニケーション改善 #yjtcモブデザインによる多職種チームのコミュニケーション改善 #yjtc
モブデザインによる多職種チームのコミュニケーション改善 #yjtcYahoo!デベロッパーネットワーク
 
ユーザーの地域を考慮した検索入力補助機能の改善の試み #yjtc
ユーザーの地域を考慮した検索入力補助機能の改善の試み #yjtcユーザーの地域を考慮した検索入力補助機能の改善の試み #yjtc
ユーザーの地域を考慮した検索入力補助機能の改善の試み #yjtcYahoo!デベロッパーネットワーク
 

More from Yahoo!デベロッパーネットワーク (20)

ゼロから始める転移学習
ゼロから始める転移学習ゼロから始める転移学習
ゼロから始める転移学習
 
継続的なモデルモニタリングを実現するKubernetes Operator
継続的なモデルモニタリングを実現するKubernetes Operator継続的なモデルモニタリングを実現するKubernetes Operator
継続的なモデルモニタリングを実現するKubernetes Operator
 
ヤフーでは開発迅速性と品質のバランスをどう取ってるか
ヤフーでは開発迅速性と品質のバランスをどう取ってるかヤフーでは開発迅速性と品質のバランスをどう取ってるか
ヤフーでは開発迅速性と品質のバランスをどう取ってるか
 
オンプレML基盤on Kubernetes パネルディスカッション
オンプレML基盤on Kubernetes パネルディスカッションオンプレML基盤on Kubernetes パネルディスカッション
オンプレML基盤on Kubernetes パネルディスカッション
 
LakeTahoe
LakeTahoeLakeTahoe
LakeTahoe
 
オンプレML基盤on Kubernetes 〜Yahoo! JAPAN AIPF〜
オンプレML基盤on Kubernetes 〜Yahoo! JAPAN AIPF〜オンプレML基盤on Kubernetes 〜Yahoo! JAPAN AIPF〜
オンプレML基盤on Kubernetes 〜Yahoo! JAPAN AIPF〜
 
Persistent-memory-native Database High-availability Feature
Persistent-memory-native Database High-availability FeaturePersistent-memory-native Database High-availability Feature
Persistent-memory-native Database High-availability Feature
 
データの価値を最大化させるためのデザイン~データビジュアライゼーションの方法~ #devsumi 17-E-2
データの価値を最大化させるためのデザイン~データビジュアライゼーションの方法~ #devsumi 17-E-2データの価値を最大化させるためのデザイン~データビジュアライゼーションの方法~ #devsumi 17-E-2
データの価値を最大化させるためのデザイン~データビジュアライゼーションの方法~ #devsumi 17-E-2
 
eコマースと実店舗の相互利益を目指したデザイン #yjtc
eコマースと実店舗の相互利益を目指したデザイン #yjtceコマースと実店舗の相互利益を目指したデザイン #yjtc
eコマースと実店舗の相互利益を目指したデザイン #yjtc
 
ヤフーを支えるセキュリティ ~サイバー攻撃を防ぐエンジニアの仕事とは~ #yjtc
ヤフーを支えるセキュリティ ~サイバー攻撃を防ぐエンジニアの仕事とは~ #yjtcヤフーを支えるセキュリティ ~サイバー攻撃を防ぐエンジニアの仕事とは~ #yjtc
ヤフーを支えるセキュリティ ~サイバー攻撃を防ぐエンジニアの仕事とは~ #yjtc
 
Yahoo! JAPANのIaaSを支えるKubernetesクラスタ、アップデート自動化への挑戦 #yjtc
Yahoo! JAPANのIaaSを支えるKubernetesクラスタ、アップデート自動化への挑戦 #yjtcYahoo! JAPANのIaaSを支えるKubernetesクラスタ、アップデート自動化への挑戦 #yjtc
Yahoo! JAPANのIaaSを支えるKubernetesクラスタ、アップデート自動化への挑戦 #yjtc
 
ビッグデータから人々のムードを捉える #yjtc
ビッグデータから人々のムードを捉える #yjtcビッグデータから人々のムードを捉える #yjtc
ビッグデータから人々のムードを捉える #yjtc
 
サイエンス領域におけるMLOpsの取り組み #yjtc
サイエンス領域におけるMLOpsの取り組み #yjtcサイエンス領域におけるMLOpsの取り組み #yjtc
サイエンス領域におけるMLOpsの取り組み #yjtc
 
ヤフーのAIプラットフォーム紹介 ~AIテックカンパニーを支えるデータ基盤~ #yjtc
ヤフーのAIプラットフォーム紹介 ~AIテックカンパニーを支えるデータ基盤~ #yjtcヤフーのAIプラットフォーム紹介 ~AIテックカンパニーを支えるデータ基盤~ #yjtc
ヤフーのAIプラットフォーム紹介 ~AIテックカンパニーを支えるデータ基盤~ #yjtc
 
Yahoo! JAPAN Tech Conference 2022 Day2 Keynote #yjtc
Yahoo! JAPAN Tech Conference 2022 Day2 Keynote #yjtcYahoo! JAPAN Tech Conference 2022 Day2 Keynote #yjtc
Yahoo! JAPAN Tech Conference 2022 Day2 Keynote #yjtc
 
新技術を使った次世代の商品の見せ方 ~ヤフオク!のマルチビュー機能~ #yjtc
新技術を使った次世代の商品の見せ方 ~ヤフオク!のマルチビュー機能~ #yjtc新技術を使った次世代の商品の見せ方 ~ヤフオク!のマルチビュー機能~ #yjtc
新技術を使った次世代の商品の見せ方 ~ヤフオク!のマルチビュー機能~ #yjtc
 
PC版Yahoo!メールリニューアル ~サービスのUI/UX統合と改善プロセス~ #yjtc
PC版Yahoo!メールリニューアル ~サービスのUI/UX統合と改善プロセス~ #yjtcPC版Yahoo!メールリニューアル ~サービスのUI/UX統合と改善プロセス~ #yjtc
PC版Yahoo!メールリニューアル ~サービスのUI/UX統合と改善プロセス~ #yjtc
 
モブデザインによる多職種チームのコミュニケーション改善 #yjtc
モブデザインによる多職種チームのコミュニケーション改善 #yjtcモブデザインによる多職種チームのコミュニケーション改善 #yjtc
モブデザインによる多職種チームのコミュニケーション改善 #yjtc
 
「新しいおうち探し」のためのAIアシスト検索 #yjtc
「新しいおうち探し」のためのAIアシスト検索 #yjtc「新しいおうち探し」のためのAIアシスト検索 #yjtc
「新しいおうち探し」のためのAIアシスト検索 #yjtc
 
ユーザーの地域を考慮した検索入力補助機能の改善の試み #yjtc
ユーザーの地域を考慮した検索入力補助機能の改善の試み #yjtcユーザーの地域を考慮した検索入力補助機能の改善の試み #yjtc
ユーザーの地域を考慮した検索入力補助機能の改善の試み #yjtc
 

Recently uploaded

2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~arts yokohama
 
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見Shumpei Kishi
 
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-LoopへTetsuya Nihonmatsu
 
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法ssuser370dd7
 
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdf
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdfTaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdf
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdfMatsushita Laboratory
 
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)ssuser539845
 
20240326_IoTLT_vol109_kitazaki_v1___.pdf
20240326_IoTLT_vol109_kitazaki_v1___.pdf20240326_IoTLT_vol109_kitazaki_v1___.pdf
20240326_IoTLT_vol109_kitazaki_v1___.pdfAyachika Kitazaki
 
2024 01 Virtual_Counselor
2024 01 Virtual_Counselor 2024 01 Virtual_Counselor
2024 01 Virtual_Counselor arts yokohama
 

Recently uploaded (11)

2024 03 CTEA
2024 03 CTEA2024 03 CTEA
2024 03 CTEA
 
What is the world where you can make your own semiconductors?
What is the world where you can make your own semiconductors?What is the world where you can make your own semiconductors?
What is the world where you can make your own semiconductors?
 
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~
 
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見
 
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ
 
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法
 
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdf
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdfTaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdf
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdf
 
2024 04 minnanoito
2024 04 minnanoito2024 04 minnanoito
2024 04 minnanoito
 
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)
 
20240326_IoTLT_vol109_kitazaki_v1___.pdf
20240326_IoTLT_vol109_kitazaki_v1___.pdf20240326_IoTLT_vol109_kitazaki_v1___.pdf
20240326_IoTLT_vol109_kitazaki_v1___.pdf
 
2024 01 Virtual_Counselor
2024 01 Virtual_Counselor 2024 01 Virtual_Counselor
2024 01 Virtual_Counselor
 

Goでヤフーの分散オブジェクトストレージを作った話 Go Conference 2017 Spring

  • 1. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved. Yasuharu GOTO (@ono_matope) 2017/03/25 Goでヤフーの分散オブジェクトストレージを作った話 Go Conference 2017 Spring
  • 2. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved. About me 名前: Yasuharu GOTO Twitter: @ono_matope Github: @matope 所属: ヤフー株式会社 データプラットフォーム開発本部 Go歴:3年 コントリビューション: Expect:100-Continueのクライアント実装 (Go1.6) 2
  • 3. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved. Agenda • Goでヤフーの基盤ストレージ Dragon を作った話 • Goでの耐障害性向上テクニック 3
  • 4. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.Copyright © 2017 Yahoo Japan Corporation. All Rights Reserved. Dragon
  • 5. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved. Dragon • ヤフーで開発している分散オブジェクトストレージ • デザインゴール:高速、高スケーラビリティ、高可用性、低コスト • Go言語 • S3 互換 API • 2016年1月 リリース (14ヶ月の本番稼働実績) 5
  • 6. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved. Why we built a new Object Storage? 6 • Octagon(2011-) • 最初の内製オブジェクトストレージ • 諸々の技術的課題から、代替を検討 • 遅い・不安定・運用しづらい・レガシー・etc... • 既存のOSS? • Riak CS : 一部で導入するも、性能がサービス要件を満たさず • OpenStack Swift : スケーラビリティに不安 • パブリッククラウド? • 自社DCと比べてコスト面で不利
  • 7. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved. Why we built a new Object Storage? 7 じゃあ作ろう 2014年 実装スタート
  • 8. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.8 クラスタ数: 2 格納オブジェクト数: 100億 格納データ量: 9PB サービス利用多数(右) その他社内システム多数 Presto (in experiment) 利用規模 Yahoo!オークション (画像) Yahoo!ニュース・トピックス/個人 (画像) Yahoo!ディスプレイアドネットワーク (画像/動画) Yahoo!ブログ (画像) Yahoo!スマホきせかえ (画像) Yahoo!トラベル (画像) Yahoo!不動産 (画像) Yahoo!知恵袋 (画像) Yahoo!飲食店予約 (画像) Yahoo!みんなの政治 (画像) Yahoo!ゲーム (コンテンツ) Yahoo!ブックストア (コンテンツ) Yahoo!ボックス (データ) ネタりか (記事画像) etc...
  • 9. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved. Performance (with Riak CS/参考値) • Dragon: API*1, Storage*1,Cassandra*3 • Riak CS: haproxy*1, stanchion*1, Riak (KV+CS)*3 • CassandraとStanchion以外はすべて同一構成のHWを使用。 9 0 500 1000 1500 2000 2500 3000 3500 1 5 10 50 100 200 400 Requests/sec # of Threads GET Object 10KB Throughput Riak CS Dragon 0 100 200 300 400 500 600 700 800 900 1000 1 5 10 50 100 200 400 Requests/sec # of Threads PUT Object 10KB Throughput Riak CS Dragon
  • 10. Copyright © 2017 Yahoo Japan Corporation. All Rights Reserved. 10 Architecture API Nodes HTTP (S3 API) Storage Node Storage Node Storage Node Storage Node Storage Node Storage Node ... Storage Node Storage Node Storage Node Storage Node Storage Node Storage Node Storage Cluster Blob Metadata Meta DB
  • 11. Copyright © 2017 Yahoo Japan Corporation. All Rights Reserved. 11 Architecture API Nodes HTTP (S3 API) Storage Node Storage Node Storage Node Storage Node Storage Node Storage Node ... Storage Node Storage Node Storage Node Storage Node Storage Node Storage Node Storage Cluster Blob Metadata Meta DB
  • 12. Copyright © 2017 Yahoo Japan Corporation. All Rights Reserved. 12 Upload API Nodes HTTP PUT Storage Node Storage Node Storage Node Storage Node Storage Node Storage Node Meta DB ... Storage Node Storage Node Storage Node Storage Node Storage Node Storage Node 格納位置を含む オブジェクトメタデータ HTTP PUT
  • 13. Copyright © 2017 Yahoo Japan Corporation. All Rights Reserved. 13 Download API Nodes HTTP GET Storage Node Storage Node Storage Node Storage Node Storage Node Storage Node Meta DB ... Storage Node Storage Node Storage Node Storage Node Storage Node Storage Node Storage Cluster 格納位置を含む オブジェクトメタデータ HTTP GET
  • 14. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved. Architecture • シンプル is ベスト • ブラックボックスを減らす • メタDBとしてCassandraを利用 • 十分な可用性とスケーラビリティ • 他にもいろいろな工夫が • 今日は省略 14
  • 15. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.Copyright © 2017 Yahoo Japan Corporation. All Rights Reserved. Go Failure Tlerance Tips: 1. Circuit Breaker 2. Timeout for Streaming
  • 16. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.Copyright © 2017 Yahoo Japan Corporation. All Rights Reserved. Go Tips 1: Circuit Breaker
  • 17. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved. Circuit Breaker Storage Nodeが障害で停止・ネットワーク断の場合 • ストレージへのリクエストがコネクションタイムアウトの間ブロック • 他ノードにフェイルオーバーするまでのレイテンシがユーザーリクエストに影響 • 落ちているノードへのリクエストは避けたい 17 API Node Storage Nodes 数秒間ブロック数秒間ブロック 😢
  • 18. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.18 Circuit Breaker Circuit Breakerパターン ある処理のエラー頻度が閾値をこえたら、 しばらくは処理を省略(Circuit Open)して 即座にエラーを返すパターン タイムアウト待ちを省略してエラーを返せる Remote Server Success Error!(1) Error!(2) Trip Error!(3) Circuit Open! Circuit Breaker Trip
  • 19. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved. Circuit Breaker http://github.com/rubyist/circuitbreaker 19
  • 20. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved. API Node 20 Circuit Breaker Dragonでは、Circuit Breakerを HTTPクライアントのDialContextに適用 • 接続先アドレスのDialをCBで管理 • n回連続でDialに失敗したNodeは Circuit Openし、一定期間Dialしない • 即座にフォールバック可能 Storage NodesCircuit Breakers node1 node2 node3 node4 node5 client := http.Client{ Transport: &http.Transport{ DialContext: (&CircuitDialer{}).DialContext, }, }
  • 21. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved. type CircuitDialer struct { mu sync.Mutex dialer net.Dialer breakers map[string]*circuit.Breaker } func (d *CircuitDialer) DialContext(ctx context.Context, network, addr string) (conn net.Conn, err error) { d.mu.Lock() if d.breakers == nil { d.breakers = map[string]*circuit.Breaker{} } if _, ok := d.breakers[addr]; !ok { d.breakers[addr] = circuit.NewConsecutiveBreaker(4) } cb := d.breakers[addr] d.mu.Unlock() err = cb.CallContext(ctx, func() error { conn, err = d.dialer.DialContext(ctx, network, addr) return err }, 0) return conn, err } Circuit Breaker 21
  • 22. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved. type CircuitDialer struct { mu sync.Mutex dialer net.Dialer breakers map[string]*circuit.Breaker } func (d *CircuitDialer) DialContext(ctx context.Context, network, addr string) (conn net.Conn, err error) { d.mu.Lock() if d.breakers == nil { d.breakers = map[string]*circuit.Breaker{} } if _, ok := d.breakers[addr]; !ok { d.breakers[addr] = circuit.NewConsecutiveBreaker(4) } cb := d.breakers[addr] d.mu.Unlock() err = cb.CallContext(ctx, func() error { conn, err = d.dialer.DialContext(ctx, network, addr) return err }, 0) return conn, err } Circuit Breaker 22 接続先ごとにCircuitBreakerを用意
  • 23. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved. type CircuitDialer struct { mu sync.Mutex dialer net.Dialer breakers map[string]*circuit.Breaker } func (d *CircuitDialer) DialContext(ctx context.Context, network, addr string) (conn net.Conn, err error) { d.mu.Lock() if d.breakers == nil { d.breakers = map[string]*circuit.Breaker{} } if _, ok := d.breakers[addr]; !ok { d.breakers[addr] = circuit.NewConsecutiveBreaker(4) } cb := d.breakers[addr] d.mu.Unlock() err = cb.CallContext(ctx, func() error { conn, err = d.dialer.DialContext(ctx, network, addr) return err }, 0) return conn, err } Circuit Breaker 23 接続先のCircuitBreaker がなければ作成 接続先ごとにCircuitBreakerを用意
  • 24. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved. type CircuitDialer struct { mu sync.Mutex dialer net.Dialer breakers map[string]*circuit.Breaker } func (d *CircuitDialer) DialContext(ctx context.Context, network, addr string) (conn net.Conn, err error) { d.mu.Lock() if d.breakers == nil { d.breakers = map[string]*circuit.Breaker{} } if _, ok := d.breakers[addr]; !ok { d.breakers[addr] = circuit.NewConsecutiveBreaker(4) } cb := d.breakers[addr] d.mu.Unlock() err = cb.CallContext(ctx, func() error { conn, err = d.dialer.DialContext(ctx, network, addr) return err }, 0) return conn, err } Circuit Breaker 24 接続先のCircuitBreaker がなければ作成 DialContextにCircuitBreakerを適用 接続先ごとにCircuitBreakerを用意
  • 25. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved. API Node Circuit Breaker Circuit Breakerパターンにより、ノード障害時のリクエストレイテンシを保護 25 Storage Nodes Circuit Dialer 😄
  • 26. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.Copyright © 2017 Yahoo Japan Corporation. All Rights Reserved. Go Tips 2: I/O Timeout for Streaming
  • 27. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved. Download 27 func (s *Server) Download(w http.ResponseWriter, r *http.Request) error { // ... resp, err := s.HTTPClient.Get(blobURL) if err != nil { return err } defer resp.Body.Close() _, err = io.Copy(w, resp.Body) return err } バックエンドストレージに HTTP GETリクエストを発行 ストレージからのレスポンスボディを io.CopyでResponseWriterに転送 単純化したダウンロードハンドラ実装
  • 28. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved. Download 28 • io.Copy(dest io.Writer, src io.Reader) • src (io.Reader) を dest (io.Writer) にコピーする関数 • 内部では32KBバッファ bufを確保し、 src.Read(buf), dest.Write(buf)を繰り返し呼ぶ API Node io.Copy dest.Write() src.Read() GET Response.BodyResponseWriter
  • 29. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved. Case1: Storage Blocking on Download 29 1. もしストレージノードにNW障害やHW障害が起こると、 Response.Bodyが流れてこなくなる 2. io.Copy()内のsrc.Read()が無限にブロックする 3. ダウンロード転送が止まる! API Node io.Copy dest.Write() src.Read() GET Response.BodyResponseWriter 😢
  • 30. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved. Case2: Client Blocking on Download 30 1. 逆に、何らかの問題で、クライアントがレスポンスのダウンロードを止めると、 ResponseWriter.Write() が無限にブロックする 2. io.Copy()が進まず、ダウンロード転送が止まる 3. リソースリーク! API Node io.Copy dest.Write() src.Read() GET Response.BodyResponseWriter 😢
  • 31. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved. Upload 31 アップロードもio.Copyを使っている。 src: クライアントRequest.Body dest: 3ノードへのPUTリクエストのBody(MultiWriterとPipeを経由) API Node PUT Request.Body io.Copy Multi WriterRequest.Body src.Read() dest.Write() PUT Request.Body PUT Request.BodyWriter – Pipe - Reader Writer – Pipe - Reader Writer – Pipe - Reader
  • 32. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved. Case3: Storage Blocking on Upload 32 API Node PUT Request.Body io.Copy Multi WriterRequest.Body src.Read() dest.Write() PUT Request.Body PUT Request.BodyWriter – Pipe - Reader Writer – Pipe - Reader Writer – Pipe - Reader 1. ストレージノードに障害が起こると、リクエストBodyが送れなくなる io.Copy()内のsrc.Read()が無限にブロックする 2. アップロード転送が止まる! 😢
  • 33. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved. Timeout for Stream 33 • まとめると… • ストレージ、クライアントどちらかでデータ転送が止まると、 Read()またはWrite()が無限にブロックする • ダウンロード、アップロードのストリームが止まったままになる • リソースリークが起こる
  • 34. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved. Timeout for Stream 34 • なんとかしてI/Oのブロックを検知して、 タイムアウトエラーとしてハンドリングしたい
  • 35. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved. Timeout for Stream 35 • net.Conn.SetDeadline() ? • net.ConnのRead(),Write()に時間制限を指定する機能 • http.ServeHTTPはクライアントのnet.Connにアクセスできない • http.TimeoutHandler ? • データサイズやユーザーの通信帯域がバラバラなので 固定のタイムアウト値が設定できない • サイズ:1Byte〜5GB、帯域:100Kbps 〜 10Gbps • The complete guide to Go net/http timeouts • https://blog.cloudflare.com/the-complete-guide-to-golang-net-http-timeouts/
  • 36. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved. Our approach 36 • タイムアウト機能付きの io.Reader, io.Writerを実装して、 すべてのストリーム経路に仕掛ける Request .Body Request .Body API Node io.Copy GET Response.BodyResponseWriter io.CopyRequest.Body Request .Body Writer – Pipe - Reader Writer – Pipe - Reader Writer – Pipe - Reader Multi Writer On Download On Upload Timeout Writer Timeout Writer Timeout Writer Timeout Writer Timeout Reader Timeout Reader
  • 37. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved. TimeoutWriter/Reader • Write()がTimeout時間で完了しなかったら関数 Fn が実行されるWriteラッパー • シンプル! • TimeoutReaderも同様に定義 37 type TimeoutWriter struct { W io.Writer Timeout time.Duration Fn func() } func (w *TimeoutWriter) Write(p []byte) (int, error) { timer := time.AfterFunc(w.Timeout, w.Fn) defer timer.Stop() return w.W.Write(p) }
  • 38. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved. Timeout for Streaming 38 func (s *Server) Download(w http.ResponseWriter, r *http.Request) error { // ... blob, _ := s.GetBlobStream(ctx, object, byteRange) n, err := io.Copy(w,blob) return err } 適用前
  • 39. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved. Timeout for Streaming 39 func (s *Server) Download(w http.ResponseWriter, r *http.Request) error { // ... blob, _ := s.GetBlobStream(ctx, object, byteRange) timeoutCh := make(chan struct{}, 1) resultCh := make(chan resultAndError, 1) go func() { tw := TimeoutWriter{ W: w, Timeout: 10 * time.Second, Fn: func() { timeoutCh <- struct{}{} }, } n, err := io.Copy(tw,blob) resultCh <- resultAndError{n:n, err:err} }() select { case <-timeoutCh: return RequestTimeoutError case result := <-resultCh: return result.err } } Copyを別Goroutineに 適用後
  • 40. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved. Timeout for Streaming 40 func (s *Server) Download(w http.ResponseWriter, r *http.Request) error { // ... blob, _ := s.GetBlobStream(ctx, object, byteRange) timeoutCh := make(chan struct{}, 1) resultCh := make(chan resultAndError, 1) go func() { tw := TimeoutWriter{ W: w, Timeout: 10 * time.Second, Fn: func() { timeoutCh <- struct{}{} }, } n, err := io.Copy(tw,blob) resultCh <- resultAndError{n:n, err:err} }() select { case <-timeoutCh: return RequestTimeoutError case result := <-resultCh: return result.err } } ResponseWriterを TimeoutWriterでラップ。 io.Copyのdestをtwに 適用後
  • 41. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved. Timeout for Streaming 41 func (s *Server) Download(w http.ResponseWriter, r *http.Request) error { // ... blob, _ := s.GetBlobStream(ctx, object, byteRange) timeoutCh := make(chan struct{}, 1) resultCh := make(chan resultAndError, 1) go func() { tw := TimeoutWriter{ W: w, Timeout: 10 * time.Second, Fn: func() { timeoutCh <- struct{}{} }, } n, err := io.Copy(tw,blob) resultCh <- resultAndError{n:n, err:err} }() select { case <-timeoutCh: return RequestTimeoutError case result := <-resultCh: return result.err } } Writeが10秒間ブロックしたら timeoutChに送信 適用後 ServeHTTPを抜けると、 wはClose()してCopyはエラーに
  • 42. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved. Timeout for Streaming 42 func (s *Server) Download(w http.ResponseWriter, r *http.Request) error { // ... blob, _ := s.GetBlobStream(ctx, object, byteRange) timeoutCh := make(chan struct{}, 1) resultCh := make(chan resultAndError, 1) go func() { tw := TimeoutWriter{ W: w, Timeout: 10 * time.Second, Fn: func() { timeoutCh <- struct{}{} }, } n, err := io.Copy(tw,blob) resultCh <- resultAndError{n:n, err:err} }() select { case <-timeoutCh: return RequestTimeoutError case result := <-resultCh: return result.err } } io.Copyが終了したら resultChに送信 適用後
  • 43. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved. Performance Impact? 43 • io.Read(), io.Write()のタイムアウトをシンプルな実装でハンドルできた😄 • でも遅いんでしょう? • すべてのRead()/Write()にタイマーを仕掛けるなんて…
  • 44. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved. Performance Impact? 44 性能インパクトは僅少 • 100KB ダウンロード スループット: -2% 〜 0% • 100KB アップロード スループット: +3% 〜 -5% 0 2000 4000 6000 8000 10000 12000 20 50 100 200 400 800 Requests/sec # of Threads GET Object 100KB Throughput No Timeout Timeout 0 500 1000 1500 2000 2500 3000 3500 4000 20 50 100 200 400 800 Requests/sec # of Threads PUT Object 100KB Throughput No Timeout Timeout
  • 45. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved. Go Failure Tlerance Tips 45 大規模な分散システムに要求される耐障害性をシンプルに実装 • CircuitBreaker • Timeout Read/Write
  • 46. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.Copyright © 2017 Yahoo Japan Corporation. All Rights Reserved. Conclusion
  • 47. Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved. Conclusion • ヤフーではGoで大規模な分散オブジェクト ストレージDragonを開発・運用中です • サービス基盤のモダン化を進行中 • We’re Hiring • Thank you! 47