Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
SREによるモンスト改善事例 / improvement-example-of-monster...
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
浜田 恭平 (Kyohei Hamada)
August 24, 2017
Programming
4.5k
4
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
SREによるモンスト改善事例 / improvement-example-of-monster-strike-by-sre
hbstudy#76
第76回: SRE大全: XFLAG スタジオ編
https://hbstudy.connpass.com/event/62338/
浜田 恭平 (Kyohei Hamada)
August 24, 2017
More Decks by 浜田 恭平 (Kyohei Hamada)
See All by 浜田 恭平 (Kyohei Hamada)
年間版1秒動画2023 大量配信の裏側 - MIXI TECH CONFERENCE 2023 DAY1
haman29
2
3.1k
モンストのサーバー負荷との戦い 〜あけおめ2018編〜 / bcu_30_server_9
haman29
12
16k
Other Decks in Programming
See All in Programming
速習iPhone Duo対応
yuukiw00w
2
910
速く作れる。その次は、速く確かめられる開発へ 〜AIネイティブ開発を支える、Shift Down〜 / Can build fast. Next, moving to development where we can verify fast.
rkaga
8
5.2k
Embedded Swiftで作る自作USBデバイス によるiOSデバイスの自動テスト / iOSDC Japan 2026 glassfiber
glassfiber
0
230
Herb in Rails 8.2: Your ERB views, now HTML-aware @ Rails World 2026, Austin, Texas
marcoroth
0
140
iOSDC Japan 2026 - Swiftで作って学ぼう!データベース自作入門
kaseken
2
410
Ghostty + Neovimで作る 透明でカッコ良い開発環境
j341nono
0
150
更なる可用性を求めて、5年間運用したKotlinのアプリケーションをGoでリプレイスする話
ken_tunc
0
420
SREの越境 / SRE Collaboration
y0hgi
2
290
AgentCore CLI で進化した AWS での AI エージェントの作り方 : 必要な機能を必要な時に
icoxfog417
PRO
4
400
iOS 27でニュースアプリはどう変わる!? 〜日経電子版の新機能対応と、開発事例から〜
lynnswap
7
13k
Intent as Code
shoppingjaws
6
1.1k
SONY CISC-NEWS NWS-1750 + NWB-225 フレームバッファの NetBSD/news68k ドライバ実装 / OSC2026Hiroshima
tsutsui
0
160
Featured
See All Featured
What does AI have to do with Human Rights?
axbom
PRO
1
2.4k
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
1
500
Heart Work Chapter 1 - Part 1
lfama
PRO
10
36k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.9k
Building Flexible Design Systems
yeseniaperezcruz
330
41k
Speed Design
sergeychernyshev
33
2.1k
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
69
66k
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
340
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
It's Worth the Effort
3n
188
29k
Leading Effective Engineering Teams in the AI Era
addyosmani
9
2.7k
Hiding What from Whom? A Critical Review of the History of Programming languages for Music
tomoyanonymous
3
1.3k
Transcript
SREʹΑΔϞϯετվળࣄྫ 2017/08/24 hbstudy ୈ76ճɿ SREେશ: XFLAG ελδΦฤ XFLAG ࣄۀຊ෦ ήʔϜ։ൃࣨ
SREάϧʔϓ ా ګฏ @haman29 XFLAG STUDIO
About me • ా ګฏ @haman29 • https://twitter.com/haman29 • લ৬ͰαʔόαΠυΤϯδχΞɻยखؒͰϑϩϯτΤϯυɺΠϯϑϥɻ
• ओʹWebαʔϏεʢϑϦϚαʔϏεɺΫʔϙϯαʔϏεͳͲʣΛ୲ɻ • 2016/07 SREάϧʔϓཱͱಉ࣌ʹೖࣾ͠ɺSREͷҰһʹɻ • ओʹຊ൛Ϟϯετͷӡ༻ɾվળΛ୲ɻ • झຯϘϧμϦϯά • https://codeiq.jp/magazine/2016/03/38660/ 3ਓʢલ৬ʹ͍ͨ࣌ʣ 2
͓ॻ͖ memcached Λར༻ͨ͠ෛՙରࡦ ࣄྫ1 Resque worker ىಈͷߴԽ ࣄྫ2 DBαʔόߏஙͷࣗಈԽ ࣄྫ3
·ͱΊ 3
4 ࣄྫ1. memcachedΛར༻ͨ͠ෛՙରࡦ
̏पΠϕϯτ • 3पരઈײँΨνϟ • 1Ϣʔβ1ճͷΈҾ͚ΔΨνϟ • 6Ωϟϥ͕5ମग़͖ͯͯͦͷ1ମΛબΔ • ΨνϟΛҾͨ͘ΊͷΞΠςϜʮχδۄʯΛϢʔβશһʹΔ •
৽نϢʔβʹΔ • ϢϝۄΫΤετ • ΠϕϯτΫΤετΛपճ͠ɺϢϝۄΛूΊɺϢϝۄΛͬͯΨνϟΛճ͢ • ͯͷΩϟϥΛ99ମूΊΔ·Ͱ͜ΕΛ܁Γฦ͢ 5
̏पരઈײँΨνϟ • 7:30ࠒϢʔβΞΠςϜ༻ͷDB٧·Δ • select/insert/update͕૿Ճ • os_waits ͕ٸ૿ • ରԠ
• innodb_spin_wait_delay ௐ • slaveΛՃͯ͠selectΛࢄ 6
ෛՙରࡦɹݕ౼ • 1िؒޙͷϢϝۄΫΤετʹඋ͑ͯselectΛݮΒ͓͖͍ͯͨ͠ • ͢ͰʹSQL࠷దԽ͞Ε͍ͯΔʢ୯७ͳΫΤϦ͔͠ͳ͍ʣ • monsterstrike/second_level_cache Λར༻ • hooopo/second_level_cache
Λfork֦ͯ͠ு • ActiveRecordܦ༝ͰΫΤϦΛൃߦ͢Δͱɺ͍͍ײ͡ʹ memcached Ͱ Ωϟογϡͯ͘͠ΕΔ • ͢ͰʹϞϯετͰར༻࣮͕͋Δ 7
SecondLevelCache `.create` { “user_item/10001” => “[10001, 101, 1, …]”, …
} insert into user_items(user_id, item_id, cnt) values (101, 1, 2); class UserItem < ActiveRecord::Base acts_as_cached(version: 1, expires_in: 1.day) end UserItem.create(user_id: 101, item_id: 1) # => id: 10001 app memcached MySQL 8 no cached
SecondLevelCache `.find` { “user_item/10001” => “[10001, 101, 1, …]” }
select * from user_items where id = 10001; UserItem.find(10001) app memcached MySQL 9 class UserItem < ActiveRecord::Base acts_as_cached(version: 1, expires_in: 1.day) end no cached cached
SecondLevelCache `.fetch_by_uniq_keys` { “user_item/fbu/user_id_101_item_id_1” => 10001, “user_item/10001” => “[10001, 101,
1, …]” } select * from user_items where user_id = 101 and item_id = 1; app memcached MySQL UserItem.fetch_by_uniq_keys(user_id:101, item_id: 1) ※ΩϟογϡͷϥΠϑαΠΫϧͷҧ͍ʹ͢Δ͜ͱͰ ɹޮΑ͘memcachedΛ׆༻Ͱ͖ɺMySQLͷΫΤϦݮΒ͢͜ͱ͕Ͱ͖Δ 10 class UserItem < ActiveRecord::Base acts_as_cached(version: 1, expires_in: 1.day) end no cached cached # جຊతʹexpire͠ͳ͍ # සൟʹexpire͢Δ
11 SecondLevelCache `.fetch_by_index` (֦ு) { “user_item/fbi/user_id/101” => [10001, 10002, 10003],
“user_item/10001” => “[10001, 101, 1, …]”, “user_item/10002” => “[10002, 101, 2, …]”, “user_item/10003” => “[10003, 101, 3, …]” } select id from user_items where user_id = 101; select * from user_items where id in (10001, 10002, 10003); app memcached MySQL UserItem.fetch_by_index(user_id:101) class UserItem < ActiveRecord::Base acts_as_cached(version: 1, expires_in: 1.day) acts_as_cached_by_index(:user_id) end # indexΛு͍ͬͯΔΧϥϜͷΈࢦఆՄ no cached cached ※Ωϟογϡ͍ͯ͠ͳ͍ࠩͷΈMySQLʹ͍߹ΘͤΔ # جຊతʹexpire͠ͳ͍ # සൟʹexpire͢Δ
SecondLevelCacheಋೖޙ ࢥ͍ͷ΄͔select͕ݮ͍ͬͯͳ͍… 12
# Profile # Rank Query ID Response time Calls R/Call
V/M Item # ==== ================== ============= ===== ====== ===== =============== # 1 0x365FBDCB443D99A3 5.1165 82.3% 2523 0.0020 0.20 SELECT user_items # 2 0x5B79B47AB9093007 1.0197 16.4% 178 0.0057 0.79 SELECT user_items # 3 0xA6FF35DF18E85C6C 0.0655 1.1% 101 0.0006 0.00 SELECT user_items # 4 0x10259F2E34E9D7F1 0.0136 0.2% 32 0.0004 0.00 SELECT user_items # 5 0x28DA30E044AAF5E8 0.0022 0.0% 8 0.0003 0.00 SELECT user_items # 6 0x022C53131F50003E 0.0016 0.0% 9 0.0002 0.00 SELECT user_items # Query 1: 910.54 QPS, 1.85x concurrency, ID 0x365FBDCB443D99A3 at byte 5687530 # Scores: V/M = 0.20 # Time range: 2016-10-13 23:06:37.637168 to 23:06:40.408062 # Attribute pct total min max avg 95% stddev median # ============ === ======= ======= ======= ======= ======= ======= ======= # Count 88 2523 # Exec time 82 5s 96us 973ms 2ms 8ms 20ms 185us # Rows affecte 100 154 0 1 0.06 0.99 0.24 0 # Query size 84 302.79k 120 124 122.89 118.34 0.00 118.34 # Warning coun 0 0 0 0 0 0 0 0 # String: # Hosts 10.53.6.53 (30/1%), 192.168.117.176 (20/0%)... 398 more # Query_time distribution # 1us # 10us # # 100us ################################################################ # 1ms ####### # 10ms ## # 100ms # # 1s # 10s+ # Tables # SHOW TABLE STATUS LIKE 'user_items'\G # SHOW CREATE TABLE `user_items`\G # EXPLAIN /*!50100 PARTITIONS*/ SELECT `user_items`.* FROM `user_items` WHERE `user_items`.`user_id` = 12345 AND `user_items`.`item_id` = 101 LIMIT 1\G ΫΤϦௐࠪ pt-query-digest ( Percona Toolkit ) # tcpdump ΛͱΔ # ݁ՌselectͷΈʹߜΔ $ pt-query-digest --type=tcpdump --limit=100 --filter '$event->{arg} =~ m/^(select)/i' dumpfile > result_select `.fetch_by_uniq_keys` ͕͑ͦ͏ 13
14 ݁Ռ selectΛ70%ݮɻΠϕϯτߴෛՙ࣌ͳ͘ࡹ͍ͨɻ ϢϝۄΫΤετ ̏पരઈײँΨνϟ ஈ֊తʹෛՙରࡦ༻ࠩΛσϓϩΠ
15 ࣄྫ2. Resque worker ىಈͷߴԽ
Resqueߏ Batch 1 Redis 1 Ԇͯ͠ྑ͍ॲཧόοάάϥϯυͰ port 1 worker worker
worker worker worker worker ɾɾɾ worker worker worker worker worker worker worker worker worker worker worker worker worker worker worker worker worker worker Batch 2 worker worker worker port 2 port 3 port 4 Redis 2 port 1 port 2 port 3 port 4 (Redis 1 port 1) app app app LB enqueue dequeue 16 (Redis 2 port 4)
resque:restart • શͯͷ Resque worker ϓϩηεΛ࠶ىಈ͢ΔλεΫʢcapistranoʣ • جຊతʹɺࠩΛө͢Δ࣌ʹຖճ࣮ߦ͢Δඞཁ͕͋Δ • ߹ܭ
3,500 workers • Redis server 6 * 4 ports • Batch server 50 * 1ʙ4 workers / port • ՝ • શөʹ20΄Ͳֻ͔Δɻ • workerͷࢦఆɺqueue໊ͷࢦఆ͕ύϥϝʔλԽ͞Ε͍ͯͳ͍ 17
ௐࠪɹresque:restart ಈ࡞ Batch 1 worker worker worker worker worker worker
ɾɾɾ worker worker worker worker worker worker worker worker worker worker worker worker worker worker worker worker worker worker Batch 2 worker worker worker (Redis 1 port 1) (Redis 2 port 4) 18
Batch 1 worker worker worker worker worker worker ɾɾɾ worker
worker worker worker worker worker worker worker worker worker worker worker worker worker worker worker worker worker Batch 2 worker worker worker ௐࠪɹresque:restart ಈ࡞ (Redis 1 port 1) (Redis 2 port 4) 19 STOP
Batch 1 worker worker worker worker worker worker ɾɾɾ worker
worker worker worker worker worker worker worker worker worker worker worker worker worker worker worker worker worker Batch 2 worker worker worker worker ௐࠪɹresque:restart ಈ࡞ (Redis 1 port 1) (Redis 2 port 4) 20 STOP parent
Batch 1 worker worker worker worker worker worker ɾɾɾ worker
worker worker worker worker worker worker worker worker worker worker worker worker worker worker worker worker worker Batch 2 worker worker worker worker fork worker worker worker ௐࠪɹresque:restart ಈ࡞ (Redis 1 port 1) (Redis 2 port 4) 21 STOP parent
Batch 1 worker worker worker worker worker worker ɾɾɾ worker
worker worker worker worker worker worker worker worker worker worker worker worker worker worker worker worker worker Batch 2 worker worker worker worker fork worker worker worker ௐࠪɹresque:restart ಈ࡞ (Redis 1 port 1) (Redis 2 port 4) 22 STOP parent STOP
Batch 1 worker worker worker worker worker worker ɾɾɾ worker
worker worker worker worker worker worker worker worker worker worker worker worker worker worker worker worker worker Batch 2 worker worker worker worker fork worker fork worker worker worker worker worker worker Ҏ߱ྻͰ࣮ߦ͞ΕΔ ௐࠪɹresque:restart ಈ࡞ (Redis 1 port 1) (Redis 2 port 4) 23 STOP STOP parent parent
ௐࠪɹresque:restart ಈ࡞ worker worker worker ɾɾɾ worker worker worker worker
worker worker worker worker worker worker worker worker worker worker worker Redis 1 port 1 queue 1 worker worker worker ɾɾɾ worker worker worker worker worker worker worker worker worker worker worker worker worker worker worker queue 2 ෳqueue͕૬Γ͍ͯ͠Δύλʔϯ queue 1 ͷޙʹ queue 2 ͕ྻͰ࣮ߦ͞ΕΔ 24
࣮ɹresque:restart • grosser/parallel Λར༻ͯ͠4ฒྻͰ࣮ߦ • ෳqueue͕૬Γ͍ͯ͠Δ߹ฒྻʹ • workerɺqueue໊ΛύϥϝʔλԽ • มߋ࣌ͷίετΛݮΒ͢
25
݁Ռɹresque:restart 20 → 3 85%ݮ Ϣʔβ༷ʹΑΓૣ͘ՁΛఏڙͰ͖ΔΑ͏ʹͳͬͨ 26
27 ࣄྫ3. DBαʔόߏஙͷࣗಈԽ
• MariaDB • શͯΦϯϓϨ • DC • 1DC͋ͨΓ150ऑ(backupؚΉ) → શମͰ300ʢ2017/08࣌ʣ
• ਨׂɺਫฏׂ DBαʔόߏ master slave backup master backup DC1 DC2 replication • εέʔϧΞοϓͳͲͷߏมߋɺϋʔυΣΞނোͳͲʹΑΓDBαʔό ͷߏங͕ߴ͍සͰൃੜ͢Δ 28
• Ϛγϯ֬อɺߏมߋʢDCৗறͷϝϯόʔͱ࿈ܞʣ • OSΠϯετʔϧʢPXEboot ͔ Cobbler + koanʣ • ॳظηοτΞοϓʢAnsibleʣ
• σʔλྖҬ࡞ ( mkfs.xfs, mount ) • MariaDBηοτΞοϓʢChefʣ • όοΫΞοϓͱϦετΞ Percona XtraBackup • σʔλݩbackup༻DBαʔό • ϨϓϦέʔγϣϯ • nagiosࢹೖΕ • (masterͷ߹) ϝϯςφϯε࣌ʹMHA(mysql-master-ha)ͰΓସ͑ DBαʔόߏஙʙαʔϏεΠϯ 29
• Ϛγϯ֬อɺߏมߋʢDCৗறͷϝϯόʔͱ࿈ܞʣ • OSΠϯετʔϧʢPXEboot ͔ Cobbler + koanʣ • ॳظηοτΞοϓʢAnsibleʣ
• σʔλྖҬ࡞ ( mkfs.xfs, mount ) • MariaDBηοτΞοϓʢChefʣ • όοΫΞοϓͱϦετΞ Percona XtraBackup • σʔλݩbackup༻DBαʔό • ϨϓϦέʔγϣϯ • nagiosࢹೖΕ • (masterͷ߹) ϝϯςφϯε࣌ʹMHA(mysql-master-ha)ͰΓସ͑ DBαʔόߏஙʙαʔϏεΠϯɹվળલ ख࡞ۀ ख࡞ۀ ख࡞ۀ 30
σʔλྖҬ࡞( mkfs.xfs, mount )ͷࣗಈԽ • طଘͷChefϨγϐʹՃ͢Δ • ཁ݅ • SSD,
ioDrive, ioMemoryͷΈ߹ΘͤʹରԠ͍ͨ͠ • ϚϯτରͷσόΠε໊Λਪఆ͍ͨ͠ • LVMΛར༻ͯ͠ෳσΟεΫΛଋͶ͍ͨ 31
σʔλྖҬͷରσΟεΫΛਪఆ͢Δ • SSD 1ຕ, ioMemory 1ຕ • /dev/fioa ͕ data
volume • SSD 1ຕ • /dev/sda7 ͳͲ͕ data volume • SSD 2ຕ • /dev/sdb ͕ data volume • ( /dev/sda root volume ) • SSD 3ຕ • /dev/sdb + /dev/sdc (LVM) ͕ data volume 32
• Ϛγϯ֬อɺߏมߋʢDCৗறͷϝϯόʔͱ࿈ܞʣ • OSΠϯετʔϧʢPXEboot ͔ Cobbler + koanʣ • ॳظηοτΞοϓʢAnsibleʣ
• σʔλྖҬ࡞ ( mkfs.xfs, mount ) • MariaDBηοτΞοϓʢChefʣ • όοΫΞοϓͱϦετΞ Percona XtraBackup • σʔλݩbackup༻DBαʔό • ϨϓϦέʔγϣϯ • nagiosࢹೖΕ • (masterͷ߹) ϝϯςφϯε࣌ʹMHA(mysql-master-ha)ͰΓସ͑ DBαʔόߏஙʙαʔϏεΠϯɹվળޙ 1ίϚϯυͰରతʹ࣮ߦͰ͖ΔΑ͏ʹͨ͠ γΣϧεΫϦϓτʹͨ͠ Chefద༻ʹؚΊͨ 33
• ຊ࣭తͳ࡞ۀʹूத͢ΔͨΊʹɺ • ʢࣄྫ3ʣࣗಈԽʹΑΓଐਓੑΛഉআ͠ɺΦϖϛεΛݮΒ͠ɺεέʔϧ ͍͢͠ӡ༻ʹ͢Δ ↓ • Ϣʔβ༷ʹΑΓߴ͍ՁΛఏڙ͢ΔͨΊʹɺ • ʢࣄྫ1ʣαʔϏεΛམͱ͞ͳ͍ͨΊʹઌճΓΛͯ͠ෛՙରࡦ͢Δ
• ʢࣄྫ2ʣσϓϩΠϑϩʔΛվળͯ͠ϦϦʔεʹֻ͔Δ࣌ؒΛ͘͢Δ ·ͱΊ 34
͋Γ͕ͱ͏͍͟͝·ͨ͠