Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
事業のスケールアウトを支える PHPで作る分散アーキテクチャ
Search
yuuki takezawa
December 11, 2020
Technology
4
4.9k
事業のスケールアウトを支える PHPで作る分散アーキテクチャ
事業の成長と、それにともなうアプリケーションの課題、
発生しがちな問題を追いながら、
解決策の一つであるCQRS導入について解説します。
分散システムで発生する問題についても軽く触れていきます。
yuuki takezawa
December 11, 2020
Tweet
Share
More Decks by yuuki takezawa
See All by yuuki takezawa
なぜAI時代に 「イベント」を中心に考えるのか? / Why focus on "events" in the age of AI?
ytake
4
1.4k
PHPでアクターモデルを活用したSagaパターンの実践法 / php-saga-pattern-with-actor-model
ytake
0
1.9k
PHP ステートレス VS ステートフル 状態管理と並行性 / php-stateless-stateful
ytake
0
210
PHPでアクターモデルを理解・体験しよう / Understand and experience the actor model in PHP
ytake
2
690
再考 アクターモデル/ reconsider actor model
ytake
0
1.4k
GoとアクターモデルでES+CQRSを実践! / proto_actor_es_cqrs
ytake
1
560
Phluxorでアクターモデルを 理解・体験しよう / toolkit-for-flexible-actor-models-in-php-phluxor
ytake
1
330
オブジェクトのおしゃべり大失敗 メッセージングアンチパターン集 / messaging anti-pattern collection
ytake
2
1.2k
DRE/SREのプラクティス融合によるクラウドネイティブなデータ基盤作り / dre_sre
ytake
0
900
Other Decks in Technology
See All in Technology
データエンジニアがこの先生きのこるには...?
10xinc
0
440
Function calling機能をPLaMo2に実装するには / PFN LLMセミナー
pfn
PRO
0
910
Azure SynapseからAzure Databricksへ 移行してわかった新時代のコスト問題!?
databricksjapan
0
130
AI ReadyなData PlatformとしてのAutonomous Databaseアップデート
oracle4engineer
PRO
0
160
What is BigQuery?
aizack_harks
0
130
about #74462 go/token#FileSet
tomtwinkle
1
290
生成AIとM5Stack / M5 Japan Tour 2025 Autumn 東京
you
PRO
0
200
Oracle Cloud Infrastructure:2025年9月度サービス・アップデート
oracle4engineer
PRO
0
380
VCC 2025 Write-up
bata_24
0
180
研究開発部メンバーの働き⽅ / Sansan R&D Profile
sansan33
PRO
3
20k
OpenAI gpt-oss ファインチューニング入門
kmotohas
2
940
AI駆動開発を推進するためにサービス開発チームで 取り組んでいること
noayaoshiro
0
130
Featured
See All Featured
RailsConf 2023
tenderlove
30
1.2k
Art, The Web, and Tiny UX
lynnandtonic
303
21k
Unsuck your backbone
ammeep
671
58k
Agile that works and the tools we love
rasmusluckow
331
21k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
9
580
[RailsConf 2023] Rails as a piece of cake
palkan
57
5.9k
Build The Right Thing And Hit Your Dates
maggiecrowley
37
2.9k
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.2k
Designing for Performance
lara
610
69k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
188
55k
Designing for humans not robots
tammielis
254
25k
Typedesign – Prime Four
hannesfritz
42
2.8k
Transcript
ࣄۀͷεέʔϧΞτΛࢧ͑Δ PHPͰ࡞ΔࢄΞʔΩςΫνϟ Yuuki Takezawa / ytake
Pro f i le • ᖒ ༗و / ytake •
ελʔϑΣεςΟόϧגࣜձࣾ • PHP, Hack, Go, Scala • Apache Hadoop, Apache Spark, Apache Kafka • twitter https://twitter.com/ex_takezawa • facebook https://www.facebook.com/yuuki.takezawa • github https://github.com/ytake
ελʔϑΣεςΟόϧגࣜձࣾ
ͦΜͳελʔϑΣεςΟόϧͰ ΤϯδχΞืूதʂʂʂ
Caution • ࠓճͷ༰શͯͷΞϓϦέʔγϣϯͰ ద༻Ͱ͖ΔͷͰ͋Γ·ͤΜ • ࣮ࡍʹຊਓ͕࠾༻͍ͯ͠Δͷ ϕʔεͷ༰Ͱ͢
Agenda • ΞϓϦέʔγϣϯͷͱ λʔχϯάϙΠϯτ • ղܾ͢ΔͨΊͷࣝ • ࢄτϥϯβΫγϣϯରࡦ
Ϗδωεͷͱ৫
খ͞ͳνʔϜ • σʔλϕʔεઃܭ + ORM etc ϑϨʔϜϫʔΫͰߏங͞ΕΔ ΞϓϦέʔγϣϯ
• গਓͷ։ൃऀͰߏ͞ΕΔ։ൃ৫
ෳͷνʔϜ • ૿͑ΔΞϓϦέʔγϣϯػೳ • ։ൃνʔϜͷ૿һ εΩϧ༷ʑ
ΞϓϦέʔγϣϯͱσʔλϕʔε • ORMͰN+1͕૿͑Δέʔε ൃߦͨ͠SQL ΞϓϦέʔγϣϯʹ߹͍ͬͯΔ͔ʁ • ϝϞϦɺCPUͳͲͷ૿ڧͰΓΔ
͕ޙճ͠ʹͳΔ͜ͱ
ͬͯ͠·͍͕ͪͳରԠ • σʔλऔಘ؆ུԽͷͨΊͷ σʔλϕʔεઃܭ(;͑Δඇਖ਼نԽ) • ͱΓ͋͑ͣϦετͰશ෦औಘ ͦΕ͔Β1ϨίʔυͣͭৄࡉΛऔಘ͠Α͏
ΞϓϦέʔγϣϯͱσʔλϕʔε • SELECT * FROM articles; SELECT * FROM
users WHERE user_id = ?; • ͜Ε͕͠10000݅औಘͰ ൃߦ͞Ε͍ͯͨΒʁ • ORM͕ѱ͍ͷͰͳ͘ దʹར༻Ͱ͖͍ͯͳ͍έʔε
େ͖͘νʔϜͱࣄۀͷ • ૿͑ଓ͚ΔΞϓϦέʔγϣϯػೳ • ։ൃνʔϜͷڊେԽ ෳͷνʔϜߏͱ ෳͷεςʔΫϗϧμ
ෆ҆ఆͳΞϓϦέʔγϣϯ • Ϩίʔυ૿Ճɾ࣮ίʔυ૿ՃʹΑΔ ͞ΒͳΔύϑΥʔϚϯεԼ • ͍͡ΊΒΕଓ͚Δσʔλϕʔε • ͋ͪͪ͜Ͱى͜Γ࢝ΊΔো
ࠔͳཁ݅ͷ࣮ݱ • ϦΫΤετ͝ͱʹϨεϙϯεΛΈཱͯ ΞϓϦέʔγϣϯͷύϑΥʔϚϯεѱԽ • ਖ਼نԽ͍͍ͨ͠ͷͷɺཁ݅ʹ߹Θͤ ͨσʔλऔಘίετ૿
ͬͯ͠·͍͕ͪͳରԠ • ݪҼΘ͔Γ·ͤΜ͕͘ͳ͖ͬͯͨͷͰ Ωϟογϡ͠·͢ -> ෳࡶԽ͢ΔΩϟογϡαʔόʔ • ݪҼΘ͔Γ·ͤΜ͕͘ͳ͖ͬͯͨͷͰ Ωϟογϡ͠·͢
-> ΩϟογϡαʔόʹՃ͑ͯCDNՃ
͏खஈ͕ͳ͍ɾɾɾʂ
ڊେͳΞϓϦέʔγϣϯ
σʔλॲཧͷෳࡶԽ Ϣʔβʔใมߋ Ϣʔβʔใআ Ϣʔβʔใ͕ݟ͔ͭΒͳ͍ͨΊ σʔλॲཧ͝ͱʹ"1*ΞΫηε ͋ͦ͜ͱͦ͜Ͱใ͕ҧ͏ʂ Ͳͷσʔλ͕ຊʁ શͯͷΞϓϦέʔγϣϯ͔Β
Ωϟογϡͳ͠ͰΞΫηε ৗʹߴෛՙঢ়ଶʹ
ࢭΊΒΕͳ͍ ϏδωεͷՃ
ฐ • ϦϦʔε༏ઌͷͨΊɺ ܧ͗͠ͷΞϓϦέʔγϣϯ • εςʔΫϗϧμ૿Ճʹ͏ ΞϓϦέʔγϣϯͷෳࡶԽ
• খதنͷΞϓϦέʔγϣϯ࣌ͷ ઃܭͱ࣮༝དྷͷෆ۩߹͕૿Ճ
σʔλઃܭ༝དྷͷ • େྔσʔλͷϑϧεΩϟϯ • INDEXෆͷͨΊͷύϑΥʔϚϯεԼ • γϯϓϧͳߏނͷػೳՃ࣌ͷ ΫΤϦෳࡶԽ
࣮ίʔυ༝དྷͷฐ • ػೳՃͷͨΊͷௐࠪʹ2ϲ݄ • ͞·͟·ͳཁҼͷੵΈॏͶʹΑΓ བྷΈ߹ͬͨίʔυͰϞνϕʔγϣϯμϯ • ͕͔͔࣌ؒͬͯ͠·͏͕ނɺ
ϏδωενʔϜʹ·ͣҰݴ ʮ͕͔͔࣌ؒΔͷͰͰ͖·ͤΜʯ
ͦͷ݁Ռ • Ϗδωεͷػձଛࣦ • γϡϦϯΫ࢝͠ΊΔࣄۀ • ଞࣾʹෛ͚ͯ͠·͏ࣄۀ • څ༩্͕͕Βͳ͍ɾɾ
͜ΕͰࣄۀ͕εέʔϧ͠ͳ͍ʂ
ࣄۀ͢Δͷ • ΞϓϦέʔγϣϯϦϦʔε͔ͯ͠Β • ఆ֎ͷΛ͛Δ WebΞϓϦέʔγϣϯ • ͞·͟·ͳϏδωεͷՄೳੑΛߟྀͨ͠
σʔλઃܭ
Λࢧ͑Δʹʁ • ఆظతͳσʔλϕʔεϦϑΝΫλϦϯάɺ ΞϓϦέʔγϣϯͷϦϑΝΫλϦϯά ͕࣮ࢪͰ͖Δ͔ • ͋Γͱ͋ΒΏΔՄೳੑΛఆͨ͠σʔλ ઃܭෆՄೳ 27
ΞϓϦέʔγϣϯͰى͜Δ • ਖ਼نԽ͞Εͨςʔϒϧͱ ඇਖ਼نԽςʔϒϧͷઓ͍ • ෳࡶԽ͢Δॻ͖ࠐΈॲཧͱଟൃ͢ΔN+1 • σʔλϞσϧͱυϝΠϯϞσϧ͕ҟͳΔ
Α͋͘ΔN+1 • Λऔಘ͠ ҬɾΩονϯใΛऔಘ • ΠΠωɺΫνίϛऔಘ͠ͳ͚Ε...
public function run(): \Generato r { foreach ($repository->findAll() as $row)
{ yield new ReadProductTransfer ( $row , $this->kitchenRepository->find($row->getId()) , $this->areaRepository->find($row->getId() ) ) ; } }
͜Μͳςʔϒϧઃܭͨ͠هԱ͋Γ·ͤΜ͔ʁ • UIΛߏ͢Δཁૉ͕औಘ͍͢͠ ςʔϒϧઃܭ • JOIN͢Δͱ͘ͳΔʁ ͳΒϫΠυΧϥϜઃܭͩ
͜Μͳςʔϒϧ͋Γ·ͤΜ͔ʁ • ͳʹ͔ͷεςʔλεΛฦ͢ʹ ͋ͷΧϥϜͱ͜ͷΧϥϜͱ͋ΕΛɾɾɾɻ • ϏδωεϩδοΫ͕ςʔϒϧʹ͋Δ • ΧϥϜ໊ͱ༻్͕શ͘ผ
ΞϓϦέʔγϣϯͰى͜Δ • ඇਖ਼نԽςʔϒϧಛఆͷཁ݅Ͱղܾ Ͱ͖Δ͕ɺͦΕҎ֎ʹ͍͠ɻ σʔλநग़ܥɺ αʔϏε֦େɺ༷มߋͳͲʹແཧ͕ ͋Δ
ཁ݅ͱσʔλߏͷࠩ ඞͣ͋Δ
ॻ͖ࠐΈͱಡΈࠐΈͷҧ͍ ॻ͖ࠐΈ ಡΈࠐΈ Ұ؏ੑɾՄ༻ੑ τϥϯβΫγϣϯΛ༻ ͍ͯॻ͖ࠐΈΛߦ͏ Ұ؏ੑॏࢹ ݁Ռ߹ੑͱՄ༻ੑ σʔλ ਖ਼نԽ
ඇਖ਼نԽ εέʔϥϏϦςΟ Ұൠతʹ εέʔϥϏϦςΟ ॏཁͰͳ͍ ଟ͘ൺॏΛΊ͓ͯΓ εέʔϥϏϦςΟ ॏཁ
ߟ͑ΔϙΠϯτ • ॻ͖ࠐΈॲཧͰɺಡΈࠐΈཁ݅ʹରԠ͢Δ ͨΊͷॲཧ͕ଟ͍ • ಡΈࠐΈཁ݅ΛΒͳ͚Εॻ͖ࠐΊͳ͍ • Ϩεϙϯεͱσʔλߏ͕͋·Γʹҧ͍ ͗͢Δ
ߟ͑ΔϙΠϯτ • σʔλͷਖ਼͠͞ͱཁ݅Ϩϕϧͷਖ਼͠͞ ҧ͏ͷ • ͲͪΒ͔ʹدͤͨઃܭʹ͢Δɺ Ͱͳ྆͘ํΛͰ͖Εγϯϓϧʹ
ϛυϧΣΞϨϕϧͰ
ॻ͖ࠐΈଟͷΞϓϦέʔγϣϯ • ॻ͖ࠐΈʹڧ͘ɺ εέʔϧ͕༰қͳσʔλϕʔε Cassandra, DynamoDB etc
ಡΈࠐΈଟͷΞϓϦέʔγϣϯ • RDBMSͷΈͰे • LIKEݕࡧͳͲElasticsearch, Solr
ղܾɺͰ͖ͳ͍ɾɾ • ϛυϧΣΞϨϕϧͰͷղܾํ๏Ͱɺ ΞϓϦέʔγϣϯࣗମ͕࣋ͭ ෳࡶ͞ղܾͰ͖ͳ͍ɻ • ύϑΥʔϚϯε໘ͰͷվળͰ͖Δ͕ɺ
ࣄۀͷΛࢧ͑ΔεϐʔσΟ͞ͳ͍
ΞϓϦέʔγϣϯϨϕϧͷ՝
ΞϓϦέʔγϣϯϨϕϧͰͷ՝ • ੳΛߦΘͳ͍͜ͱʹΑΔޡͬͨ൚༻Խ • ෳͷίϯςΩετ͕ࠞࡏ • ͳΜͰ͠Α͏ͱ͢Δॲཧ
ڥք͚ΒΕͨίϯςΩετ ໊ ѻ͍ͬͯΔΩονϯళฮ ஈ ൢചظؒͰ͢
ڥք͚ΒΕͨίϯςΩετ QSPEVDU/BNF LJUDIFO/BNF QSJDF TBMFT1FSJPE
ڥք͚ΒΕͨίϯςΩετ ໊ ݸ ૹઌͰ͢
ڥք͚ΒΕͨίϯςΩετ QSPEVDU/BNF LJUDIFO/BNF QSJDF TBMFT1FSJPE RVBOUJUZ TJQQJOH"EESFTT
ڥք͚ΒΕͨίϯςΩετ ໊ ஈͰ͢
ڥք͚ΒΕͨίϯςΩετ QSPEVDU/BNF LJUDIFO/BNF QSJDF TBMFT1FSJPE RVBOUJUZ TJQQJOH"EESFTT
ڥք͚ΒΕͨίϯςΩετ • ͱ͍͏ݴ༿Ͱ༰͕ҟͳΔ • ΞϓϦέʔγϣϯͰଟʑ • ڞ௨ԽͰ͖ΔͷͰͳ͍
ڥք͚ΒΕͨίϯςΩετ • ྫ͑ɺΛࢦ͢ݴ༿ͱ DB্ͷproductsςʔϒϧҰக͠ͳ͍ έʔε͕ଟ͍ • ͲͪΒ͔ʹ߹ΘͤΒΕΔͷͰͳ͍ͱ
ೝࣝ͢Δ͜ͱ
ॻ͖ࠐΈͱಡΈࠐΈΛ ͯ͠ΈͯͲ͏͔
CQRS
CQRS • ॻ͖ࠐΈϞσϧͱಡΈࠐΈϞσϧΛִ • υϝΠϯϞσϧͷ͚ͩͰͳ͘ σʔλετΞ͢ΒཧతʹผʹՄೳ ؔ৺ࣄͷΛపఈ
• DDDʹ͓͚ΔಡΈࠐΈͱॻ͖ࠐΈͷࠩΛղܾ͢Δ ύλʔϯ
CQRS
CQRS ͳΜΒ͔ͷมॲཧΛ௨ͯ͡ 3FBEͷσʔλΛߋ৽
CQRS • CommandͱReadʹڥքઢ͕͋Δ • CommandͱRead ಉ͡ϦϙδτϦɺϢʔεέʔεͱ͠ͳ͍ • ಉ͡ςʔϒϧࢀর͠ͳ͍
σʔλϕʔεͰ͖Εʁ
େ͖͘ͳͬͨαʔϏεͰղܾ͞ΕΔ • ෳࡶԽ͍ͯͨ͠ಡΈࠐΈϞσϧͷ ύϑΥʔϚϯεΛվળ • ಡΈࠐΈϞσϧʹؔ͢Δ εέʔϥϏϦςΟ্
ҙ • CQRSಛఆͷػೳʹͷΈద༻Մೳ ΞϓϦέʔγϣϯશͯʹద༻͢ΔͷͰ ͳ͍ • ॻ͖ࠐΈϞσϧͱಡΈࠐΈϞσϧͷ͕ࠩΑ ͘Θ͔Βͳ͍
-> ཁ݅ͷੳΛ·ͣ͠·͠ΐ͏
CQRSʹΑͬͯղܾ͞ΕΔ • ॻ͖ࠐΈϞσϧCUDΛ୲͠ɺ υϝΠϯϞσϧͷ࣮Λߦ͏ • ಡΈࠐΈϞσϧͷ୯७Խ DTOͷΈ
CQRSʹΑͬͯղܾ͞ΕΔ • ಡΈࠐΈϞσϧɺཁ݅ʹ߹Θͤͨ ͞·͟·ͳσʔλϕʔεΛར༻͠ ಡΈࠐΈϞσϧͷύϑΥʔϚϯεΛվળ • ॻ͖ࠐΈϞσϧಉ༷ʹ
ཁ݅ʹ߹ΘͤͨσʔλϕʔεΛར༻
ྫ • ϥϯΩϯάॲཧ ͋Δظؒ·ͰͷσʔλΛͬͨ ϥϯΩϯάΛੜ • ٻσʔλͷੜ
ͳͲ
ϥϯΩϯά࡞ • ϦΫΤετຖʹϥϯΩϯά࡞ -> εέʔϧ͠ͳ͍ • ྫ͑1ԯલޙͷશσʔλʹରͯ͠
ΫΤϦΛ͛ͯऔಘ͢Δ
ͷϥϯΩϯάྫ • ྫ͑ ͦͷͷΛѻ͏Ϟσϧͱ ϥϯΩϯάΛߏ͢ΔͷϞσϧΛ ڞ௨Խͯ͠͠·͏
ͷϥϯΩϯάྫ • ྫ͑ ͦͷͷΛѻ͏Ϟσϧͱ ϥϯΩϯάΛߏ͢ΔͷϞσϧΛ ڞ௨Խͯ͠͠·͏
-> વμϝ
ϥϯΩϯά࡞ղܾ • લ·ͰͷσʔλΛͬͯ ϥϯΩϯάΛ࡞Δཁ݅ͷ߹ ʢཁ݅ʹΑͬͯมΘΓ·͢ʣ • σʔλͷߏཁૉෆมͰ
ੜ͢Δඞཁͳ͍ ࣄલʹσʔλΛੜ͠ɺϦʔυΛ୲͢Δσʔλ ϕʔεʹอ࣋
ϥϯΩϯά࡞ղܾ • ϥϯΩϯάʹ͍ͭͯͷ͕ࣝͳ͘ͱ ಘΒΕΔ͜ͱ͕Ͱ͖Δ • ElasticsearchͷΤΠϦΞεͳͲΛ ར༻͢Δ͜ͱͰ༰қʹରԠՄೳ
ϥϯΩϯά࡞ղܾ • ϥϯΩϯάੜʹෆ۩߹͕͋ͬͨ߹ɺ ࠶ੜ͢Εྑ͍ • ো͕͋ͬͯ࠶࣮ߦ͢ΕΑ͍
CQRS ར
CQRS ར • োੑͷ্ • εέʔϥϏϦςΟ • ޮͷྑ͍σʔλϕʔεͷબ • పఈͨؔ͠৺ͷ
CQRS ܽ
CQRS ܽ • ҰͭҰͭͷػೳγϯϓϧ ߏ͢Δཁૉ͕૿͑ΔͨΊશମͰݟΔͱ ෳࡶԽ • ϨϓϦέʔγϣϯͷλΠϜϥά
ෳࡶԽ • CUDΞϓϦέʔγϣϯ • RΞϓϦέʔγϣϯ • ಡΈࠐΈϞσϧߋ৽ΞϓϦέʔγϣϯ
ෳࡶԽ • ѻ͏σʔλϕʔε͕૿͑Εɺ ͦΕͧΕͷσʔλϕʔεʹ߹Θͤͨ ཧɺӡ༻ํ๏͕ඞཁ • ։ൃ࣌ʹෳͷσʔλϕʔεͷ͕ࣝ
ඞਢ
ϨϓϦέʔγϣϯͷλΠϜϥά • γϯϓϧͳϥϯΩϯάͳͲͳ͠ • ϦΞϧλΠϜੑ͕ཁٻ͞ΕΔॲཧ ྫ) ͕ొ͞ΕͨΒଈ
ݕࡧΫΤϦͰώοτͰ͖Δ༷ʹͯ͠ʂ
ϨϓϦέʔγϣϯͷλΠϜϥά • ͍͍ͶϘλϯΛԡͨ͠ΒΠϯΫϦϝϯτ/ σΫϦϝϯτͤͯ͞ɺ͍͍ͶॱͰιʔτ • ϝοηʔδ͕ߘ͞ΕͨΒɺ ϑΥϩϫʔશһʹϦΞϧλΠϜͰ௨
CQRS͚ͩͰղܾ͕Ͱ͖ͳ͍ • DBͷτϦΨʔͳͲΛ༻͍ͯมߋΛݕ ҟͳΔσʔλϕʔεΛબ͢Δͱ ରԠෆՄೳ • ϦʔυϞσϧߋ৽༻ϓϩηεΛ
༻ҙ͠ͳ͚ΕͳΒͳ͍ ͕ɺมߋͷݕ͕͏·͘Ͱ͖ͳ͍
ྫ֎ • Debezium • DynamoDB streams • LinkedIn Databus
ͳͲॻ͖ࠐΈΛݕͯ͠௨Մೳ
CQRS͚ͩͰղܾ͕Ͱ͖ͳ͍ • ҟͳΔσʔλϕʔεͷίϛοτ • 2ϑΣʔζίϛοτରԠ͍ͨ͠Ί ආ͚ͳ͚ΕͳΒͳ͍
ϑϨʔϜϫʔΫͰղܾͰ͖Δ͡ΌΜʂ • ྫ͑Laravel QueueɺPHPͷΦϒδΣΫτΛ γϦΞϥΠζ͠QueueʹಥͬࠐΜͩ • पลγεςϜ͕PHPͩͱݶΒͳ͍
Event Sourcing
Event Sourcing • ΠϕϯτΛهͯ͠࠶ݱ͢Δύλʔϯ • ΠϕϯτΛΠϕϯτετΞʹอଘ͠ਅͷιʔεʹ • ه͞ΕͨΠϕϯτ͔ΒΦϒδΣΫτΛ෮ݩ • Πϕϯτෆม
Event Sourcing • ಡΈࠐΈ͕ར༻͢Δσʔλϕʔεͷ өʹඞਢ • ৴པͰ͖Δਅͷσʔλιʔεʹ ΠϕϯτετΞʹσʔλ͕͋Εྑ͍
Message Brokerબఆ • PubSubͰشൃੑͷͳ͍ͷΛબ͢Δ • ϝοηʔδอ͕ՄೳͰɺ࠶ݱ͢Δ͜ͱ ͕ՄೳͳͷΛ࠾༻͢Δͷ͕·͍͠ • εέʔϥϒϧͰ͋Δ͜ͱ
͓͢͢Ίʁ • Message BrokerεέʔϥϏϦςΟॏࢹ • ۙͷΠϕϯτΛ͙͢ʹऔಘͰ͖Δͷ • ۤ࿑ͨ͘͠ͳ͚ΕApache Kafka
(AWS MSK / Con f l uent ͳͲ)
Event Sourcing CQRS
CQRS
CQRS σʔλߋ৽͕ൃੜʂ ৽͍͠σʔλૹΓ·͢Ͷ
ղܾͰ͖Δ
ෳࡶ͔ͭϋΠύϑΥʔϚϯεͳ ݕࡧ
N+1ͳͲʹΑΔύϑΥʔϚϯεྼԽ εφοϓγϣοτతʹσʔλΛ ॻ͖ࠐΈ MBTUJOTFSU*%͕Ͳ͏͍͍ͯͨ͠߹ͳͲ
N+1ͳͲʹΑΔύϑΥʔϚϯεྼԽ %#ॻ͖ࠐΈྃޙɺ ಛఆͷΠϕϯτΛൃߦ
N+1ͳͲʹΑΔύϑΥʔϚϯεྼԽ ಡΈࠐΈϞσϧߋ৽ϓϩηε͕ ΠϕϯτΛফඅ
N+1ͳͲʹΑΔύϑΥʔϚϯεྼԽ &MBTUJDTFBDIॻ͖ࠐΈ ಛఆͷϨίʔυͷΈॻ͖͑Δ ྫ͑ϥΠΫɺίϝϯτͳͲ
N+1ͳͲʹΑΔύϑΥʔϚϯεྼԽ ಡΈࠐΈγϯϓϧʹ ΠϯσοΫεʹ͍߹ΘͤΔͷΈ ෳࡶͳܭࢉॲཧߦΘͳ͍
ϝϦοτ • ॴҦεϚʔτUIύλʔϯΛ ଞʹӨڹΛ༩͑Δ͜ͱͳ࣮͘ݱ • ॻ͖ࠐΈͰඞཁͱ͞ΕΔਖ਼نԽΛ่͢͜ͱͳ͘ ରԠՄೳ •
ಡΈࠐΈΛεέʔϧ͍ͤ͢͞
ϝϦοτ • ಡΈࠐΈϞσϧͷߋ৽ॲཧࢸͬͯ؆୯ • ߹ʹΑͬͯϏδωεϩδοΫΛ࣮ ͢Δ͜ͱ͋ΓɺෳࡶʹͳΒͳ͍Α͏ʹ ҙ͢Δ
ҙ • Ϩίʔυʹߋ৽ɺ আ͕ൃੜ͢Δ߹ μʔςΟϦʔυʹҙ
ࢄτϥϯβΫγϣϯ
ࢄτϥϯβΫγϣϯ • ಡΈࠐΈϞσϧߋ৽ϓϩηε͕ ෳͷσʔλϕʔεʹ ॻ͖ࠐ·ͳ͚Ε͍͚ͳ͍έʔε • 2ϑΣʔζίϛοτίετ͕ߴ͍
ࢄτϥϯβΫγϣϯ͘͠ɺෳࡶ • ཧతʹҟͳΔσʔλϕʔεͰ ॲཧ͕ࣦഊͨ͠߹ • औΓফ͢ॲཧΛΒͤͳ͚ΕͳΒͳ͍ • NoSQLKafkaͳͲʹͳ͍
ࢄτϥϯβΫγϣϯΛΘͳ͍ • ҰͭͷϓϩηεͰ ෳσʔλϕʔεॻ͖ࠐΉͷΛආ͚Δ • Ͳ͏ͯ͠ආ͚ΒΕͳ͍߹ ϚΠΫϩαʔϏεΞʔΩςΫνϟͷ
τϥβΫγϣϯରࡦͷҰͭɺSagaΛར༻
ίϨΦάϥϑΟͷαʔΨ डΠϕϯτΛൃߦ
ίϨΦάϥϑΟͷαʔΨ ΩονϯαʔϏε͕ डΠϕϯτΛফඅ 1&/%*/(ঢ়ଶͱ͢Δ
ίϨΦάϥϑΟͷαʔΨ ΩονϯαʔϏε͕ ༻ҙΠϕϯτΛൃߦ
ίϨΦάϥϑΟͷαʔΨ ༻ҙΠϕϯτΛফඅ ΫϨδοτܾࡁΛ࣮ߦ
ίϨΦάϥϑΟͷαʔΨ ձܭαʔϏε͕ ܾࡁྃΠϕϯτΛൃߦ
ίϨΦάϥϑΟͷαʔΨ ΩονϯαʔϏε͕ ܾࡁྃΠϕϯτΛফඅ ࠷ऴతͳΠϕϯτΛऔಘ͢Δ·Ͱ "8"*5*/(ঢ়ଶͱ͢Δ
ίϨΦάϥϑΟͷαʔΨ डαʔϏε͕ ܾࡁྃΠϕϯτΛফඅ
ίϨΦάϥϑΟͷαʔΨ डαʔϏε͕ डΛਖ਼ৗऴྃͱݟ၏͠௨
ίϨΦάϥϑΟͷαʔΨ डਖ਼ৗऴྃΛফඅ͠ɺ Φʔμʔ௨ΓͷྉཧΛ։࢝
ίϨΦάϥϑΟͷαʔΨ ϝϦοτ • ର͕গͳ͘ɺγϯϓϧͳॲཧͷϑϩʔ ʹ࠷ద • ॲཧͷ͕ࢄ͍ͯ͠ΔͨΊ ୯Ұোͳ͠
ίϨΦάϥϑΟͷαʔΨ σϝϦοτ • ࢄ͍ͯ͠Δ͕ނʹΘ͔Γʹ͍͘ • ॥ґଘ • ݁߹ςετͷқ͕ߴ͍ • ؔ͢ΔαʔϏεͷΠϕϯτશͯαϒεΫ
ϥΠϒ͢Δඞཁ͕͋Δ
ΦʔέετϨʔγϣϯͷαʔΨ डΠϕϯτΛൃߦ
ΦʔέετϨʔγϣϯͷαʔΨ ΩονϯαʔϏε͕ डΠϕϯτΛফඅ 1&/%*/(ঢ়ଶͱ͢Δ
ΦʔέετϨʔγϣϯͷαʔΨ ΩονϯαʔϏε͕ ༻ҙΠϕϯτΛൃߦ
ΦʔέετϨʔγϣϯͷαʔΨ ΦʔέετϨλʔͱͯ͠ ༻ҙΠϕϯτΛফඅ
ΦʔέετϨʔγϣϯͷαʔΨ ձܭαʔϏεʹ ΫϨδοτܾࡁґཔΠϕϯτΛ ൃߦ
ΦʔέετϨʔγϣϯͷαʔΨ ΫϨδοτܾࡁґཔΠϕϯτΛ ফඅ ܾࡁΛߦ͏
ΦʔέετϨʔγϣϯͷαʔΨ ΫϨδοτܾࡁྃΠϕϯτΛ ൃߦ
ΦʔέετϨʔγϣϯͷαʔΨ ΫϨδοτܾࡁྃΠϕϯτফඅ ΩονϯαʔϏεʹܾࡁྃΠϕ ϯτΛൃߦ
ΦʔέετϨʔγϣϯͷαʔΨ ϝϦοτ • ॥ґଘͳ͠ • ؔ͢ΔαʔϏεͷΠϕϯτΛαϒεΫ ϥΠϒ͢Δඞཁ͕ͳ͍ • ίϨΦάϥϑΟΑΓεςʔλεΛ࣋ͨ ͳ͍ͨΊɺϩδοΫ͕୯७ʹ
ΦʔέετϨʔγϣϯͷαʔΨ ϝϦοτ • ΦʔέετϨʔλʹϏδωεϩδοΫ͕ ूத͘͢͠ͳΔ ίʔσΟωʔτ͚ͩΛߦ͏Α͏ʹ ϏδωεϩδοΫΛഉআ͢Δඞཁ͋Γ
• ϫʔΫϑϩʔܗʹͳΔͨΊɺ োʹͳΔՄೳੑ͋Γ
αʔΨͷҙ • ߋ৽σʔλͷࣦ • μʔςΟϦʔυ • ෮ෆೳಡΈऔΓ
αʔΨͷҙ • ࢄॲཧԞ͕ਂ͘қ͕ߴ͍ • PHPͰ࣮ݱͤ͞Δͷ͓͢͢Ί͠·ͤΜ • ಘҙͳݴޠɺΈʹͤΑ͏
ES+CQRSͷ ΤοηϯεΛऔΓೖΕΔ
ES+CQRSͷൃల • DDD͚ͷղܾύλʔϯͰ͋Δ͕ɺ ۙͰΤοηϯεΛऔΓೖΕͨ LambdaɺKappaΞʔΩςΫνϟ͕͋Δ (େنσʔλॲཧ͚ not
Web App)
KappaΞʔΩςΫνϟ
KappaΞʔΩςΫνϟ
·ͱΊ
·ͱΊ • Ϗδωεʹؔ৺Λ࣋ͭ͜ͱ͕ୈҰ • نʹ߹Θͤͨσʔλઃܭ ఆظతͳϦϑΝΫλϦϯά ཁ݅ͷੳͰϏδωεΛࢧ͑Δ •
దࡐదॴΛݟۃΊΔٕज़
ࣄۀΛࢧ͍͑ͯ͜͏