SlideShare uma empresa Scribd logo
1 de 47
Baixar para ler 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

Mais conteúdo relacionado

Mais procurados

Twitterのsnowflakeについて
TwitterのsnowflakeについてTwitterのsnowflakeについて
Twitterのsnowflakeについてmoai kids
 
Redisの特徴と活用方法について
Redisの特徴と活用方法についてRedisの特徴と活用方法について
Redisの特徴と活用方法についてYuji Otani
 
ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方増田 亨
 
PlaySQLAlchemy: SQLAlchemy入門
PlaySQLAlchemy: SQLAlchemy入門PlaySQLAlchemy: SQLAlchemy入門
PlaySQLAlchemy: SQLAlchemy入門泰 増田
 
こわくない Git
こわくない Gitこわくない Git
こわくない GitKota Saito
 
DDDのモデリングとは何なのか、 そしてどうコードに落とすのか
DDDのモデリングとは何なのか、 そしてどうコードに落とすのかDDDのモデリングとは何なのか、 そしてどうコードに落とすのか
DDDのモデリングとは何なのか、 そしてどうコードに落とすのかKoichiro Matsuoka
 
事例で学ぶApache Cassandra
事例で学ぶApache Cassandra事例で学ぶApache Cassandra
事例で学ぶApache CassandraYuki Morishita
 
エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織Takafumi ONAKA
 
イミュータブルデータモデルの極意
イミュータブルデータモデルの極意イミュータブルデータモデルの極意
イミュータブルデータモデルの極意Yoshitaka Kawashima
 
OSS活動の活発さと評価の関係について
OSS活動の活発さと評価の関係についてOSS活動の活発さと評価の関係について
OSS活動の活発さと評価の関係についてTakuto Wada
 
テスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるなテスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるなKentaro Matsui
 
DockerとPodmanの比較
DockerとPodmanの比較DockerとPodmanの比較
DockerとPodmanの比較Akihiro Suda
 
それはYAGNIか? それとも思考停止か?
それはYAGNIか? それとも思考停止か?それはYAGNIか? それとも思考停止か?
それはYAGNIか? それとも思考停止か?Yoshitaka Kawashima
 
分散システムについて語らせてくれ
分散システムについて語らせてくれ分散システムについて語らせてくれ
分散システムについて語らせてくれKumazaki Hiroki
 
コンテナの作り方「Dockerは裏方で何をしているのか?」
コンテナの作り方「Dockerは裏方で何をしているのか?」コンテナの作り方「Dockerは裏方で何をしているのか?」
コンテナの作り方「Dockerは裏方で何をしているのか?」Masahito Zembutsu
 
初心者向けMongoDBのキホン!
初心者向けMongoDBのキホン!初心者向けMongoDBのキホン!
初心者向けMongoDBのキホン!Tetsutaro Watanabe
 
AWS で Presto を徹底的に使いこなすワザ
AWS で Presto を徹底的に使いこなすワザAWS で Presto を徹底的に使いこなすワザ
AWS で Presto を徹底的に使いこなすワザNoritaka Sekiyama
 
わかる!metadata.managedFields / Kubernetes Meetup Tokyo 48
わかる!metadata.managedFields / Kubernetes Meetup Tokyo 48わかる!metadata.managedFields / Kubernetes Meetup Tokyo 48
わかる!metadata.managedFields / Kubernetes Meetup Tokyo 48Preferred Networks
 

Mais procurados (20)

Twitterのsnowflakeについて
TwitterのsnowflakeについてTwitterのsnowflakeについて
Twitterのsnowflakeについて
 
Redisの特徴と活用方法について
Redisの特徴と活用方法についてRedisの特徴と活用方法について
Redisの特徴と活用方法について
 
ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方
 
PlaySQLAlchemy: SQLAlchemy入門
PlaySQLAlchemy: SQLAlchemy入門PlaySQLAlchemy: SQLAlchemy入門
PlaySQLAlchemy: SQLAlchemy入門
 
こわくない Git
こわくない Gitこわくない Git
こわくない Git
 
