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
PHPでアクターモデルを活用したSagaパターンの実践法 / php-saga-pattern-with-actor-model
ytake
0
1.6k
PHP ステートレス VS ステートフル 状態管理と並行性 / php-stateless-stateful
ytake
0
150
PHPでアクターモデルを理解・体験しよう / Understand and experience the actor model in PHP
ytake
2
540
再考 アクターモデル/ reconsider actor model
ytake
0
1.2k
GoとアクターモデルでES+CQRSを実践! / proto_actor_es_cqrs
ytake
1
460
Phluxorでアクターモデルを 理解・体験しよう / toolkit-for-flexible-actor-models-in-php-phluxor
ytake
1
290
オブジェクトのおしゃべり大失敗 メッセージングアンチパターン集 / messaging anti-pattern collection
ytake
2
1.1k
DRE/SREのプラクティス融合によるクラウドネイティブなデータ基盤作り / dre_sre
ytake
0
830
技術的負債と向き合う取り組みでよかったもの / positive_efforts_to_tackle_technical_debt
ytake
10
3.9k
Other Decks in Technology
See All in Technology
Amplifyとゼロからはじめた AIコーディング。失敗と気づき
mkdev10
1
180
Software Delivery Observability CI・CD , DORA metrics も Datadog で可視化しよう / datadog-ci-cd-observability
parupappa2929
0
170
MagicPod MCPサーバー開発の裏側とAIエージェント活用の展望
magicpod
0
310
名単体テスト 禁断の傀儡(モック)
iwamot
PRO
1
330
インラインRBSコメントに鯛pe checkersもニッコリ
sansantech
PRO
2
200
テスト設計、逆から読むとおもしろい──仕様にない“望ましさ”の逆設計
mhlyc
0
190
encoding/json v2を予習しよう!
yuyu_hf
PRO
1
220
Software Architecture in an AI-Driven World
atty303
64
25k
Developer 以外にこそ使って欲しい Amazon Q Developer
mita
0
190
CARTA HOLDINGS エンジニア向け 採用ピッチ資料 / CARTA-GUIDE-for-Engineers
carta_engineering
0
28k
木を見て森も見る-モジュールが織りなすプロダクトの森
kworkdev
PRO
0
300
さくらのクラウド開発の裏側
metakoma
PRO
18
5.9k
Featured
See All Featured
Rebuilding a faster, lazier Slack
samanthasiow
81
9k
How GitHub (no longer) Works
holman
314
140k
StorybookのUI Testing Handbookを読んだ
zakiyama
30
5.7k
Reflections from 52 weeks, 52 projects
jeffersonlam
349
20k
Designing for Performance
lara
608
69k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
34
3k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
41
2.3k
Stop Working from a Prison Cell
hatefulcrawdad
268
20k
Keith and Marios Guide to Fast Websites
keithpitt
411
22k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
3.8k
The Cult of Friendly URLs
andyhume
78
6.4k
Fireside Chat
paigeccino
37
3.4k
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ΞʔΩςΫνϟ
·ͱΊ
·ͱΊ • Ϗδωεʹؔ৺Λ࣋ͭ͜ͱ͕ୈҰ • نʹ߹Θͤͨσʔλઃܭ ఆظతͳϦϑΝΫλϦϯά ཁ݅ͷੳͰϏδωεΛࢧ͑Δ •
దࡐదॴΛݟۃΊΔٕज़
ࣄۀΛࢧ͍͑ͯ͜͏