Share
Embed
Transcript
62 slides
-
Software Engineer, Infrastructure • Role • ιϑτΣΞΤϯδχΞϦϯάʹΑΔߴ͍ύϑΥʔϚϯε৴པੑͷߴ͍Πϯϑϥε τϥΫνϟͷ࣮ݱ • ΞϓϦέʔγϣϯΠϯϑϥपΓͰڞ௨͢Δٕज़త՝Λղܾ͢ΔͨΊͷπʔϧϛ
υϧΣΞͷ։ൃɾӡ༻ • Software Engineer, Site Reliability (SRE)ͱͷҧ͍ • ਖ਼ʹݴ͏ͱɺͦ͜·Ͱ໌֬ʹ۠ผ͞ΕΔΘ͚Ͱͳ͍ʢॴଐSREνʔϜʣ • ҰํͰɺSREΑΓ։ൃۀͷൺॏ͕େ͖͍ʢ7:3͔8:2͘Β͍ʣ -
Software Engineer, Infrastructure • ։ൃݴޠGo͕த৺ • ωοτϫʔΫγεςϜϓϩάϥϛϯάدΓͷࣝεΩϧ͕ཁٻ͞ΕΔ໘͕ଟΊ • ΠϯϑϥετϥΫνϟͷج൫Τοδέʔε͚ͷαʔόαΠυϛυϧΣΞͷ ։ൃɾӡ༻
• ֤छΦϖϨʔγϣϯͷࣗಈԽϞχλϦϯά͚πʔϧͷ։ൃɾϝϯς • ύϑΥʔϚϯενϡʔχϯάϘτϧωοΫͷௐࠪɾվળɺͷલʹ͋Δٕज़త՝ ΛιϑτΣΞΤϯδχΞϦϯάͷྗʹΑͬͯൃݟɾղܾ͢Δͷ͕ϛογϣϯʢ͜ ΕSREҰॹʣ -
ύϑΥʔϚϯεεέʔϥϏϦςΟͷ؍͔ΒݟͨPHP • PHP7ʹͳͬͯେ͘ͳͬͨ • CPU༻ҎԼ • ॲཧ͕࣌ؒे%ݮ • ͔͠͠ɺ୯ମੑೳ্͕͚ͨͩ͠ͰΟʔΫϙΠϯτͦͷ·· •
γϯάϧεϨουͳͷͰϚϧνίΞΛ׆͔ͤͳ͍ • ඇಉظॲཧ͕ۤख PHP5.6 -> PHP7.1 Response time avg PHP5.6 -> PHP7.1 -
• ेͳੑೳ • ϐʔΫ࣌Ͱඵؒઍreq/secΛࡹ͍ͯΔ ͱ͋ΔGoͷHTTP APIαʔόͷ CPU༻ͷάϥϑˠ • ϨεϙϯελΠϜavgͰ4msɺ90~99percentileͰ10~20msલޙ •
ඇಉظॲཧฒߦੑͷߴ͍ϓϩάϥϜͷ࣮ݱ͕Մೳ • ΰϧʔνϯνϟωϧʹΑΔڧྗͳαϙʔτ ύϑΥʔϚϯεεέʔϥϏϦςΟͷ؍͔ΒݟͨGo -
࣮ࡍʹyum installͰ͖ΔΑ͏ʹͳΔ·ͰͷྲྀΕ Merge PR to chage spec Build package &
upload to S3 JP US UK aws s3 sync yum repo yum repo yum repo -
slackboard • Slack Incoming WebhookϓϩΩγ݉ΫϥΠΞϯτ • github.com/cubicdaiya/slackboard • Slackͷ௨ॲཧඞཁͳใΛҰݩཧԽ •
௨ઌWebhook URLઃఆͷू • ΫϥΠΞϯτϓϩάϥϜͷ౷ҰʹΑΔϝϯςφϏϦςΟͷ্ • ࣌(2014ࠒ)ࣾͰPHPRubyPythonͷSlackΫϥΠΞϯτ͕ཚཱͯͨ͠ -
slackboard configuration [core] # listen port port = “29800” #
URL for Incoming Webhooks slack_url = “https://hooks.slack.com/services/…” [log] # access log path or redirector access_log = “stdout” # error log path or redirector error_log = “stderr” # log level level = “error” -
Usage of slackboard-cli $ slackboard -c /path/to/slackboard.toml Server Client $
echo mercari | slackboard-cli -c test -s 127.0.0.1:29800 -
Usage of slackboard-log $ slackboard -c /path/to/slackboard.toml Server Client $
slackboard-log -c test -s 127.0.0.1:29800 — ls notfound -
࣮ࡍͷγεςϜߏ by slackboard asia region us region eu region eu
region asia region us region Cloud Load Balancing GCP TMBDLCPBSE TMBDLCPBSE TMBDLCPBSE -
System architecture of pvpool • nginx • pvpoold • Powered
by Go (net/http) • MySQL pvpoold pvpoold nginx MySQL pvpool.local by consul DNS : HTTP protocol : MySQL protocol The gopher was designed by Renée French -
ఏڙ͢ΔAPI2ͭ • POST /items/pvc • ༩͑ΒΕͨIDຖͷPVΛΧϯτΞοϓ • POST /items/pv •
༩͑ΒΕͨIDຖͷPVΛฦ͢ • IDෳࢦఆՄೳ -
pvpoold Internals POST /items/pvc { "item_ids" [ ... ] }
PVCHandler Sharding Item IDs MySQL Slot Slot Slot Slot Slot Slot Pooling query Flushing periodically synchronous processing asynchronous processing -
pvpoold Internals • Slotͷొਓ • Slot -> chan types.ItemID •
PVMap -> map[types.ItemID]int • Storer -> Slot͔ΒIDΛϑΣονͯ͠PVMapͷΛߋ৽ • Flusher -> ఆظతʹPVMapͷΛऔΓग़ͯ͠MySQLʹߋ৽ΫΤϦΛൃߦ • Storer ͱ Flusher ·ͨΰϧʔνϯ -
Slot overview Slot Storer Flusher PVMap dequeue item ID Store
pv per item Fetch pv per item periodically MySQL Issue SQL to count up -
Storer func (slot *PVCSlot) storer() { for { itemID :=
<- slot.Slot slot.Lock() slot.PVMap[itemID]++ slot.Unock() } } -
Flusher func (slot *PVCSlot) flusher(interval time.Duration) { ticker := time.NewTicker(interval)
for { <- ticker.C slot.Lock() if err := slot.flush(); err != nil { // transaction // error handling } slot.Unlock() } } -
StorerͱFlusherͷׂ • Storer • MySQLൃߦ͢ΔSQLΛIDຖʹ·ͱΊΔ • eg. UPDATE pv =
pv + 5 instead of five of UPDATE pv = pv +1 • Flusher • ҰఆִؒͰMySQLʹߋ৽༻SQLΛൃߦ͢Δ • ͕Ӿཡ͞ΕΔʹUPDATE͕ΔͷΛආ͚ͯෛՙΛΒ͛Δ -
go-httpstats • ʢػೳ͕গͳ͍ͱ͍͏ҙຯͰʣখنͳHTTPαʔό͚ͷϝτϦΫεऔಘϥΠϒϥϦ • ϦΫΤετʢτʔλϧͱεςʔλείʔυຖʣ • ϨεϙϯελΠϜʢmaxɺminɺavgɺpercentileຖʣ • Not published
• ։ൃͨ͠ͷࠓ৽ଔೖࣾͷSoftware Engineer, Infrastructure • ͢Ͱʹ͋ΔͷΛ୳͚ͨ͠Ͳɺͪΐ͏Ͳ͍͍ͷ͕ͳ͔ͬͨͷͰࣗ࡞ -
Getting Started - go-httpstats mw := stats.New() handler := mw.WrapHandleFunc(
http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Write([]byte(“Hello, World”)) })) statsHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { d, err := mw.Data() if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } }) http.Handle(“/“, handler) http.Handle(“/stats”, statshandler) http.ListenAndServe(“:9999”, nil) -
Getting Started - go-httpstats $ curl -s http://127.0.0.1:9999/stats | jq
‘.request’ { “count”: 13821031, “status_count”: { “200”: 13820000, “400”: 31, “401”: 0, “403”: 0, “404”: 1000, “500”: 0, … } } -
Getting Started - go-httpstats $ curl -s http://127.0.0.1:9999/stats | jq
‘.response’ { “max_time”: 0.0238210, “min_time”: 0.00015, “average_time”: 0.0035, “percentiled_time”: { “90”: 0.0109, “95”: 0.0130, “99”: 0.0215 } } -
Sampling factor const ( // DefaultBufferSize is buf size sampling
response time for percentile and average DefaultBufferSize = 1000 // DefaultSamplingFactor is factor to sample response time for percentile and average DefaultSamplingFactor = 1 ) // … // mw := stats.New() // NewCapa returns a new statistics structure // buffer size of HTTP requests is allocated length of bufsize // If bufsize is less than 2, NewCapa returns error mw, err := stats.NewCapa(bufsize, factor) -
Introducing sampling factor • percentileͷܭࢉͦͦ͜͜ॏ͍ • avgͷܭࢉͱҧͬͯιʔτ͕ඞཁ • ϨεϙϯελΠϜܥ౷ܭσʔλͳͷͰඞͣ͠શ෦औΔඞཁͳ͍ •
ϫʔΫϩʔυͷܹ͍͠ՕॴͩͱόοϑΝॻ͖ࠐΈͷMutexڝ߹͕ܹͯ͘͠ ʹͳͬͨͷͰɺͦͷϫʔΫΞϥϯυͱͯ͠ಋೖ -
࠷ऴతʹMackerelͰάϥϑԽ $ curl -s http://127.0.0.1:9999/stats | jq ‘.request’ { “count”:
13821031, “status_count”: { “200”: 13820000, “400”: 31, “401”: 0, “403”: 0, “404”: 1000, “500”: 0, … } } $ curl -s http://127.0.0.1:9999/stats | jq ‘.response’ { “max_time”: 0.0238210, “min_time”: 0.00015, “average_time”: 0.0035, “percentiled_time”: { “90”: 0.0109, “95”: 0.0130, “99”: 0.0215 } } -
mackerelϓϥάΠϯGoͰ։ൃ • MackerelϓϥάΠϯ։ൃ༻ϔϧύʔΛ͏ͱָ • github.com/mackerelip/go-mackerel-plugin • specϑΝΠϧ࡞ޙɺmake mackerel-plugin-nameͰRPMύοέʔδΛϏ ϧυ &
• ฐࣾͷಠࣗMackerelϓϥάΠϯGo & Perl • https://speakerdeck.com/kazeburo/mackerel-day -
mfc • In-house Fastly CLI tool at Mercari • Early
development phase • ϝϧΧϦͰ2017͔ΒFastlyΛར༻த • ػೳͷཏੑࣗମͦΜͳʹߴ͘ͳ͍ • ඞཁʹͳͬͨΓɺ͋Δͱศརͦ͏ͳػೳΛΠϯςάϨʔτͯ͠Δײ͡ • ΏΔ;Θʹ։ൃͯ͠·͢ -
Usage of mfc • $ mfc Usage of mfc: config
the utility for mfc configuration service the utility for fastly service acl the utility for fastly ACL (etc…) • ػೳྖҬຖʹαϒίϚϯυΛఆٛ • ACL, Service, Version • ॳผʑͷϓϩάϥϜ͚ͩͬͨͲɺ૿͖͑ͯͨͷͰ౷߹ switch args[1] { case “config”: return config.NewCLI().Run(args) case “service”: return service.NewCLI().Run(args) case “acl”: return acl.NewCLI().Run(args) case “…” … } ಈ࡞Πϝʔδ -
mfcͷػೳ(Ұ෦) $ mfc config -h Usage of config: mfc config
list output mfc configuration $ mfc service -h Usage of service: mfc service vcldiff from_version to_version output difference between from and to mfc service versions output active and latest versions $ mfc acl -h Usage acl: mfc acl create create acl mfc acl remove remove acl mfc acl add add given entry to acl mfc acl del delete given entry in acl mfc acl show output acl mfc acl list output acl entries mfc acl sync sync acl with given provider file -
imageflux-cli • In-house ImageFlux CLI tool for Mercari • github.com/mercari/imageflux-cli
• ImageFlux ~ Ϋϥυը૾มαʔϏε • https://www.sakura.ad.jp/services/imageflux/ • Reference • ImageFluxΛར༻ͨ͠ը૾৴ͷ࠷దԽʙಈతϦαΠζͱWebPมʙ • https://tech.mercari.com/entry/2018/01/30/161001 -
Usage of imageflux-cli $ imageflux-cli -h Usage: imageflux-cli cache.lookup -k
$url imageflux-cli cache.delete -k $url imageflux-cli signature -s $secret -p $path -
΄͔ʹ͍Ζ͍Ζ • Gaurun - Building high performance push notification server
in Go • https://speakerdeck.com/cubicdaiya/building-high-performance-push-notification-server-in- go • chocon - Simple proxy server for persisting connection between upstream servers • https://speakerdeck.com/kazeburo/cloud-connect-the-world-as-a-glue-aws-dev-day-2017? slide=53 • Mercari API Gateway • https://go-talks.appspot.com/github.com/tcnksm/talks/2018/07/mercarigo/microservices-api- gateway.slide#1 • etc… ( There are too many works and products in Go at Mercari)