DDDのモデリングとは何なのか、 そしてどうコードに落とすのか
DDDのモデリングとは何なのか、 そしてどうコードに落とすのかDDDのモデリングとは何なのか、 そしてどうコードに落とすのか
DDDのモデリングとは何なのか、 そしてどうコードに落とすのか
 
事例で学ぶApache Cassandra
事例で学ぶApache Cassandra事例で学ぶApache Cassandra
事例で学ぶApache Cassandra
 
エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織
 
分散トレーシング技術について(Open tracingやjaeger)
分散トレーシング技術について(Open tracingやjaeger)分散トレーシング技術について(Open tracingやjaeger)
分散トレーシング技術について(Open tracingやjaeger)
 
イミュータブルデータモデルの極意
イミュータブルデータモデルの極意イミュータブルデータモデルの極意
イミュータブルデータモデルの極意
 
OSS活動の活発さと評価の関係について
OSS活動の活発さと評価の関係についてOSS活動の活発さと評価の関係について
OSS活動の活発さと評価の関係について
 
テスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるなテスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるな
 
DockerとPodmanの比較
DockerとPodmanの比較DockerとPodmanの比較
DockerとPodmanの比較
 
それはYAGNIか? それとも思考停止か?
それはYAGNIか? それとも思考停止か?それはYAGNIか? それとも思考停止か?
それはYAGNIか? それとも思考停止か?
 
分散システムについて語らせてくれ
分散システムについて語らせてくれ分散システムについて語らせてくれ
分散システムについて語らせてくれ
 
Glibc malloc internal
Glibc malloc internalGlibc malloc internal
Glibc malloc internal
 
コンテナの作り方「Dockerは裏方で何をしているのか?」
コンテナの作り方「Dockerは裏方で何をしているのか?」コンテナの作り方「Dockerは裏方で何をしているのか?」
コンテナの作り方「Dockerは裏方で何をしているのか?」
 
初心者向けMongoDBのキホン!
初心者向けMongoDBのキホン!初心者向けMongoDBのキホン!
初心者向けMongoDBのキホン!
 
AWS で Presto を徹底的に使いこなすワザ
AWS で Presto を徹底的に使いこなすワザAWS で Presto を徹底的に使いこなすワザ
AWS で Presto を徹底的に使いこなすワザ
 
わかる!metadata.managedFields / Kubernetes Meetup Tokyo 48
わかる!metadata.managedFields / Kubernetes Meetup Tokyo 48わかる!metadata.managedFields / Kubernetes Meetup Tokyo 48
わかる!metadata.managedFields / Kubernetes Meetup Tokyo 48
 

Destaque

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
 
マイクロサービスバックエンドAPIのためのRESTとgRPC
マイクロサービスバックエンドAPIのためのRESTとgRPCマイクロサービスバックエンドAPIのためのRESTとgRPC
マイクロサービスバックエンドAPIのためのRESTとgRPCdisc99_
 
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
 

Destaque (10)

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
 
マイクロサービスバックエンドAPIのためのRESTとgRPC
マイクロサービスバックエンドAPIのためのRESTとgRPCマイクロサービスバックエンドAPIのためのRESTとgRPC
マイクロサービスバックエンドAPIのためのRESTとgRPC
 
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)
 
条件式評価器の実装による管理ツールの抽象化
条件式評価器の実装による管理ツールの抽象化条件式評価器の実装による管理ツールの抽象化
条件式評価器の実装による管理ツールの抽象化
 

Semelhante a 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
 

Semelhante a 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
 

Mais de 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!デベロッパーネットワーク
 

Mais de 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
 

Último

自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineerYuki Kikuchi
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...博三 太田
 
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfFumieNakayama
 
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)UEHARA, Tetsutaro
 
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案sugiuralab
 
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfFumieNakayama
 
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)Hiroshi Tomioka
 
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NTT DATA Technology & Innovation
 
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?akihisamiyanaga1
 

Último (9)

自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
 
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
 
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
 
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
 
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
 
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
 
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
 
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
 

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