Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.

CQRS+ES on GCP

cqrs + es on gcp

  • Loggen Sie sich ein, um Kommentare anzuzeigen.

CQRS+ES on GCP

  1. 1. copyright Fringe81 Co.,Ltd. CQRS+ES on GCP 2018.3.27 GCPを活用した戦略的な新サービス開発の裏側@Fringe81
  2. 2. copyright Fringe81 Co.,Ltd. About me (@mtoyoshi) ・サーバーサイドエンジニア ・ScalaとGolang書いてます
  3. 3. 共に働く仲間と送り合う ピアボーナスを実現するサービス 〜サイレントヒーローの発見〜
  4. 4. - -copyright Fringe81 Co.,Ltd. 事業化判 断 2. Fringe81の新規事業の開発フェーズ 事業企画 以下のフェーズを意識して、 実現性検証 プロトタイピン グ ローンチ にむけた 開発 ローンチ 直後の サポート フェーズ1 フェーズ2 フェーズ3 フェーズ4 フェーズ5
  5. 5. copyright Fringe81 Co.,Ltd. 今回の戦を略す話: 1. アプリケーション開発以外との戦い 2. 美しさ vs 速さの二項対立との戦い 3. 障害やバグの原因究明の時間との戦い
  6. 6. copyright Fringe81 Co.,Ltd. 少ないエンジニアリソースでのスタート アプリケーション開発に集中したい Google App Engine (PaaS) を採用
  7. 7. copyright Fringe81 Co.,Ltd. GAE選定で悩んだ話はこちらの資料に
  8. 8. copyright Fringe81 Co.,Ltd. 理想 ドメイン世界の表現 モデル的/コード的妥当性・美しさ (メンテナンス性) パフォーマンス 現実はトレードオフの 関係になりやすい
  9. 9. copyright Fringe81 Co.,Ltd. It is not possible to create an optimal solution for searching,reporting,and processing transactions utilizing a single model. -CQRS documents by Greg Young-
  10. 10. copyright Fringe81 Co.,Ltd. It is not possible to create an optimal solution for searching,reporting,and processing transactions utilizing a single model. -CQRS documents by Greg Young- 2軸を包括するモデルの定義はかなり難しい
  11. 11. copyright Fringe81 Co.,Ltd. ドメイン世界の表現 モデル的/コード的妥当性・美しさ (メンテナンス性) パフォーマンス 2軸を 操作(CRUD)レベルに 落とし込むと
  12. 12. copyright Fringe81 Co.,Ltd. ドメイン世界の表現 モデル的/コード的妥当性・美しさ (メンテナンス性) パフォーマンス 更新系(CUD)の処理
  13. 13. copyright Fringe81 Co.,Ltd. ドメイン世界の表現 モデル的/コード的妥当性・美しさ (メンテナンス性) パフォーマンス 検索系(R)の処理
  14. 14. copyright Fringe81 Co.,Ltd. 更新系 検索系 アクセス量に 占める割合 少 多 スケール性 △ ◎ 複雑さの傾向 ビジネスロジック データ量と応答速度 複数切り口での見せ方 (R)DB傾向 正規化 非正規化(速さ重視) 特性の違い
  15. 15. copyright Fringe81 Co.,Ltd. 2軸の違いを素直に受け止め 別々に管理・開発していこう Command Query Responsibility Segregation コマンド クエリ 責務 分離
  16. 16. copyright Fringe81 Co.,Ltd. Command Adapters DB UseCases Entities(Domains) Repository RepositoryImpl Controller UseCase Presenter DDD x CleanArchitecture
  17. 17. copyright Fringe81 Co.,Ltd. Command (GAE flexible) Adapters DB UseCases Entities(Domains) Repository RepositoryImpl Controller UseCase Presenter DDD x CleanArchitecture GAE flexible x Scala ※ScalaはFringe81のメイン言語で最も使い慣れている
  18. 18. copyright Fringe81 Co.,Ltd. Query Controller DAO DB
  19. 19. copyright Fringe81 Co.,Ltd. Query (GAE standard) Controller DAO DB GAE standard x Go ※GAE standard x Goの組み合わせは スケール性能抜群でQ要件にとてもマッチしている
  20. 20. copyright Fringe81 Co.,Ltd. 内部のソフトウェアアーキテクチャも プログラミング言語も GAEの種類も異なるものとなった 2軸の違いを素直に受け止め 別々に管理・開発していこう
  21. 21. copyright Fringe81 Co.,Ltd. Command App Engine Flexible Query App Engine Standard Cloud Pub/Sub microservice1 microservice2 マイクロサービス群の連携は ドメインイベントのPublishとSubscribeで実現 Event
  22. 22. copyright Fringe81 Co.,Ltd. Command App Engine Flexible Query App Engine Standard Cloud Pub/Sub microservice1 microservice2 Cloud Datastore より複雑なクエリへの対応にも (C側に影響を及ぼすことなく:疎結合) Cloud SQL Event Event Event
  23. 23. copyright Fringe81 Co.,Ltd. ここでEventについて もう少し理解しておきたい
  24. 24. copyright Fringe81 Co.,Ltd. Message-driven vs Event-driven The Reactieve ManifestoのGlossary集より (https://www.reactivemanifesto.org/glossary#Message-Driven)
  25. 25. copyright Fringe81 Co.,Ltd. ■定義 Message: 特定の送り先に送られたデータ Event: ある状態になったコンポーネントが送出するシ グナル(過去に起きた事象をあらわす: fact)
  26. 26. copyright Fringe81 Co.,Ltd. メッセージ駆動では 受信者はメッセージの到着を待って メッセージに反応しそれ以外は休眠状態 誰に送るのかに関心
  27. 27. copyright Fringe81 Co.,Ltd. イベント駆動では イベント発生時に実行できるよう 通知リスナはイベントをアタッチする    何が起きたのかに関心
  28. 28. copyright Fringe81 Co.,Ltd. MessageやEventが伝わる伝送路のことを 一般化してChannel※と呼ぶとすると ※Enterprise Integration Patternsより
  29. 29. copyright Fringe81 Co.,Ltd. EventのChannelがCloudPubSub (イベントに関心があるものは複数ある)
  30. 30. copyright Fringe81 Co.,Ltd. MessageのChannelがCloudTasks※ (誰に送るのかに関心) ※現在はα版です。TaskQueue
  31. 31. copyright Fringe81 Co.,Ltd. Command App Engine Flexible Query App Engine Standard Cloud Pub/Sub microservice1 microservice2 Cloud Datastore 改めてこの図 Cloud SQL Event Event Event
  32. 32. copyright Fringe81 Co.,Ltd. Command App Engine Flexible Query App Engine Standard Cloud Pub/Sub microservice1 microservice2 Cloud Datastore Eventは揮発性だと気付く Cloud SQL Event Event Event
  33. 33. copyright Fringe81 Co.,Ltd. Command App Engine Flexible Query App Engine Standard Cloud Pub/Sub microservice1 microservice2 Cloud Datastore 「後から追加できる」という特徴との コンフリクトが少なからず存在する Cloud SQL Event Event Event
  34. 34. copyright Fringe81 Co.,Ltd. どういうことか?
  35. 35. copyright Fringe81 Co.,Ltd. microservice1 Cloud Datastore Cloud SQL投入時点で過去のデータをもとに 加工したデータを入れておく必要あり (さも最初からあったかのように振る舞うために) Cloud SQL
  36. 36. copyright Fringe81 Co.,Ltd. microservice1 Cloud Datastore 出来ないこともある Cloud SQL
  37. 37. copyright Fringe81 Co.,Ltd. INPUT Cloud SQL OUTPUT Cloud SQLのデータを作るのはSubscriber OUTPUTを作るにはEventを入れないと
  38. 38. copyright Fringe81 Co.,Ltd. 過去に発行されたEvent群がなければ さも最初からあったかのように振る舞うための データを満足に作ることは出来ない Cloud SQL INPUT OUTPUT ※もちろん要件によっては必ずしもイベントを INPUTにしなくても datastoreの現在の状態をもとにしても作れる
  39. 39. copyright Fringe81 Co.,Ltd. Eventに永続性を
  40. 40. copyright Fringe81 Co.,Ltd. Command App Engine Flexible Query App Engine Standard Cloud Pub/Sub microservice1 microservice2 Cloud Datastore publish対象のEventと同じものを永続化 Event Event
  41. 41. copyright Fringe81 Co.,Ltd. Got: 3 Got: 6 Lost: 1 ①イベント追加 ②イベント追加 ③イベント追加 イベントが発生するたびに永続化 (ここでは何らかの値を得たり失ったりするイベントが発生)
  42. 42. copyright Fringe81 Co.,Ltd. “Eventは過去の出来事をあらわす” 過去の積み重ねが現在の状態をあらわす
  43. 43. copyright Fringe81 Co.,Ltd. Got: 3 Got: 6 Lost: 1 value = 8 <DB世界> <プログラム世界> イベント群から状態を復元する (+3 + 6 -1)
  44. 44. copyright Fringe81 Co.,Ltd. このようにEventを永続化してEventをもとに アプリケーション状態を表現する方法を Event Sourcingと呼ぶ
  45. 45. copyright Fringe81 Co.,Ltd. value: 3 value = 8 <DB世界> <プログラム世界> ① 最初の状態は3 ② 9に更新 ③ 8に更新 一方、お馴染みのこちらはState Sourcing value: 9 value: 8
  46. 46. copyright Fringe81 Co.,Ltd. Eventは過去の出来事、事実 Immutable Stateは変わり続ける Mutable
  47. 47. copyright Fringe81 Co.,Ltd. Event Sourcingにはどういうメリットが? 参考:CQRS Jornery (https://msdn.microsoft.com/ja-jp/library/jj554200.aspx)
  48. 48. copyright Fringe81 Co.,Ltd. メリット 要約 Performance ESにおいては永続化はイベントの append-only。 更新処理のパフォーマンス改善が望める。 Simplification factとしてのイベントを保存するだけ。 O-R間のインピーダンスミスマッチが起きない。 Audit trail システムで何が起きてその状態なのかの追跡が可能となり、監査ログとして使える Integration with other subsystems 疎結合を促す。 また、他のサブシステムへ publishした全てのイベントは eventStoreに保存されている。 Deriving additional business value from the event history 将来起こるビジネス要件を予想することは困難だが全てのイベント履歴を持っていることで対処 可能性が高まる。 例:ある時点での状態がどうであったかにこたえられるなど Production troubleshooting 本番環境のデータをテスト環境にコピーするなどして状態の再現を簡単にできるためトラブル シューティングに役立つ Fixing Errors ESの場合factとしてイベントが保存されているだけなので、コーディングエラーを修正するだけ でDB値を手動メンテせずにすむ場合がある Testing テスト容易性が高まる Flexibility イベント群があればいかなる構造のデータにも変換可能
  49. 49. copyright Fringe81 Co.,Ltd. メリット 要約 Performance ESにおいては永続化はイベントの append-only。 更新処理のパフォーマンス改善が望める。 Simplification factとしてのイベントを保存するだけ。 O-R間のインピーダンスミスマッチが起きない。 Audit trail システムで何が起きてその状態なのかの追跡が可能となり、監査ログとして使える Integration with other subsystems 疎結合を促す。 また、他のサブシステムへ publishした全てのイベントは eventStoreに保存されている。 Deriving additional business value from the event history 将来起こるビジネス要件を予想することは困難だが全てのイベント履歴を持っていることで対処 可能性が高まる。 例:ある時点での状態がどうであったかにこたえられるなど Production troubleshooting 本番環境のデータをテスト環境にコピーするなどして状態の再現を簡単にできるためトラブル シューティングに役立つ Fixing Errors ESの場合factとしてイベントが保存されているだけなので、コーディングエラーを修正するだけ でDB値を手動メンテせずにすむ場合がある Testing テスト容易性が高まる Flexibility イベント群があればいかなる構造のデータにも変換可能 イベント群があれば いかなる構造のデータにも変換可能 (さきほど紹介したもの)
  50. 50. copyright Fringe81 Co.,Ltd. メリット 要約 Performance ESにおいては永続化はイベントの append-only。 更新処理のパフォーマンス改善が望める。 Simplification factとしてのイベントを保存するだけ。 O-R間のインピーダンスミスマッチが起きない。 Audit trail システムで何が起きてその状態なのかの追跡が可能となり、監査ログとして使える Integration with other subsystems 疎結合を促す。 また、他のサブシステムへ publishした全てのイベントは eventStoreに保存されている。 Deriving additional business value from the event history 将来起こるビジネス要件を予想することは困難だが全てのイベント履歴を持っていることで対処 可能性が高まる。 例:ある時点での状態がどうであったかにこたえられるなど Production troubleshooting 本番環境のデータをテスト環境にコピーするなどして状態の再現を簡単にできるためトラブル シューティングに役立つ Fixing Errors ESの場合factとしてイベントが保存されているだけなので、コーディングエラーを修正するだけ でDB値を手動メンテせずにすむ場合がある Testing テスト容易性が高まる Flexibility イベント群があればいかなる構造のデータにも変換可能 ESにおいては永続化はイベントのappend-only 更新処理のパフォーマンス改善が望める
  51. 51. copyright Fringe81 Co.,Ltd.
  52. 52. copyright Fringe81 Co.,Ltd. メリット 要約 Performance ESにおいては永続化はイベントの append-only。 更新処理のパフォーマンス改善が望める。 Simplification factとしてのイベントを保存するだけ。 O-R間のインピーダンスミスマッチが起きない。 Audit trail システムで何が起きてその状態なのかの追跡が可能となり、監査ログとして使える Integration with other subsystems 疎結合を促す。 また、他のサブシステムへ publishした全てのイベントは eventStoreに保存されている。 Deriving additional business value from the event history 将来起こるビジネス要件を予想することは困難だが全てのイベント履歴を持っていることで対処 可能性が高まる。 例:ある時点での状態がどうであったかにこたえられるなど Production troubleshooting 本番環境のデータをテスト環境にコピーするなどして状態の再現を簡単にできるためトラブル シューティングに役立つ Fixing Errors ESの場合factとしてイベントが保存されているだけなので、コーディングエラーを修正するだけ でDB値を手動メンテせずにすむ場合がある Testing テスト容易性が高まる Flexibility イベント群があればいかなる構造のデータにも変換可能 システムで何が起きてその状態なのかの 追跡が可能となり監査ログとして使える
  53. 53. copyright Fringe81 Co.,Ltd. DB内のイベント群と アプリケーションログ ミスが疑われた場合 突き合わせができるので ミスの発見だけでなく どこがおかしいのか あたりをつけることもできる Got: 3 Got: 6 Lost: 1 ・ ・ ・ ・ ・ ・ ・ ・ ・ ・・ ・
  54. 54. copyright Fringe81 Co.,Ltd. 以上が主なEvent Sourcingのメリット
  55. 55. copyright Fringe81 Co.,Ltd. よーし、俺たちも次のプロジェクトから StateSourcingやめてEventSourcingだ! ...とは多分ならない
  56. 56. copyright Fringe81 Co.,Ltd. 頭では分かっても 慣れ親しんできたやり方を捨てる のは厳しいし新しすぎて不安 私達も同じでした
  57. 57. copyright Fringe81 Co.,Ltd. 自分たちの場合はここぞ! というところからはじめた ピアボーナスシステムで絶対にミス してはいけない獲得ボーナス額
  58. 58. copyright Fringe81 Co.,Ltd. DB内のイベント群と アプリケーションログ ミスが疑われた場合 突き合わせができるので ミスの発見だけでなく どこがおかしいのかあたりをつけ ることもできる Got: 3 Got: 6 Lost: 1 ・ ・ ・ ・ ・ ・ ・ ・ ・ ・・ ・
  59. 59. copyright Fringe81 Co.,Ltd. ちなみに新しい概念と思っていたものの 実は意外と古くからありました
  60. 60. copyright Fringe81 Co.,Ltd. 最後にEvent Sourcingの 弱点とその克服を2つほど紹介
  61. 61. copyright Fringe81 Co.,Ltd. Event Sourcingの 弱点その1
  62. 62. copyright Fringe81 Co.,Ltd. Got: 3 Got: 6 Lost: 1 クエリに弱い Got: 2 ex.値が7以上のもの一覧を取得 select * from table where value >= 7 のようにはいかない厳しさ
  63. 63. copyright Fringe81 Co.,Ltd. value: 8 クエリに対応するためのQ用DBが必要 ※CQRSとESが一緒に語られる理由はこれだと思う value: 2 Q Got: 3 Got: 6 Lost: 1 Got: 2 C
  64. 64. copyright Fringe81 Co.,Ltd. Event Sourcingの 弱点その2
  65. 65. copyright Fringe81 Co.,Ltd. イベントが積み上がってくると 状態復元のパフォーマンスが悪くなる
  66. 66. copyright Fringe81 Co.,Ltd. イベントが積み上がってくると 状態復元のパフォーマンスが悪くなる 加えてDatastoreの場合は オペレーション数課金なのでコスト面でも懸念
  67. 67. copyright Fringe81 Co.,Ltd. 100Events:約60ms 500Events:約160ms 1,500Events:約420ms 3,000Events:約940ms やってみた
  68. 68. copyright Fringe81 Co.,Ltd. 大量イベントのロードは StackdriverTrace上で 見ても大変なことに
  69. 69. copyright Fringe81 Co.,Ltd. 〜 Snapshot機能 〜 任意のタイミングで Eventレコードをまとめあげた地点をつくり ロードするレコード数を減らす
  70. 70. copyright Fringe81 Co.,Ltd. Got: 3 Got: 6 Lost: 1 value:8 Snapshotテーブル
  71. 71. copyright Fringe81 Co.,Ltd. value:8 Snapshotテーブル Got: 3 Got: 6 Lost: 1 Got: 10 Lost: 2
  72. 72. copyright Fringe81 Co.,Ltd. value:8 Snapshotテーブル プログラム ③ value = 16 Got: 3 Got: 6 Lost: 1 Got: 10 Lost: 2 ① ②
  73. 73. copyright Fringe81 Co.,Ltd. まとめ
  74. 74. copyright Fringe81 Co.,Ltd. 今回の戦を略す話: 1. アプリケーション開発以外との戦い 2. 美しさ vs 速さの二項対立との戦い 3. 障害やバグの原因究明の時間との戦い
  75. 75. copyright Fringe81 Co.,Ltd. 今回の戦を略す話: 1. アプリケーション開発以外との戦い 2. 美しさ vs 速さの二項対立との戦い 3. 障害やバグの原因究明の時間との戦い 1. GAEいいよ!
  76. 76. copyright Fringe81 Co.,Ltd. 今回の戦を略す話: 1. アプリケーション開発以外との戦い 2. 美しさ vs 速さの二項対立との戦い 3. 障害やバグの原因究明の時間との戦い 2. CQRSいいよ!
  77. 77. copyright Fringe81 Co.,Ltd. 今回の戦を略す話: 1. アプリケーション開発以外との戦い 2. 美しさ vs 速さの二項対立との戦い 3. 障害やバグの原因究明の時間との戦い 3. Event Sourcingいいよ! (EventとアプリログのWチェック)
  78. 78. copyright Fringe81 Co.,Ltd. CQRS+ES on GCP ありがとうございました

×