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
420
Phluxorでアクターモデルを 理解・体験しよう / toolkit-for-flexible-actor-models-in-php-phluxor
ytake
1
260
オブジェクトのおしゃべり大失敗 メッセージングアンチパターン集 / 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
Classmethod AI Talks(CATs) #17 司会進行スライド(2025.02.19) / classmethod-ai-talks-aka-cats_moderator-slides_vol17_2025-02-19
shinyaa31
0
170
データマネジメントのトレードオフに立ち向かう
ikkimiyazaki
6
1.2k
コンピュータビジョンの社会実装について考えていたらゲームを作っていた話
takmin
1
570
遷移の高速化 ヤフートップの試行錯誤
narirou
5
860
あれは良かった、あれは苦労したB2B2C型SaaSの新規開発におけるCloud Spanner
hirohito1108
2
890
Iceberg Meetup Japan #1 : Iceberg and Databricks
databricksjapan
0
290
プロダクトエンジニア 360°フィードバックを実施した話
hacomono
PRO
0
130
Raycast Favorites × Script Command で実現するお手軽情報チェック
smasato
1
120
脳波を用いた嗜好マッチングシステム
hokkey621
0
270
Visualize, Visualize, Visualize and rclone
tomoaki0705
9
75k
php-conference-nagoya-2025
fuwasegu
0
140
OSS構成管理ツールCMDBuildを使ったAWSリソース管理の自動化
satorufunai
0
390
Featured
See All Featured
Designing on Purpose - Digital PM Summit 2013
jponch
117
7.1k
A designer walks into a library…
pauljervisheath
205
24k
How GitHub (no longer) Works
holman
314
140k
Building Flexible Design Systems
yeseniaperezcruz
328
38k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
GraphQLの誤解/rethinking-graphql
sonatard
68
10k
It's Worth the Effort
3n
184
28k
How to Think Like a Performance Engineer
csswizardry
22
1.4k
Done Done
chrislema
182
16k
The Invisible Side of Design
smashingmag
299
50k
A Modern Web Designer's Workflow
chriscoyier
693
190k
Navigating Team Friction
lara
183
15k
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ΞʔΩςΫνϟ
·ͱΊ
·ͱΊ • Ϗδωεʹؔ৺Λ࣋ͭ͜ͱ͕ୈҰ • نʹ߹Θͤͨσʔλઃܭ ఆظతͳϦϑΝΫλϦϯά ཁ݅ͷੳͰϏδωεΛࢧ͑Δ •
దࡐదॴΛݟۃΊΔٕज़
ࣄۀΛࢧ͍͑ͯ͜͏