Slide 1

Slide 1 text

(Pݚमୈظ %": :VUBLB,BUP 
 3% %&4".*4 %&4".*4ࣾ಺ݚम

Slide 2

Slide 2 text

ݚमܭը ճ ೔࣍ ༧ఆ λΠτϧ ୈճ  Ր  (Pͷجຊ ୈճ  Ր  ؀ڥߏஙͱ(JU (JU)VCͷجຊ ୈճ  Ր  جຊߏจ ୈճ  Ր  ߏ଄ମɺεϥΠεɺϚοϓ ୈճ  Ր  ඪ४ϥΠϒϥϦ͸΍Ί͙Γ ୈճ  Ր  ϞδϡʔϧγεςϜͱ֎෦ϥΠϒϥϦ ୈճ  Ր  )FSPLV(Pೖ໳ ୈճ  Ր  "84-BNCEB(Pೖ໳ ୈճ  Ր  ฒߦॲཧϓϩάϥϛϯά ୈճ  Ր  ୯ମςετٕ๏ ୈճ  Ր  σʔλϕʔεΞΫηε ୈճ  Ր  'ZOFʹΑΔ(6*ΞϓϦέʔγϣϯ։ൃ ୈճ  Ր  ࣾ಺(PϓϩδΣΫτͷίʔυղઆ 

Slide 3

Slide 3 text

˞ લճͷ13ͷ 
 ղઆλΠϜ 

Slide 4

Slide 4 text

ຊ೔ͷΰʔϧ w 🚩ΰʔϧ w (PͷฏߦॲཧͷجຊΛशಘ͢Δ w ࣮ྫΛݟͳ͕ΒޮՌతͳར༻๏Λ஌Δ w ❌ΰʔϧͰ͸ͳ͍ w ฏߦॲཧͷςετɾσόοάεΩϧΛशಘ͢Δ 

Slide 5

Slide 5 text

എܠ 

Slide 6

Slide 6 text

ͭͷഎܠ   $16ͷൃలτϨϯυ  $,໰୊  ฏߦॲཧϞσϧͷݚڀ੒Ռ

Slide 7

Slide 7 text

$16ൃలτϨϯυ  従来手法 の 性能向上 が 頭打 ち に な り 、 マ ル チ コ ア 化 が 急速 に 進 ん で いる C P U の 性能 を 引 き 出 す に は ソ フ ト ウ ェ ア の マ ル チ コ ア 対応 が 不可欠 な 時代 に ,BSM3VQQ`Tl.JDSPQSPDFTTPS5SFOE%BUBz $$#: IUUQTHJUIVCDPNLBSMSVQQNJDSPQSPDFTTPSUSFOEEBUB ".%3Z[FO5ISFBESJQQFS9 ίΞεϨου 
 IUUQTXXXHENPSKQSFWJFX

Slide 8

Slide 8 text

&SSBUB4FDVSJUZ`Tl4DBMBCJMJUZJUTUIFRVFTUJPOUIBUESJWFTVTzIUUQTCMPHFSSBUBTFDDPNTDBMBCJMJUZJUTRVFTUJPOUIBUESJWFTVTIUNM $,໰୊  ク ラ イ ア ン ト の 同時接続数 が 1 0 , 0 0 0 ( 1 0 k ) を 超 え る と 、 
 サ ー バ ー を ス ケ ー ル ア ッ プ し て も 同時接続数 を 増 や せ な い 問題 サ ー バ ー の 性能 を2 倍 ( 赤 ) に し た の に 1 0 k 捌 け な い・ ・・ 

Slide 9

Slide 9 text

$,໰୊  ク ラ イ ア ン ト の 同時接続数 が 1 0 , 0 0 0 ( 1 0 k ) を 超 え る と 、 
 サ ー バ ー を ス ケ ー ル ア ッ プ し て も 同時接続数 を 増 や せ な い 問題 &SSBUB4FDVSJUZ`Tl4DBMBCJMJUZJUTUIFRVFTUJPOUIBUESJWFTVTzIUUQTCMPHFSSBUBTFDDPNTDBMBCJMJUZJUTRVFTUJPOUIBUESJWFTVTIUNM サ ー バ ー の 性能 を2 倍 ( 赤 ) に し た の に 1 0 k 捌 け な い・ ・・ N o d e . j s や N g i n x は 
 問題 な いん だ って ! 

Slide 10

Slide 10 text

$,໰୊   サ ー バ ー ス レ ッ ド ス レ ッ ド ス レ ッ ド ス レ ッ ド ス レ ッ ド ઀ଓ ઀ଓ͋ͨΓ 
 εϨου ス レ ッ ド を1 つ 起 こ す に は 最低 で も 1 〜 2 M B は 必要 、 1 0 k な ら 最 低 で も 1 0 〜 2 0 G B ! 通信 に 対応 す る ス レ ッ ド を 探 す に は O(n2) の 探索 が 必要 C P U が 処理 す る ス レ ッ ド を 切 り 替 え る コ ン テ キ ス ト ス イ ッ チ の オ ー バ ー ヘ ッ ド が 増大 処理 の I / O 待 ち が 多 く な り 、 C P U の 利用効率 が 低下

Slide 11

Slide 11 text

ฏߦॲཧϞσϧͷݚڀ੒Ռ  ϓϩάϥϛϯάݴޠ(P1YJW ·͕͖͑ ΑΓ w ฏߦॲཧͷ֓೦Ϟσϧ $41 Λ൚༻ݴޠͰදݱ ͢Δݚڀͷूେ੒͕(P w $41͔Β"MFGʹࢸΔܥ ේ΋ɺ6OJY΍$ݴޠͳ ͲΛੜΈग़ͨ͠ϕϧݚڀ ॴͰߦΘΕ͍ͯͨ

Slide 12

Slide 12 text

ୈճͷ෮श 

Slide 13

Slide 13 text

lHPz w (PͰฒߦॲཧΛ ߦ͏ʹ͸ʜ func f1() { fmt.Println("f1") } func f2() { fmt.Println("f2") } func main() { go f1() go f2() time.Sleep(100 * time.Microsecond) } +VTUlgoz $ go run main.go f1 f2 $ go run main.go f2 f1 

Slide 14

Slide 14 text

lHPz w (PͰฒߦॲཧΛ ߦ͏ʹ͸ʜ func f1() { fmt.Println("f1") } func f2() { fmt.Println("f2") } func main() { go f1() go f2() time.Sleep(100 * time.Microsecond) } +VTUlgoz $ go run main.go f1 f2 $ go run main.go f2 f1  m a i n 
 g o r o u t i n e g o r o u t i n e 2 g o r o u t i n e 1 3 つ の g o r o u t i n e が 平行 で 動 いて いる !

Slide 15

Slide 15 text

νϟωϧ func f1(done chan bool) { fmt.Println("f1") done <- true } func f2(done chan bool) { fmt.Println("f2") done <- true } func main() { done1 := make(chan bool) done2 := make(chan bool) go f1(done1) go f2(done2) <-done1 <-done2 }  w νϟωϧΛ࢖͏ͱɺฒߦॲཧؒ Ͱ஋΍ϝοηʔδΛ΍ΓͱΓͰ ͖Δ w ૹ৴จch <- x w ड৴จx = <-ch w ଴͚ͭͩͳΒ<-ch

Slide 16

Slide 16 text

νϟωϧ w νϟωϧΛ࢖͏ͱɺฒߦॲཧؒ Ͱ஋΍ϝοηʔδΛ΍ΓͱΓͰ ͖Δ w ૹ৴จch <- x w ड৴จx = <-ch w ଴͚ͭͩͳΒ<-ch func f1(done chan bool) { fmt.Println("f1") done <- true } func f2(done chan bool) { fmt.Println("f2") done <- true } func main() { done1 := make(chan bool) done2 := make(chan bool) go f1(done1) go f2(done2) <-done1 <-done2 }  受信 を 待機 送信 送信 複数処理 を 平行 で 走 ら せ て 全部終 わ る の を
 待 つ 処理 が こ ん な に シ ン プ ル に ! チ ャ ネ ル を 渡 す

Slide 17

Slide 17 text

TFMFDU w ଟॏԽෳ਺ͷνϟ ωϧΛ଴ͪड͚ɺ 
 ࠷ॳʹड৴ͨ͠΋ ͷΛर͏ func f1(done chan bool) { fmt.Println("f1") done <- true } func f2(done chan bool) { fmt.Println("f2") done <- true } func main() { done1 := make(chan bool) done2 := make(chan bool) go f1(done1) go f2(done2) select { case <-done1: fmt.Println("f1 is first!") case <-done2: fmt.Println(“f2 is first!") } } $ go run main.go f1 f1 is first! f2 
 $ go run main.go f2 f2 is first!  何 か の 条件 に 合 う ま で 待機

Slide 18

Slide 18 text

DMPTF w νϟωϧʹ͸஋Λ ૹΓଓ͚Δ͜ͱ͕ Ͱ͖Δ w ૊ΈࠐΈؔ਺ close()Ͱνϟ ωϧͷऴྃΛ଴ͪ खʹ఻͑ΒΕΔ func async(counter chan int) { for i := 1; i <= 3; i++ { counter <- i time.Sleep(100 * time.Microsecond) } close(counter) } func main() { counter := make(chan int) go async(counter) for count := range counter { fmt.Println(count) } } $ go run main.go 1 2 3 $  3 回送信 チ ャ ネ ル を 閉 じ る 閉 じ ら れ る と 
 r a n g e が 抜 け る

Slide 19

Slide 19 text

όοϑΝ͋Γνϟωϧ w όοϑΝαΠζΛࢦఆ͢ΔͱόοϑΝ͋ΓνϟωϧʹͳΔ w ड৴ʹରͯ͠ૹ৴͕ͷ৔߹͕Ӭԕʹૹ৴଴ͪʹͳΔͷΛ๷͛Δ func f1(done chan bool) { fmt.Println("f1") done <- true } func f2(done chan bool) { fmt.Println("f2") done <- true } func main() { done := make(chan bool, 2) go f1(done) go f2(done) <-done } $ go run main.go f2 $ go run main.go f2 f1  引数追加 1 つ 受信 し て 終了

Slide 20

Slide 20 text

ฒߦॲཧͷཪଆ 1SPDFTT 1SPDFTT 1SPDFTT 5ISFBE 5ISFBE 5ISFBE $16 
 ίΞ $16 
 ίΞ ࣮ߦ ࣮ߦ εέδϡʔϦϯά 
 ίϯςΩετεΠον 

Slide 21

Slide 21 text

ฒߦॲཧͷཪଆ 1SPDFTT 5ISFBE 5ISFBE $16 
 ίΞ $16 
 ίΞ ࣮ߦ NBJO 
 HPSPVUJOF HPSPVUJOF HPSPVUJOF ʜ ࣮ߦ ࣮ߦ ࣮ߦ ࣮ߦ ࣮ߦ ࣮ߦ 04εέδϡʔϥʔ HPϥϯλΠϜ 
 ./εέδϡʔϥʔ  ʜ

Slide 22

Slide 22 text

ฒߦॲཧͷཪଆ w HPSPVUJOF͸ͱͯ΋ܰྔʂখ͞ͳؔ਺ͷ࣮ߦͰ΋͡ΌΜ͡ΌΜ্ཱͪ͛ͯ΋ ߏΘͳ͍ w ଞͷݴޠͷίϧʔνϯͱ͸ҟͳΓɺϓϩάϥϚ͕தஅ΍࠶։Λࢦࣔ͢Δ͜ͱ ͸Ͱ͖ͳ͍  ࣮ߦ୯Ґ ؅ཧ ࠷খελοΫ 
 αΠζ -JOVY ϓϦΤϯϓγϣϯ 1SPDFTT 04 .# ͋Γ 5ISFBE 04 .# ͋Γ HPSPVUJOF (Pϓϩηε ,# ϒϩοΫ͍ͯ͠Δ HPSPVUJOFͷΈ

Slide 23

Slide 23 text

                 (PMBOH +BWB 1ZUIPO           (PMBOH +BWB 1ZUIPO HPSPVUJOFͷҖྗ w େྔͷ.255௨৴Λߦ͏ϓϩάϥϜͰϦιʔεফඅΛൺֱ w ௨৴਺Λ૿΍ͯ͠΋ϝϞϦফඅͷ૿Ճ͕গͳ͘ɺͳ͓͔ͭ଎͍ʂ  ϝϞϦফඅྔ # ফඅ࣌ؒ T ݕূίʔυIUUQTHJUIVCDPNNJLBONRUUCFODINBSLT

Slide 24

Slide 24 text

ฒߦॲཧͷཪଆ w (0."9130$4؀ڥม਺ w σϑΥϧτ஋ϥϯλΠϜͷ$16ίΞ਺ w ڝ߹ঢ়ଶ͕ͳ͍͔ςετΛ͢Δͱ͖ͱ͔ʹΘ͟ͱ૿΍͢ func main() { for { go fmt.Print(0) fmt.Print(1) } }  (0."9130$4HPSVONBJOHP (0."9130$4HPSVONBJOHP

Slide 25

Slide 25 text

ݱ࣮ੈքͷฏߦॲཧ 

Slide 26

Slide 26 text

IUUQ-JTUFO"OE4FSWF  http.HandleFunc("/", handleHome ) log.Printf("ϙʔτ %s Ͱ଴ͪड͚Λ։࢝͠·͢...", port ) if err := http.ListenAndServe(":"+port, nil); err != nil { log.Printf("αʔόʔ͕ҟৗऴྃ͠·ͨ͠: %v", err ) } ୈճϋϯζΦϯͷίʔυͷҰ෦ ඪ४ϥΠϒϥϦͷ࣮૷Λḷ͍ͬͯ͘ͱʜ

Slide 27

Slide 27 text

IUUQ-JTUFO"OE4FSWF  http.HandleFunc("/", handleHome ) log.Printf("ϙʔτ %s Ͱ଴ͪड͚Λ։࢝͠·͢...", port ) if err := http.ListenAndServe(":"+port, nil); err != nil { log.Printf("αʔόʔ͕ҟৗऴྃ͠·ͨ͠: %v", err ) } ୈճϋϯζΦϯͷίʔυͷҰ෦ func (srv *Server) Serve(l net.Listener) error { .. . for { rw, err := l.Accept( ) if err != nil { .. . } .. . go c.serve(connCtx ) } } TSDOFUIUUQTFSWFSHP -JTUFO"OE4FSWF TFSWFS-JTUFO"OE4FSWF TFSWFS4FSWF イ ベ ン ト ル ー プ は m a i n g o r o u t i n e 各 コ ネ ク シ ョン の 処理 は 別 の g o r o u t i n e

Slide 28

Slide 28 text

)551Λ(PͰࡹ͘  m a i n 
 g o r o u t i n e ε Ϩου ε Ϩου ε Ϩου ε Ϩου g o r o u t i n e ઀ଓ ઀ଓ͋ͨΓ 
 HPSPVUJOF HPSPVUJOFͷελοΫαΠζ ͸े෼ʹখ͘͞ɺͨ͘͞Μىͯ͜͠ ΋େৎ෉ʂ ֤HPSPVUJOF͸(Pϥϯλ ΠϜ͕ޮ཰తʹ؅ཧ͍ͯ͠Δ ϒϩοΫ͠ͳ͍ݶΓ 
 ϓϦΤϯϓγϣϯ͞Εͳ͍ *0଴ͪͷ HPSPVUJOF͸$16ʹׂΓ౰ͯͳ ͍ͷͰແବ͕ͳ͍

Slide 29

Slide 29 text

ϚΠΫϩαʔϏεͰͷ׆༻  サ ー ビ ス 1 外部 
 サ ー ビ ス 1 外部 
 サ ー ビ ス 2 外部 
 サ ー ビ ス 3 HPSPVUJOFͰॲཧ HPSPVUJOFͰॲཧ HPSPVUJOFͰॲཧ ク ラ イ ア ン ト へ 高速 に 応答 を 返 す に は 各依存 サ ー ビ ス の 平行呼 び 出 し が 効果的

Slide 30

Slide 30 text

*P5Ͱͷ׆༻  ήʔτ΢ΣΠ $MPVE ͭड৴ͨ͠Β͙͢͞ ·࣍ͷड৴ʹඋ͑Δ ηϯ 
 αʔ ΤΫεϙωϯγϟϧ όοΫΦϑͳͲͷϦτϥ Π੍ޚ ΩϡʔΠϯάʹΑΔΦ ϑϥΠϯ࣌ͷσʔλ࠶ૹ σίʔυɺόϦσʔ γϣϯ౳ͷඇಉظԽ 頑強 な I o T ゲー ト ウ ェ イ 開発 に は 
 非同期処理 が 不可欠

Slide 31

Slide 31 text

ഉଞ੍ޚ 

Slide 32

Slide 32 text

TZODඪ४ϥΠϒϥϦ  w ෳ਺ͷHPSPVUJOF͔Βಉ͡ม਺ΛಡΈॻ͖͢ΔͱͲ͏ͳΔ͔ʁ 
 ˠσʔλڝ߹ EBUBSBDF BOEPSڝ߹ঢ়ଶ SBDFDPOEJUJPO ʹʂ w .VUFYͳͲݪ࢝తͳ΋ͷ͔Βந৅౓ͷߴ͍΋ͷ·ͰऔΓἧ͑ͯ͋Δ ܕ આ໌ 4JODF .VUFY -PDL 6OMPDL͕Ͱ͖Δ  38.VUFY ಡग़͠ϩοΫ͕େଟ਺Λ઎ΊΔͱ͖ͷΈར༻  0ODF ॳظԽͳͲճͷΈ࣮ߦ͍ͨ͠ॲཧͷ࣮ݱ  8BJU(SPVQ ෳ਺ͷHPSPVUJOFͷ଴ͪ߹Θͤͷ࣮૷ʹศར  $POE ෳࡶͳ଴ͪ߹Θͤͷ৚݅ม਺ͷ࣮૷༻  1PPM σʔλ΍ΦϒδΣΫτͷ࠶ར༻ͷͨΊͷอ؅ݿ  .BQ ҆શʹಡΈॻ͖Ͱ͖Δ.BQ ͔ͪ͠͠ΐͬͱ࢖͍ͮΒ͍  ΑΓ௿Ϩϕϧͷػೳ͕ἧͬͨTZODBUPNJDαϒύοέʔδ΋νΣοΫʂ

Slide 33

Slide 33 text

σουϩοΫͨ͠Β  w (P͕σουϩοΫΛݕ஌͢ΔͱQBOJD Ͱམͱͯ͘͠ΕΔ w ͨͩ͠*0଴ͪʹΑΔϩοΫͷ৔߹͸མͱͣ͞଴ͬͯ͘ΕΔ var resource sync.Mute x func f(done chan bool) { resource.Lock( ) defer resource.Unlock( ) done <- tru e } func main() { done := make(chan bool ) go f(done ) resource.Lock( ) defer resource.Unlock( ) <-don e } 👈͜ΕΛ࣮ߦ͢Δͱʜ

Slide 34

Slide 34 text

σουϩοΫͨ͠Β  w (P͕σουϩοΫΛݕ஌͢ΔͱQBOJD Ͱམͱͯ͘͠ΕΔ w ͨͩ͠*0଴ͪʹΑΔϩοΫͷ৔߹͸མͱͣ͞଴ͬͯ͘ΕΔ var resource sync.Mute x func f(done chan bool) { resource.Lock( ) defer resource.Unlock( ) done <- tru e } func main() { done := make(chan bool ) go f(done ) resource.Lock( ) defer resource.Unlock( ) <-don e } fatal error: all goroutines are asleep - deadlock ! goroutine 1 [chan receive] : main.main( ) .../main.go:18 +0xb 8 goroutine 5 [semacquire] : sync.runtime_SemacquireMutex(0x10fa58c, 0x0, 0x1 ) ...
 main.f(0xc000054060 ) .../main.go:8 +0xa b .. . exit status 2 ϩοΫ͕औΕͳ͍ νϟωϧ͕ฦͬͯ͜ͳ͍ ˞ઌʹϩοΫΛऔͬͨͷ͕G ͩͬͨ৔߹͸ཱ৔͕ٯʹͳͬͨελοΫτϨʔε͕ग़Δ

Slide 35

Slide 35 text

࿅श 

Slide 36

Slide 36 text

࿅श໰୊ w ࿅श໰୊ 1 <ϑΥϧμ໊EBZFY> w ·ͣ͸11ͷCBOLΛࣸܦ͠·͢ ύοέʔδ͸NBJOʹม͑ͯ͠·͍·͠ΐ͏  w ώϯτҎԼͷΑ͏ͳߏ଄ମΛ࡞ͬͯΈ͍ͯͩ͘͞  type withdrawTransaction struct { amount in t ok chan boo l }

Slide 37

Slide 37 text

ʙղઆλΠϜʙ 

Slide 38

Slide 38 text

͕࣌ؒ༨ͬͨΒ w ࿅श໰୊ 1 <ϑΥϧμ໊EBZFY> w Ͳ͏࡞Δ͔͸ࣗ༝ʂ w ͸ͨͯ͋͠ͳͨͷϚγϯͰ͸ԿQJOHTFD 
 ग़Δ͔ɾɾɾʂʁ 

Slide 39

Slide 39 text

ίʔυΛॻ͖ऴ͑ͨΒ w ʮϢʔβʔ໊QSBDUJDFʯϒϥϯνͰ࡞ۀ͍ͯ͠Δ͜ͱΛ֬ೝ͍ͯͩ͘͠͞ w 74$PEFͷҰ൪ࠨԼʹදࣔ͞Ε͍ͯ·͢ w มߋΛεςʔδ͠ɺίϛοτ͍ͯͩ͘͠͞ w 74$PEFͷࠨϝχϡʔͷʮιʔε؅ཧʯ͔Βૢ࡞ w ίʔυΛ(JU)VCʹϓογϡ͍ͯͩ͘͠͞ w 74$PEFͷҰ൪ࠨԼͷϒϥϯν໊ͷ͙͢ӈʹ͋ΔΞΠίϯ͔Βૢ࡞ ্ਤ  w ϓϧϦΫΤετΛ࡞੒͍ͯͩ͘͠͞ w ʮιʔε؅ཧʯͷ্෦ʹΞΠίϯ͕͋Γ·͢ 

Slide 40

Slide 40 text

࣍ճ༧ࠂ w ࣍ճ͸ʮ୯ମςετٕ๏ʯͰ͢ w ෼͔Βͳ͔ͬͨͱ͜Ζ΍࣭໰ͳͲ͸ɺࣾ಺ 4MBDLHPQIFSTνϟϯωϧʹ౤ߘ͍ͩ͘͞ w ຊ೔ͷ಺༰ΛΑΓਂ͘ཧղ͍ͨ͠ํ͸ɺڭՊॻ ͷୈষɺୈষΛಡΜͰΈ͍ͯͩ͘͞