Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Developer Productivity in Cookpad
Search
Issei Naruta
June 03, 2015
Technology
174
42k
Developer Productivity in Cookpad
クックパッドはなぜ開発しやすいのか
At AWS Summit Tokyo 2015 Developer Conference
2015/06/03
Issei Naruta
June 03, 2015
Tweet
Share
More Decks by Issei Naruta
See All by Issei Naruta
mairuでつくるクレデンシャルレス開発環境 / Credential-less development environment using Mailru
mirakui
5
540
インフラからSREへ
mirakui
32
13k
データパイプラインをなんとかした話 / Improving the Data Pipeline in IVRy
mirakui
1
600
Cookpad TechConf 2022 Keynote
mirakui
0
3.9k
ドライイーストを使わずにパンを焼けるか? 〜天然酵母のパン作りを支える技術〜
mirakui
0
3.5k
関東積みについて/How to build Kanto-stacking
mirakui
0
730
先折りGTRについて/How to build left-GTR transitions
mirakui
3
1.1k
サービス開発速度に着目したソフトウェアアーキテクチャ/Software architecture for effective service development at Cookpad
mirakui
5
7.2k
Beyond the Boundaries
mirakui
1
1.4k
Other Decks in Technology
See All in Technology
大企業でもできる!ボトムアップで拡大させるプラットフォームの作り方
findy_eventslides
1
830
S3を正しく理解するための内部構造の読解
nrinetcom
PRO
2
150
Sansanが実践する Platform EngineeringとSREの協創
sansantech
PRO
2
920
NIKKEI Tech Talk #41: セキュア・バイ・デザインからクラウド管理を考える
sekido
PRO
0
140
LLM-Readyなデータ基盤を高速に構築するためのアジャイルデータモデリングの実例
kashira
0
270
2025年 開発生産「可能」性向上報告 サイロ解消からチームが能動性を獲得するまで/ 20251216 Naoki Takahashi
shift_evolve
PRO
1
200
ハッカソンから社内プロダクトへ AIエージェント「ko☆shi」開発で学んだ4つの重要要素
sonoda_mj
2
110
AI-DLCを現場にインストールしてみた:プロトタイプ開発で分かったこと・やめたこと
recruitengineers
PRO
2
160
寫了幾年 Code,然後呢?軟體工程師必須重新認識的 DevOps
cheng_wei_chen
1
1.5k
会社紹介資料 / Sansan Company Profile
sansan33
PRO
11
390k
エンジニアとPMのドメイン知識の溝をなくす、 AIネイティブな開発プロセス
applism118
4
1.3k
子育てで想像してなかった「見えないダメージ」 / Unforeseen "hidden burdens" of raising children.
pauli
2
270
Featured
See All Featured
Statistics for Hackers
jakevdp
799
230k
The Illustrated Children's Guide to Kubernetes
chrisshort
51
51k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.3k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.6k
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
1
100
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
9.8k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
22k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
141
34k
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.5k
How STYLIGHT went responsive
nonsquared
100
6k
Site-Speed That Sticks
csswizardry
13
1k
Building Adaptive Systems
keathley
44
2.9k
Transcript
ΫοΫύουͳͥ ։ൃ͍͢͠ͷ͔ ΫοΫύουגࣜձࣾాҰੜ "844VNNJU5PLZP
ాҰੜ ͳΔͨ ͍͍ͬͤ !NJSBLVJ ΫοΫύουגࣜձࣾ ΠϯϑϥετϥΫνϟʔ෦
ΫοΫύουʹ͍ͭͯ
.6#NP .14VTFST .DPPLJOHSFDJQFT ˞݄ݱࡏ !" # !
'VMM"84 20113݄ ౦ژϦʔδϣϯΦʔϓϯ 20118݄ DC͔ΒAWSҠߦ ✈
&$JOTUBODFT BUQFBL SFRTFD BUQFBL $
0QT %FWFMPQFST %FQMPZTEBZ ⚒ #
IUUQTTQFBLFSEFDLDPNB@NBUTVEBUIFSFDJQFGPSUIFXPSMETMBSHFTUSBJMTNPOPMJUI ΫοΫύουੈքҰڊେͳ ϞϊϦγοΫ3BJMTΞϓϦέʔγϣϯʢ͔͠Ε·ͤΜʣ
None
ʮ։ൃ͍͢͠ʯͱԿ͔
% ʮ։ൃ͠ʹ͍͘ʯঢ়ଶͷྫ ٕज़తͳʹΑͬͯΠϊϕʔγϣϯ્͕͞Ε͍ͯΔঢ়ଶ େྔͷϨΨγʔίʔυɺٕज़తෛ࠴ ςετ͋Δ͚Ͳৗʹ͍͔ͭ͘ Fail ͍ͯͯ͠ɺ ์ஔ͞Ε͍ͯΔ σϓϩΠ͕ଐਓతͰɺ͕͔͔࣌ؒΓ͗ͨ͢Γɺ ͨ·ʹࣦഊͨ͠Γ͢Δ
։ൃ͠ʹͯ͘͘Կ͕ѱ͍ʁ ݱָ͕Λ͍ͨ͠ ૉૣ͘ՁΛఏڙ͍ͨ͠
⚒ ։ൃ σϓϩΠ ςετ
։ൃ ⚒
None
None
αʔϏε։ൃͱԿͳͷ͔ ࡞͍ͬͯΔͷʮػೳʯͰͳ͘ʮαʔϏεʯʮϢʔβମݧʯ μϛʔσʔλͰͳ͘ຊ൪ͷσʔλΛͬͯ։ൃ͢Δ͖ &
ຊ൪ͱಉظͨ͠%#Ͱ։ൃ͢ΔϝϦοτ • Ϣʔβʔͱಉͷମݧ • ༧ظͤ͵σʔλʹΑΔόάʹؾ͖͍ͮ͢ • ॏ͍ΫΤϦʹؾ͖͍ͮ͢
'# ຊ൪%# ։ൃ%# ։ൃऀ .Z42- .Z42- NZTRMEVNQ ( # ։ൃऀͷ୭͔͕ؾ͕͍ͨ࣌ʹ
ຊ൪μϯϓσʔλ͔Β։ൃ DB Λߋ৽ ʢʹ1͘Β͍ʣ d
खಈߋ৽ํࣜͷ ݱߦͷσʔλͷΈͰൃੜ͢ΔΑ͏ͳΤϥʔʹؾ͖ͮʹ͍͘ ৽ணίϯςϯπʹؔ࿈ͨ͠ಈ࡞֬ೝ͕͠ʹ͍͘ ϢʔβͷମݧͱҟͳΔ
' ' ' # # # ຊ൪%# ։ൃ%# NBTUFS TMBWF
SFBE X SJUF ։ൃऀ .Z42- .Z42- ݱࡏ ։ൃऀৗʹຊ൪ͷ࠷৽σʔλ͕ೖͬͨDBͰ։ൃ
Ͳ͏Δͷ͔ ݒ೦ slave ʹॻ͖ࠐΜͩΒΩʔিಥͰ ϨϓϦέʔγϣϯΤϥʔʹͳΔͷͰʁ id ͕ຊ൪ͱͣΕͯ݁ہ͑ͳ͍σʔλʹͳΔͷͰʁ
JE OBNF ΧϨʔ ͔Β͋͛ ͡Ό͕ JE OBNF
ΧϨʔ ͔Β͋͛ ͡Ό͕ ͦ '# ຊ൪%# ։ൃ%# */4&35 ϨϓϦέʔγϣϯ ϥʔϝϯ ௨ৗɺslave ʹॻ͖ࠐΜͰ͠·͏ͱ AUTO_INCREMENT ͍ͯ͠Δ id ͕িಥ͢Δ
JE OBNF ΧϨʔ ͔Β͋͛ ͡Ό͕ JE OBNF
ΧϨʔ ͔Β͋͛ ͡Ό͕ ͦ ͏ͲΜ ੜᇙম͖ '# ຊ൪%# ։ൃ%# */4&35 ϨϓϦέʔγϣϯ AUTO_INCREMENT ʹڊେͳΦϑηοτΛઃఆ͢Δ͜ͱͰ ຊ൪ͱিಥ͠ʹ͘͘͢Δ ϥʔϝϯ
JE OBNF ΧϨʔ ͔Β͋͛ ͡Ό͕ JE OBNF
ΧϨʔ ͔Β͋͛ ͡Ό͕ ͦ ͏ͲΜ ੜᇙম͖ ຊ൪%# ։ൃ%# εςʔτϝϯτϕʔε ϨϓϦέʔγϣϯ ࠷৽ͷ݅Λʮমʯʹมߋ UPDATE recipes SET name=‘ম’ ORDER BY id DESC LIMIT 1 ম ম εςʔτϝϯτϕʔεϨϓϦέʔγϣϯͰ ։ൃ DB ͷσʔλ͕յΕ͍͢
JE OBNF ΧϨʔ ͔Β͋͛ ͡Ό͕ JE OBNF
ΧϨʔ ͔Β͋͛ ͡Ό͕ ͦ ͏ͲΜ ੜᇙম͖ ຊ൪%# ։ൃ%# ߦϕʔε ϨϓϦέʔγϣϯ ࠷৽ͷ݅Λʮমʯʹมߋ UPDATE recipes SET name=‘ম’ ORDER BY id DESC LIMIT 1 ম ম ߦϕʔεϨϓϦέʔγϣϯʹ͢Δ͜ͱͰ ։ൃ DB ͷσʔλ͕յΕʹ͘ͳΔ
ຊ൪%# ։ൃ%# ߦϕʔε ϨϓϦέʔγϣϯ εςʔτϝϯτϕʔε ϨϓϦέʔγϣϯ CJOMPH ม༻%# ߦϕʔεϨϓϦέʔγϣϯͰɺ όΠφϦϩάసૹྔ͕ڊେʹͳΓɺຊ൪ʹෛՙ͕͔͔ΔͨΊ
࣮ࡍʹதؒ DB Λ༻ҙ͠όΠφϦϩάΛม͍ͯ͠Δ
ϨϓϦέʔγϣϯఀࢭରࡦඞཁ ෆ߹ى͖ʹ͘͘Ͱ͖Δ͕ɺܾͯ͠ᘳͰͳ͍ͷͰ ϨϓϦ͕ΤϥʔͰࢭ·Δ͜ͱ͋Δ slave_skip_errors = ON Λઃఆͭͭ͠ɺ ఀࢭͨ͠Β skip ͯ͠࠶։͢ΔࢹεΫϦϓτΛӡ༻
ʢslave_skip_errors͚ͩͰ skip ͞Εͳ͍Τϥʔ͕͋ΔͨΊ…ʣ
' ' ' # # # ຊ൪%# ։ൃ%# NBTUFS TMBWF
SFBE X SJUF ։ൃऀ .Z42- .Z42- ։ൃऀৗʹຊ൪ͷ࠷৽σʔλ͕ೖͬͨDBͰ։ൃ
ຊ൪ڥͰ։ൃ͢Δ w
&BUZPVSPXOEPHGPPE ࣗͨͪͷαʔϏε͕ࣗͨͪϢʔβʹͳΔ͖ ♥
ඇϩάΠϯ ελοϑϢʔβ ͱͯ͠ϩάΠϯ ελοϑ͕ϩάΠϯ͢Δͱɺ ։ൃதͷϕʔλػೳ͕͍ͭ͘༗ޮʹͳΔ
ϕʔλػೳ ϦϦʔεൣғΛࢦఆͯ͠ެ։ ެ։ൣғͷྫ ελοϑͷΈʹެ։ ςετࢀՃϢʔβʹͷΈެ։ શମͷ10%ͷϢʔβʹެ։
αʔϏεͷՁΘͳ͍ͱ͔Βͳ͍ ͦͷՁͷԾઆਖ਼͔ͬͨ͠ͷ͔ʁ ຊ൪ʹϦϦʔε͠ͳ͍ͱɺϢʔβʹͬͯΒ͏͜ͱ͕Ͱ͖ͳ͍ ຊ൪ʹϦϦʔε͢Δʹຊ൪ͷ࣭ͷ ίʔυʢύϑΥʔϚϯεʣʹ্͛ͳ͚ΕͳΒͳ͍ʁ ˠඞཁͷͳ͍ػೳΛ࡞Γ͜ΜͰ͠·͏Մೳੑ͕͋Δ
ૣࣦ͘ഊΛ͢Δ ίʔυͷ࡞ΓࠐΈʹ࣌ؒΛ͔͚ΔΑΓɺ ૉૣ͘ެ։ͯ͠ԾઆΛݕূ͢ΔͨΊʹ࣌ؒΛ͏͖ *
$IBOLP ຊ൪ڥͰͷτϥΠˍΤϥʔΛࢧԉ͢Δ Rails ༻ gem Unit ͱ͍͏୯ҐͰطଘίʔυͷύονΛهड़ ࣭ͷ͍ίʔυΛຊ൪ʹ҆શʹग़ͤΔ IUUQTHJUIVCDPNDPPLQBEDIBOLP +
" # طଘͷίʔυ A ΛɺελοϑϢʔβͷΈʹରͯ͠ ϕʔλ൛ͷίʔυ B ʹஔ͖͍͑ͨ ͨͩ͠ɺB ݥతͳ࣮ͳͷͰɺྫ֎͕ൃੜ͢Δ͔͠Εͳ͍
طଘͷ$POUSPMMFSͷίʔυ ϕʔλ൛ͷίʔυ
ελοϑͳΒ# #Ͱྫ֎͕ى͖ͨΒ" ελοϑҎ֎ͳΒ" ϑϥάͰذ͍ͤͯ͘͞ͱίʔυ͕ԚΕ͍ͯ͘
ϕʔλػೳͷ6OJU طଘͷ$POUSPMMFSͷίʔυ " # Chanko ͰɺUnit ͱ͍͏ϑΝΠϧʹϕʔλػೳͷϩδοΫΛهड़͢Δ invoke ݅Λຬͨͨ͠߹ʹɺطଘϩδοΫ (A)
ͷΘΓʹ Unit (B) ͕࣮ߦ͞ΕΔ B ͕ྫ֎Λىͨ͜͠߹ɺݩͷ A ͕࣮ߦ͞ΕΔͨΊɺϢʔβʹΤϥʔ͕ฦΒͳ͍ JOWPLF݅
ແࣄʹՁ͕ೝΊΒΕͨΒ ຊ൪ͷ࣭ͷίʔυʹ্͛Δ طଘίʔυΛॻ͖͑ɺUnit ϑΝΠϧΛফ͢ ʢ௨শ Un-chankoʣ
$IBOLPͷӡ༻ঢ়گ 2011: Chanko ϦϦʔε + ಋೖ 2015: 200+ Chanko Units
• εςʔδϯά༻ͷαʔόଘࡏ͢Δ͕ɺར༻ස͍ • ։ൃதͷͷΛຊ൪ʹग़͢จԽ͕Ͱ͖͍ͯΔ
ςετ
ΫοΫύουͱ34QFD 1800+ files 21000+ examples (test cases) 7 min ,
5FTUTNFMMT ࣮ߦ͕͍࣌ؒ յΕ͍͢ʢίʔυͷมߋʹऑ͍ʣ Fail ͍͢͠ ࣮ߦڥͷґଘ -
3334QFD
. 3334QFD ͯ͘ɾ҆ͯ͘ɾ҆ఆͨ͠$* ෳͷ Spot Instance Λͬͯ RSpec Λฒྻ࣮ߦ ڧྗͳϑΥʔϧττϨϥϯε
IUUQTHJUIVCDPNDPPLQBESSSTQFD +
// / / TMBWF TMBWF XPSLFS XPSLFS XPSLFS ʜ /
ʜ ʜ ʜ / / / / NBTUFS ////ʜ
$*XPSLFSͷભҠ ۀ࣌ؒ֎ΛݮΒͯ͠ ίετݮ
&$4QPU*OTUBODF ͳΔ͘ϋΠεϖοΫͳΠϯελϯεΛ͍͍͕ͨߴՁ →Spot Instance ͷར༻ 0
&$4QPU*OTUBODF ʮ1࣌ؒ͋ͨΓͷ࠷େೖࡳՁ֨ʯΛࢦఆͯ͠ىಈ͢Δ ࢦఆͨ͠ʮ࠷େೖࡳՁ֨ʯΑΓ૬Ձ͕͚֨҆Εىಈ ىಈதʹ૬Ձ͕֨ʮ࠷େೖࡳՁ֨ʯΛ্ճͬͨ߹ɺ Πϯελϯεγϟοτμϯ͞ΕΔ ૬Ձ֨ OnDemand Ձ֨ΑΓߴ͘ͳΔ͜ͱ͋Δ ૬Ձ֨ AZ
͝ͱʹΑͬͯҟͳΔ
౦ژϦʔδϣϯͷͱ͋Δ";ʹ͓͚Δ 4QPU1SJDF DYMBSHF 0OEFNBOE I 3*ZBMMVQGSPOU I
DYMBSHF DYMBSHF DYMBSHF ˺ ˺ DYMBSHF DYMBSHF DYMBSHF ˺ ˺
Ұ൪ίετύϑΥʔϚϯε͕͍͍ ΠϯελϯεΛࣗಈతʹબ
ϑΥʔϧττϨϥϯε ͍͔ʹͯ͠GBJM͠ʹ͍͘$*ʹ͢Δ͔ ·Εʹࣦഊ͢ΔFYBNQMFʹରͯ͠ɿ ۭ͍͍ͯΔ worker Ͱࣗಈతʹ࠶࣮ߦ ҰͰ success ͢Ε success
ͱͯ͠ѻ͏ 4QPU*OTUBODFͷࣗಈγϟοτμϯʹରͯ͠ɿ ଞͷ worker Ͱࣗಈతʹ࠶࣮ߦ ผλΠϓͷΠϯελϯεΛىಈ͠࠶࣮ߦ
ׂΕ૭ཧ ݐͷ૭ׂ͕Ε͍ͯΔ֗ɺ࣏͕҆ѱԽ͢Δ ܰඍͳ൜ࡑΛపఈతʹऔΓక·Δ͜ͱͰ ڟѱ൜ࡑΛࢭͰ͖Δͱ͢Δڥ൜ࡑ্ֶͷཧ IUUQKBXJLJQFEJBPSHXJLJׂΕ૭ཧ -
$*͕ʮׂΕ૭ʯʹͳΒͳ͍Α͏ʹ ܰඍͳ͏ͪʹൃݟ͠ɺରॲ͢Δ • Ϗϧυ͕࣌ؒ͘ͳΔ • ͚ͯ͜Δςετͷ์ஔ • pending ঢ়ଶͳςετͷ์ஔ 1
௨ Fail ͨ͠ example ࡞ऀΛ blame ͯ͠νϟοτͰ௨ Fail ͬ͠ͺͳ͠ʹͤ͞ͳ͍
·Εʹ'BJM͢ΔςετΛݟ͚ͭΔ lBMMOJHIU$*z ۀ࣌ؒ֎ʹͣͬͱճ͠ଓ͚Δ CI success ͕͍ͱԿ͔͕͓͔͍͠
ඪ Ҏ Ҏ্͔͔ͬͨΒ௨ $*ͷϏϧυ࣌ؒΛࢹ
QFOEJOHʹͤͬ͞ͺͳ͠ͷςετͷ࡞ऀʹࣗಈ௨ IUUQTHJUIVCDPNDPPLQBEQFOEBYFT +
$*ӡ༻ͷ·ͱΊ • ༏Εͨ CI γεςϜΛ࡞Δ͜ͱΑΓɺ Ͳ͏ӡ༻͢Δ͔͕ॏཁ • Ϗϧυ࣌ؒɾ௨աɾίετͳͲͷ ࢦඪΛఆٛͯ͠ࢹ͠ɺ վળ͍ͯ͘͠
• ׂΕ૭ʹ͠ͳ͍ 2
σϓϩΠ
+ TVDDFTT -(5. QVMMSFRVFTU NFOUJPO EFQMPZ &$ (JU)VC &OUFSQSJTF #
EFWFMPQFS # SFWJFXFS $* +FOLJOT NFSHF
σϓϩΠϧʔϧʢҰ෦ʣ • CI Λύεͨ͠ϦϏδϣϯͷΈσϓϩΠͯ͠Α͍ • σϓϩΠίʔυΛ push ͨ͠։ൃऀ͕ࣗߦ͏ • Ӧۀ࣌ؒͷΈσϓϩΠՄೳ
• σϓϩΠޙ։ൃऀ͕ಈ࡞֬ೝ͠ɺ ෆ۩߹Λݟ͚ͭͨΒ͙͢ʹϩʔϧόοΫ͢Δ
σϓϩΠʹॏཁͳ͜ͱ • ଐਓతͰͳ͍͜ͱ • ਖ਼֬Ͱ͋Δ͜ͱ • ϩʔϧόοΫͰ͖Δ͜ͱ • ेʹ͍͜ͱ 3
ۙिؒͷσϓϩΠʹ͔͔ͬͨ࣌ؒ ฏۉඵ IPTUT
$BQJTUSBOP࣌ʢʙʣ capistrano2 + rsync_with_remote_cache
$BQJTUSBOPσϓϩΠͱ 1͔Βશʹ ssh + rsync σϓϩΠରϗετ͕૿͑Δͱ͘ͳ͍ͬͯ͘
σϓϩΠରϗετશʹTTI STZOD ˠσϓϩΠͷϘτϧωοΫʹ $BQJTUSBOP # / / / / /
/ / STZOD
.BNJZB
.BNJZB ϋΠεέʔϥϒϧͳߴσϓϩΠγεςϜ σϓϩΠରϗετΛ serf ͰΫϥελϦϯά Amazon S3 ܦ༝Ͱ Capistrano ޓͷσΟϨΫτϦߏ
IUUQTHJUIVCDPNTPSBINBNJZB +
/ $* UBSCBMM 4 $*͕௨ͬͨϦϏδϣϯͷίʔυ UBSCBMMͱͯ͠4ʹૹΒΕΔ
/ / / / / / / / $*͕௨ͬͨϦϏδϣϯͷUBSCBMM શ͕ৗʹࣗಈͰQVMM͍ͯ͠Δ
ʢ͜ͷ࣌Ͱ·ͩຊ൪ͷίʔυΓସΘ͍ͬͯͳ͍ʣ /
σϓϩΠͷࢦྩ4FSGΠϕϯτͱͯ͠(PTTJQϓϩτίϧͰ # !IVCPUEFQMPZQSPEVDUJPO
શͷϦϏδϣϯ͕ΓସΘΔ ʢϑΝΠϧ͋Β͔͡Ί͍ྃͯ͠ΔͨΊɺߴʹྃ͢Δʣ / / / / / / / /
/ / / / / / / / #
.BNJZBͷεέʔϥϏϦςΟ Mamiya σϓϩΠରϗετ૿Ճʹରͯ͠εέʔϥϒϧ ϗετ͕૿Ճͯ͠ʢ΄ͱΜͲʣ͘ͳΒͳ͍ ϑΝΠϧͷɿ S3 ͷεέʔϥϏϦςΟΛར༻ શͷϦϏδϣϯΓସ͑ࢦྩɿ Serf ΠϕϯτΛར༻
.BNJZBʹΑΔσϓϩΠ࣌ؒॖޮՌ ˠඵ DBQJTUSBOP NBNJZB DBQJTUSBOP NBNJZB
͓ΘΓʹ
⚒ ։ൃ σϓϩΠ ςετ
։ൃͷ͢͠͞Λอͭ ׂΕ૭Λ࡞Βͳ͍ͨΊʹɺऀͱࢦඪ͕ඞཁ 4
ʮ։ൃ͢͠͞ʯͷՁ • ։ൃ͔ΒσϓϩΠ·ͰͷαΠΫϧ͕ेʹ͚Εɺ ʮຊ൪ڥΛͬͨ։ൃʯ͕࣮ݱͰ͖Δ →Ϣʔβͱಉ͡ମݧͷதͰ։ൃ͢Δ • ։ൃ͢͠͞ʹࢿ͢ΔՁेʹ͋Δ • ݁Ռͱͯ͠։ൃ৫αʔϏε݈શͳঢ়ଶΛอͯΔ 'JO