CQRS+ESをKinesis,Spark,RDB,S3でやってみた
by
machu
Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた CQRS+ESを Kinesis,Spark,RDB,S3でやってみた @ma2k8 Tsubasa Matsukawa スタディサプリ/Quipper Product Meetup #3
Slide 2
Slide 2 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた About me @ma2k8 Tsubasa Matsukawa スタディサプリEnglishのサーバーサイドとインフラを 担当しています。 2
Slide 3
Slide 3 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた Agenda | 01 CQRSとは 02 EventSourcingとは 03 CQRS+ESとは 04 スタディサプリENGLISHにCQRS+ESを導入する前の課題 05 CQRS with Embulkの導入 06 Spark,Kinesis,S3,RDBでCQRS+ES 07 まとめ 3
Slide 4
Slide 4 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた CQRSとは 01 4
Slide 5
Slide 5 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた コマンドクエリ分離原則 ~ Command and Query Responsibility Segregation ~ ➔ ざっくりいうと ◆ Commandは副作用を伴う処理(更新系) ◆ Queryは値だけ返す処理(参照系) ◆ この2つをわけようという考え(CQS)をアーキ テクチャへ適用したもの 5
Slide 6
Slide 6 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた メリット ➔ 参照はページングが必要なケースも多く、更新系のときと同じロジックで組み 立てるのはかなりしんどいので、参照する時の形で保存し、値を取って返だ けにすることでシンプルにできる ➔ これによりアプリケーションのコードがシンプルになり、参照系の計算量もか なり減る ➔ 一定以上の規模、複雑さを持つアプリケーションではかなり有用なアプロー チとなる 6
Slide 7
Slide 7 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた たとえば・・・・? 7
Slide 8
Slide 8 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた ゲームの巨大ロボットの部位破壊を例にしてメリットの一部を紹介 ➔ 攻撃を受けてHPを減少させる処理(更新系)は、どの箇所に受けたダメージ か、その箇所はすでに破壊済みか(壊れていたらHPの減少なし)などのロ ジックを挟むので各部位の現状の状態を計算しないといけない ➔ しかし、全体のHPを表示する(参照系)のに更新系に必要なロジックを挟むの は煩雑で、部位数が多いと重くなってしまうので、更新系が走るタイミングで 全体のHPをどこかに保存しておくことで参照系がシンプルになります 8
Slide 9
Slide 9 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた デメリット ➔ Command/Queryの保存先、同期の方法を考える必要がある 9
Slide 10
Slide 10 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた EventSourcingとは 02 10
Slide 11
Slide 11 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた Event Sourcing ➔ データではなく、イベントを主役とするパターン ➔ 発生するイベントはすべて記録し、基本的に追加しかしない ➔ 対となる概念は「State Sourcing」 11
Slide 12
Slide 12 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた メリット ➔ State Sourcingでは消えてしまう、有用な履歴情報をすべて残せる ➔ 後で「あの情報欲しいな」と思い直したときに、積み上げたEventから好きな 状態に復元することができる ➔ Eventをhookに様々な処理が書ける。マイクロサービス文脈でも有用 12
Slide 13
Slide 13 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた デメリット ➔ Eventの数が多くなると状態を計算する処理のコ ストが大きい ➔ 任意のタイミングでスナップショットデータをつくっ て回避する 13
Slide 14
Slide 14 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた CQRS+ESとは 03 14
Slide 15
Slide 15 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた CQRS+ES ➔ CommandとQueryの結合をEventで行う ➔ QueryをEvent契機で更新していく ➔ Queryはカウンターキャッシュ的に更新されていくイメージ 15
Slide 16
Slide 16 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた 16
Slide 17
Slide 17 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた スタディサプリEnglishに CQRS+ESを導入する前の課題 04 17
Slide 18
Slide 18 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた データの持ち方 ➔ スタディサプリENGLISHではリリース当初から学習ログをEvent Sourcingで RDBに保存する設計になっていた ◆ 立ち上げ期の保存場所としては妥当 ◆ State Sourcingに振っていないのでデータが残っている点もGood ➔ その学習ログを都度集計してクライアントがほしい形に加工していた 18
Slide 19
Slide 19 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた データが増え、つらみが・・ ➔ 学習者のグループを管理する要件が追加され、学習履歴一覧ページが誕生 してしまい、都度集計の重さが実用に耐えなくなってしまった ➔ ただ表示したいだけなのにロジックもめちゃくちゃ複雑 ➔ 集計しないと学習状況がわからないので、学習日数などでソートしてページ ングするのに、全学習者分の集計が必要となり、重・・・・ 19
Slide 20
Slide 20 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた これではスケールしない 20
Slide 21
Slide 21 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた CQRS with Embulkの導入 05 21
Slide 22
Slide 22 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた スケールしないので、 まずは簡単にCQRSを初めてみた 22
Slide 23
Slide 23 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた 23
Slide 24
Slide 24 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた API 軽くなった 24
Slide 25
Slide 25 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた だが・・・・ 25
Slide 26
Slide 26 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた 一時しのぎのCQRS ➔ APIは軽くなったが、Embulkでの集計処理はデータ量に応じて重くなる ➔ 導入後1年ほどして、集計に1時間を超えるようになってしまった ➔ 結果反映が1h以上おくれるので、ユースケースもかなり限られる ➔ Embulkはとても便利で大好きなツールですが、集計用の巨大な生SQLは ちょっとメンテしにくい 26
Slide 27
Slide 27 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた Spark,Kinesis,S3,RDBでCQRS+ES 06 27
Slide 28
Slide 28 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた それぞれの要素を軽く紹介 ※RDBとS3は除く 28
Slide 29
Slide 29 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた Kinesisとは ➔ マネージドなリアルタイムストリーム基盤 ➔ Consumerを自分で書けるKinesis Data Streamsと、Consumerを書かな いでもs3等、特定の箇所に突っ込んでくれるKinesis Data Firehoseがある ➔ at-least-once 29
Slide 30
Slide 30 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた Sparkとは ➔ Scalaで書かれた並列分散処理フレームワーク ➔ Hadoop MapReduceのDisk IOが重い弱点を、データをオンメモリで処理 することにより解決した ➔ 繰り返し処理、リアルタイム処理などにかなり強い ➔ Scalaで直感的に並列分散処理が書くことができて素敵 30
Slide 31
Slide 31 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた SparkはEMR上で動かしています 31
Slide 32
Slide 32 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた EMRとは ➔ Hadoop,Hive,Sparkなどのクラスタをマネージドに立ち上げることができる マネージドクラスタプラットフォーム ➔ 構築、保守がとても面倒な大規模分散処理基盤をお手軽に立ち上げ、実行 することができ、S3,Dynamo,Redshift等のAWSサービスへのインテグレー ションも容易 32
Slide 33
Slide 33 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた これらを使ってCQRS+ESを 効率よくやる 33
Slide 34
Slide 34 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた Command,Query,Eventの保存場所 ➔ Commandはトランザクション整合性で正規化されたデータを保存する ➔ Queryは結果整合性で、非正規化されたクライアント都合のデータを保存す る ➔ Eventは大量のデータをスキーマレスに保存する ➔ Command,QueryはRDB、EventはS3へ保存することにした 34
Slide 35
Slide 35 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた S3はいいぞ ➔ S3は書き込みを`Prefix毎に3500req/sec` 捌ける ➔ AWSはS3をHubにいろんなサービスへ展開しやすい ➔ 可用性99.99% 耐久性イレブンナイン ➔ 安い ➔ `Full managed object storage` 容量キニシナイ 35
Slide 36
Slide 36 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた Kinesisはイベントの伝播 SparkはQueryの集計で使う 36
Slide 37
Slide 37 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた Kinesis 37 ➔ 状態を都度更新するので、計算コストがかからない
Slide 38
Slide 38 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた Spark 38 ➔ 全Eventを利用した状態の復元や、スナップショット作成は Sparkで高速に行う
Slide 39
Slide 39 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた 切り替えも安心安全 39
Slide 40
Slide 40 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた 並行稼動させ、データに問題がないことが確認できたら切り替える 40
Slide 41
Slide 41 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた まとめ 07 41
Slide 42
Slide 42 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた CQRS+ESは便利 42
Slide 43
Slide 43 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた EventはS3においておくと 分析などで再利用しやすい 43
Slide 44
Slide 44 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた EMR,Spark,Kinesisは 大規模と戦う際にとても有用 44
Slide 45
Slide 45 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた 45
Slide 46
Slide 46 text
#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた ご清聴ありがとうございました 46