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.8k
事業のスケールアウトを支える PHPで作る分散アーキテクチャ
事業の成長と、それにともなうアプリケーションの課題、
発生しがちな問題を追いながら、
解決策の一つであるCQRS導入について解説します。
分散システムで発生する問題についても軽く触れていきます。
yuuki takezawa
December 11, 2020
Tweet
Share
More Decks by yuuki takezawa
See All by yuuki takezawa
PHP ステートレス VS ステートフル 状態管理と並行性 / php-stateless-stateful
ytake
0
110
PHPでアクターモデルを理解・体験しよう / Understand and experience the actor model in PHP
ytake
2
250
再考 アクターモデル/ reconsider actor model
ytake
0
1k
GoとアクターモデルでES+CQRSを実践! / proto_actor_es_cqrs
ytake
1
410
Phluxorでアクターモデルを 理解・体験しよう / toolkit-for-flexible-actor-models-in-php-phluxor
ytake
1
250
オブジェクトのおしゃべり大失敗 メッセージングアンチパターン集 / messaging anti-pattern collection
ytake
2
1.1k
DRE/SREのプラクティス融合によるクラウドネイティブなデータ基盤作り / dre_sre
ytake
0
770
技術的負債と向き合う取り組みでよかったもの / positive_efforts_to_tackle_technical_debt
ytake
10
3.8k
アプリケーションエンジニアから強いデータエンジニアへの歩き方 / How to transition and become a Data Engineer from an Application Engineer
ytake
1
550
Other Decks in Technology
See All in Technology
プロダクトエンジニア構想を立ち上げ、プロダクト志向な組織への成長を続けている話 / grow into a product-oriented organization
hiro_torii
1
290
転生CISOサバイバル・ガイド / CISO Career Transition Survival Guide
kanny
3
1.1k
Culture Deck
optfit
0
480
Raycast AI APIを使ってちょっと便利な拡張機能を作ってみた / created-a-handy-extension-using-the-raycast-ai-api
kawamataryo
0
150
PHPカンファレンス名古屋-テックリードの経験から学んだ設計の教訓
hayatokudou
2
510
抽象化をするということ - 具体と抽象の往復を身につける / Abstraction and concretization
soudai
27
14k
OpenID BizDay#17 KYC WG活動報告(法人) / 20250219-BizDay17-KYC-legalidentity
oidfj
0
350
明日からできる!技術的負債の返済を加速するための実践ガイド~『ホットペッパービューティー』の事例をもとに~
recruitengineers
PRO
3
510
あれは良かった、あれは苦労したB2B2C型SaaSの新規開発におけるCloud Spanner
hirohito1108
2
770
JEDAI Meetup! Databricks AI/BI概要
databricksjapan
0
280
短縮URLをお手軽に導入しよう
nakasho
0
110
深層学習と古典的画像アルゴリズムを組み合わせた類似画像検索内製化
shutotakahashi
1
260
Featured
See All Featured
Scaling GitHub
holman
459
140k
Testing 201, or: Great Expectations
jmmastey
42
7.2k
StorybookのUI Testing Handbookを読んだ
zakiyama
28
5.5k
GitHub's CSS Performance
jonrohan
1030
460k
Building Better People: How to give real-time feedback that sticks.
wjessup
367
19k
Six Lessons from altMBA
skipperchong
27
3.6k
Building Adaptive Systems
keathley
40
2.4k
Docker and Python
trallard
44
3.3k
Designing for Performance
lara
604
68k
Measuring & Analyzing Core Web Vitals
bluesmoon
6
250
For a Future-Friendly Web
brad_frost
176
9.5k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
133
33k
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ΞʔΩςΫνϟ
·ͱΊ
·ͱΊ • Ϗδωεʹؔ৺Λ࣋ͭ͜ͱ͕ୈҰ • نʹ߹Θͤͨσʔλઃܭ ఆظతͳϦϑΝΫλϦϯά ཁ݅ͷੳͰϏδωεΛࢧ͑Δ •
దࡐదॴΛݟۃΊΔٕज़
ࣄۀΛࢧ͍͑ͯ͜͏