ScalaMatsuri 2019
Akka Cluster を採用した決済サービスをリリースしました。このセッションでは、Akka Cluster を使った開発で苦労した点や、従来の RDB を用いた CRUD ベースのシステムから、どのようにしてアクターモデルやイベントソーシング・CQRS といったモデルを用いたシステムへと変化させたのかなど、本プロジェクトで Akka Cluster を採用するにあたり我々が取り組んだ内容について話します。
Using Akka Clusterfor a payment service© 2019 TIS Inc.決済サービスで Akka Cluster 使ってみた1 / 73
View Slide
Who am I ?Kazuki NegoroTIS Inc.Technology & Enginnering CenterMissionProvide High Availability Systemat a low cost@negokaz negokaz© 2019 TIS Inc.根来 和輝TIS株式会社 テクノロジー&エンジニアリングセンター2 / 73
I ll talk about...Technical story ofTIS Participates in Demonstration Trial of QR PaymentUsing High Availablity and High Throughput SoftwareStack Lerna - Applied to Omotenashi Platform forforeigh tourists visiting Japan -© 2019 TIS Inc.TIS、高可用・高スループットのソフトウェアスタック「Lerna」を活用したQR決済の実証実験に参画~ 訪日外国人観光客向け「おもてなしプラットフォーム」に適用 ~今日話すこと2019/3/27 ニュースリリースの技術的な裏側3 / 73
Omotenashi PlatformA measure promoted by Ministry of Economy to increasethe satisfication of foreign tourists.QR code payment servicesightseeing information serviceetc...© 2019 TIS Inc.withJorge - Japan Omotenashi concieRGE経済産業省が推進する、訪日外国人の満足度を高めるための施策QRコード決済や観光情報提供などのサービスが受けられる4 / 73
AkkaApache CassandraMariaDBKeepalivedHAProxyWhat is Lerna ?A Software Stack forHigh Availablity and High Throughput(Reactive System) which is promoted by TIS© 2019 TIS Inc.Lerna とは何か? TIS が推進している高可用・高スループットを実現するためのソフトウェアスタック5 / 73
Application Architecture of LernaEvent Sourcing + CQRSAkka PersistenceAkka Persistence QueryAkka Cluster Sharding© 2019 TIS Inc.Lerna のアプリケーションアーキテクチャ6 / 73
Omotenashi Platform Project© 2019 TIS Inc. 7 / 73
Project ContextCRUD version released firstReconstructs main features of the system with LernaNeeds data migration© 2019 TIS Inc.CRUD構成版を先行リリース。システムの主要機能部分を再構築。データ移行が必要。8 / 73
System OverviewMakes consumers who visit a shop can make paymentwith QR codeQR-ServerConsumerMerchantAgencyPayment© 2019 TIS Inc.システム概要店舗に訪れた顧客がQRコードで決済できるようにする9 / 73
Main features of the systemQR Payment +Payment history confirmationCancelling payment© 2019 TIS Inc.システムの主要機能はQRコード決済、決済履歴確認、決済キャンセル。10 / 73
Main features of the systemQR Payment +Payment history confirmationCancelling paymentReconstructed these features with Akka ClusterSharding and EC + CQRS© 2019 TIS Inc.システムの主要機能はQRコード決済、決済履歴確認、決済キャンセル。これら主要機能を Lerna の構成にリプレース。11 / 73
Payment processConsumer MerchantQR-ServerGenQRCodeQRCodePaymentresultofpaymentQRCodeReadQRCodeNotification© 2019 TIS Inc.決済の手順12 / 73
Payment cancellation processConsumer MerchantQR-ServerPaymenthistoryCancelGetpaymenthistoryresultofcancellation© 2019 TIS Inc.決済キャンセルの手順13 / 73
System Archtecture© 2019 TIS Inc. 14 / 73
Server-side without LernaQR-ServerWebApplicationServer MySQL・Payment・User Management・System Administration© 2019 TIS Inc.Lerna を適用する前のサーバーサイドのシステム構成15 / 73
Server-side with LernaQR-ServerWebApplicationServer・User Management・System Administration・PaymentWebApplicationServer© 2019 TIS Inc.Lerna を適用したサーバーサイドのシステム構成16 / 73
Application Architecture© 2019 TIS Inc. 17 / 73
Application ArchitectureEvent Sourcing + CQRSAkka PersistenceAkka Persistence QueryAkka Cluster Sharding© 2019 TIS Inc.アプリケーションアーキテクチャ18 / 73
Why is this architecture needed ?RDBMS makes it difficult to scale writesUsing ES + CQRS makes writing easier to scale© 2019 TIS Inc.RDBMSは書き込みがボトルネックになりやすいES + CQRS を使って書込・読込の両方をスケールできるように19 / 73
Event Sourcing ?Persist events produced inside a systemOnly INSERT events to datastoreAccount No:10OpenedEvent System State¥2,000WithdrewNo:10, Balance:¥18,000¥10,000Deposited¥10,000Deposited© 2019 TIS Inc.システムの中で起きたイベントを永続化イベントをデータストアに INSERT だけする20 / 73
Pros of Event SourcingEvents is immutableNo need lock・Can write data to multi nodesEasy to scale for to write dataEasy to caching, copying, sharingEasy to scala for to read data, too© 2019 TIS Inc.イベントは不変なのでロック不要で複数のノードに分散書き込みが可能。複製も容易なので読み込みもスケール可能。21 / 73
Cons of Event SourcingSummarizing data is expensive© 2019 TIS Inc.データの集計や一覧を作るのにコストがかかるCQRSでこの問題を解決22 / 73
Cons of Event SourcingSummarizing data is expensiveCQRS solves it© 2019 TIS Inc.データの集計や一覧を作るのにコストがかかるCQRSでこの問題を解決23 / 73
CQRS ?Command and Query Responsibility SegregationSeparate Command(reads) and Query(writes)CommandQueryCommandQuery© 2019 TIS Inc.コマンドクエリ責務分離コマンド(書き込み)とクエリ(読み込み)を分離24 / 73
Pros of CQRSCommandQueryCommandQuerydifferent Database and modelsCommand-side uses Event Sourcing.Persist on the Query-side in a form easy to sum and list© 2019 TIS Inc.コマンドとクエリで異なるDB・データ構造が使える。クエリサイドには集計や一覧しやすい形で永続化する。25 / 73
Cons of CQRSQuery-Side is updated asynchronusThere is NO strong consistency betweenCommand-Side and Query-SideHowever, sometime it will be updated:eventual consistency© 2019 TIS Inc.クエリサイドへの反映は非同期のためコマンドサイドの更新は遅れてクエリサイドに反映される(結果整合性)26 / 73
Cons of CQRSQuery-Side is updated asynchronusThere is NO strong consistency betweenCommand-Side and Query-SideHowever, sometime it will be updated:eventual consistencyNeed to design the system or business so that we donthave to worry about temporary inconsistencies© 2019 TIS Inc.クエリサイドへの反映は非同期のためコマンドサイドの更新は遅れてクエリサイドに反映される(結果整合性)一時的に一貫性が取れていなくても問題ないようにビジネスやシステムを設計する必要がある27 / 73
Not always acceptable eventual consistencyCan not withdraw if the balance is not enoughOnly one person can reserve a seatOne-time password can only be used once...© 2019 TIS Inc.あらゆる場面で結果整合性を許容できるわけではない28 / 73
Not always acceptable eventual consistencyCan not withdraw if the balance is not enoughOnly one person can reserve a seatOne-time password can only be used once...Need to look the latest state without delayto realize these requirements© 2019 TIS Inc.あらゆる場面で結果整合性を許容できるわけではないこれらの要求を実現するには、遅延無く最新の状態を確認できる必要がある29 / 73
How to look latest stateAkka Persistence makes Actor to be able to persist eventsand look latest state (as self state)Account No:10OpenedEvent ActorState¥2,000WithdrewNo:10, Balance:¥18,000¥10,000Deposited¥10,000Deposited© 2019 TIS Inc.Akka Persistence によって Actor はイベントの永続化と(それ自身の状態として)最新の状態の確認が可能になる30 / 73
How to look latest stateAkka Persistence makes Actor to be able to persist eventsand look latest state (as self state)Account No:10OpenedEvent ActorState¥2,000WithdrewNo:10, Balance:¥18,000¥10,000Deposited¥10,000Deposited© 2019 TIS Inc.Akka Persistence によって Actor はイベントの永続化と(それ自身の状態として)最新の状態の確認が可能になるSuch an Actoras has ID and statesis called Entityこのように識別子と状態を持つアクターは Entity と呼ばれる31 / 73
ES + CQRS Overview of AkkaCommand-SideQuery-SideEventStoreReadModelUpdaterPollingUpdateStateCommandQueryAPICallAPICallEntityEntityQueryStoreEntityController© 2019 TIS Inc.Akka を用いた ES + CQRS の概要32 / 73
Important point of EntityAn Entity which has the ID must exists only one placeHaving one entity in multiple location cases inconsistencyID:1 ID:1amount:10 amount:11© 2019 TIS Inc.ある ID の Entity が存在していいのは 1 箇所でだけ複数箇所に存在するとデータの整合性が崩れる33 / 73
Scale Command-Side safely© 2019 TIS Inc.コマンドサイドを安全にスケールさせるには34 / 73
Scale Command-Side safelyAkka Cluster Sharding© 2019 TIS Inc.コマンドサイドを安全にスケールさせるには35 / 73
Scale Command-Side safelyAkka Cluster ShardingFeature for load balancingCan distribute entities across several serversGuarantee that there is at most one entity in theclusterNo single point of failure© 2019 TIS Inc.コマンドサイドを安全にスケールさせるには負荷分散の仕組み。複数のサーバーに Entity を分散できる各 Entity は高々1つだけ存在することが保証される。SPOFなし36 / 73
Our experience© 2019 TIS Inc.私たちが経験したこと37 / 73
Decide where apply ES + CQRS toThere is not many enginner who can use Scala/AkkaNeed many cost to change data model and paradigmWhich do features need high availability andhigh throughput ?© 2019 TIS Inc.Scala/Akka のエンジニアが多いわけではない。データモデルとパラダイムの変更にはコストがかかる。38 / 73
Decide where apply ES + CQRS toThere is not many enginner who can use Scala/AkkaNeed many cost to change data model and paradigmWhich do features need high availability andhigh throughput ?Apply only to features directly related to payment© 2019 TIS Inc.Scala/Akka のエンジニアが多いわけではない。データモデルとパラダイムの変更にはコストがかかる。決済に直接関係する機能にだけ適用39 / 73
Consumer MerchantQR-ServerGenQRCodeQRCodePaymentresultofpaymentQRCodeReadQRCodeNotificationConsumer MerchantQR-ServerPaymenthistoryCancelGetpaymenthistoryresultofcancellationPayment flow© 2019 TIS Inc. 40 / 73
RequirementsSometime QR code is reused.Must not give same QR code multiple transactions atthe same time.Consumer confirms payment progressConsumer and Merchant confirm payment historyMerchant can cancel a payment© 2019 TIS Inc.QRコードは再利用される。顧客は決済の進捗が確認できる。決済履歴が確認できる。店舗は決済をキャンセルできる。41 / 73
Explore states of the systemWhere is status updated?(Command-side)How does status look from outside?(Query-side)© 2019 TIS Inc.システムの「状態」を探索。状態が更新される箇所は?外部から見える状態は?42 / 73
Where is status updated? (Command-side)Record QR code usage status and expiration timeRecord the progress of paymentRecord results when payment completedRecord results when payment canceling completed© 2019 TIS Inc.状態が更新される箇所はどこか43 / 73
How does status look from outside? (Query-side)Payment progress notificationPayment history list© 2019 TIS Inc.状態が外部からどのように参照されるか44 / 73
Define entityWe found two state of the systemQR code stateTokenActorPayment transaction stateTransactionActor© 2019 TIS Inc.Entity を定義。このシステムには2つの状態があることがわかった。45 / 73
Decide implimentation methods of QueriesPayment progress notificationReply the state of TransactionActorPayment history listAggregate multiple TransactionActor states© 2019 TIS Inc.クエリの実装方法を決定。通知は TransactionActor の状態を返し、履歴一覧は複数の TransactionActor の状態を集約46 / 73
Design entities as a state machineTokenActorUnused InUse[???][???]© 2019 TIS Inc.ステートマシンとして Entity を設計47 / 73
Design entities as a state machineTransactionActorWaitingForReadToken PreparingToPayment WaitingForPaymentExecutionFinishedWaitingForPaymentCancellation[???][???] [???][???] [???][???][???]© 2019 TIS Inc.ステートマシンとして Entity を設計48 / 73
TokenActorTo use startedExpiredTransactionActorToken readPayment startedPayment failedPayment completedCancellation started...Find events to change state of an entity© 2019 TIS Inc.エンティティの状態を変更するイベントを分析49 / 73
Apply events to state machinesTokenActorUnused InUse[Tousestarted][Expired]© 2019 TIS Inc.ステートマシンにイベントを適用50 / 73
Apply events to state machinesTransactionActorWaitingForReadToken PreparingToPayment WaitingForPaymentExecutionFinishedWaitingForPaymentCancellation[Tokengenerated][Tokenread] [Paymentstarted][Paymentfailed] [Paymentcompleted] [Paymentfailed][Cancellationstarted] [Cancellationcompleted] [Cancellationfailed]© 2019 TIS Inc.ステートマシンにイベントを適用51 / 73
Decide implimentation methods of QueriesPayment progress notificationReply the state of TransactionActorPayment history listAggregate multiple TransactionActor states© 2019 TIS Inc.クエリの実装方法を決定。通知は TransactionActor の状態を返し、履歴一覧は複数の TransactionActor の状態を集約52 / 73
How to construct payment history listTransactionActor knows a payment status.However, to simply collect the state of the entity isinefficient.© 2019 TIS Inc.TransactionActor は決済のステータスを知っているが、entityの状態を単純に集めるのは非効率53 / 73
How to construct payment history listConstruct payment hisotry listfrom events in Command-side to Query-sideusing akka-persistent-query© 2019 TIS Inc.Persist on the Query-side in a form easy to sumand list❝Command-Side のイベントを元に Query-Side へ決済履歴一覧を作成54 / 73
How to construct payment history listNeed to consider about the delay of Query-side updates.We can accept the delay because payment history list willbe visible by user action.© 2019 TIS Inc.There is NO strong consistency betweenCommand-Side and Query-Side❝Query-side への反映には遅延があるため許容できるか要検討。決済履歴一覧はユーザー操作によって開かれるため許容できた。55 / 73
Reduce the delay until updated Query-sideThe delay is about 10 seconds by default.How does the delay affect the business ?Can not cancel paymentSome delay is acceptable, but it is better to update faster© 2019 TIS Inc.クエリサイドが更新されるまでの遅延を短縮する。キャンセルできるようにできるだけ早く反映されるほうが望ましい。56 / 73
Use pubsub-notificationWe could reduce the delay by Turning onof akka-persistence-cassandra.However, this option disabled guarantee to order eventsfrom multiple entities by time.© 2019 TIS Inc.akka-persistence-cassandra/reference.confpubsub-notification という設定を有効にして遅延を短縮できたが、Entity を跨るイベントの順序が保証されなくなる。57 / 73
How to get scalability and availabilityof Command-sideDistribute TransactionActor and TokenActor acrossseveral server with Akka Cluster Sharding© 2019 TIS Inc.Akka Cluster Sharding を使って TransactionActor と TokenActorを複数サーバーに分散配置58 / 73
Prepare for Split BrainA phenomenon in which a cluster is divided into multipleparts due to a network failure etc.This cause to lose consistency of the data.© 2019 TIS Inc.ネットワーク障害などによりクラスターが分割され、データの一貫性が損なわれたりする現象59 / 73
Split Brain in Akka Cluster ShardingIf split brain occurs in Akka Cluster Sharding, multipleEntities with the same ID will be created.Consistency is lost because the state of entity is notsynchronized.© 2019 TIS Inc.Akka Cluster Sharding で Split Brain が発生すると同じ ID のEntity が複数生まれてしまい、一貫性が維持できなくなる60 / 73
Split Brain in Akka Cluster ShardingAkka Cluster Shardings auto failover is disabled bydefault, which prevents Split Brain.But it will lower the availability.© 2019 TIS Inc.Akka Cluster Sharding の自動フェイルオーバーは Split Brainを防ぐためデフォルトで無効になっている。61 / 73
Split Brain Solutions for Akka ClusterSplit Brain Resolver (Lightbend: Akka Commercial Addons)TanUkkii007/akka-cluster-custom-downingmbilski/akka-reasonable-downingStop one or all of the split clusters due to network failureto prevent data inconsistency.© 2019 TIS Inc.akka-cluster スプリットブレインリゾルバ OSS実装一覧 - Qiitaネットワーク障害によって分裂したクラスターの片方か、もしくは全てを停止させてデータの一貫性が崩れるのを防ぐ62 / 73
Split Brain Solutions for Akka ClusterSplit Brain Resolver (Lightbend: Akka Commercial Addons)TanUkkii007/akka-cluster-custom-downingmbilski/akka-reasonable-downingStop one or all of the split clusters due to network failureto prevent data inconsistency.The stop fire an failover of entities.© 2019 TIS Inc.akka-cluster スプリットブレインリゾルバ OSS実装一覧 - Qiitaネットワーク障害によって分裂したクラスターの片方か、もしくは全てを停止させてデータの一貫性が崩れるのを防ぐこの停止により Entity のフェイルオーバーが引き起こされる63 / 73
Consider downtime due to failureWhat will happen if Cluster Sharding nodes crashed or thenetwork failure ?Part of users will not be able to use the service.© 2019 TIS Inc.ノードのクラッシュやネットワーク障害によって、一部のユーザーがサービスを利用できなくなる。64 / 73
Downtime indication25 seconds(for a cluster of 10 nodes)failure detection: 5 secondsstable-after: 10 secondsdown-removal-margin: 10 secondsDowntime increases as nodes increase© 2019 TIS Inc.Split Brain Resolver · Akka Commercial Addonsダウンタイムの目安ノードが増えるごとにダウンタイムも増加する。65 / 73
Downtime indication© 2019 TIS Inc.Split Brain Resolver · Akka Commercial Addons66 / 73
Tune recovery timeWe can tune recovery time by to change Akka Cluterconfiguration.However, it is trade-off between recovery time and falsepositives or temporary Split Brain.© 2019 TIS Inc.Akka Cluster の設定を調整し、ダウンタイムを短くすることはできるが、障害の誤検知や一時的な Split Brain とのトレードオフ67 / 73
Data migrationCommand-side datastore (Cassandra) has no data aboutpast payments.Can not cancel past payments due to itWe had to construct Command-side data frompayment history which is in RDBMS© 2019 TIS Inc.コマンドサイドには過去の決済データがないため、RDBMSの決済履歴からコマンドサイドのデータを作成する必要があった68 / 73
SummaryWe could reconstruct a part of CRUD style systemto ES + CQRS with AkkaIt is not necessary to achieve a perfect ReactiveSystem from the beginning© 2019 TIS Inc.CRUDスタイルのシステムの一部分を Akka で再構築。最初から完璧なリアクティブシステムを達成する必要はない。69 / 73
SummaryWe could reconstruct a part of CRUD style systemto ES + CQRS with AkkaIt is not necessary to achieve a perfect ReactiveSystem from the beginningIf you want to challenge it...© 2019 TIS Inc.CRUDスタイルのシステムの一部分を Akka で再構築。最初から完璧なリアクティブシステムを達成する必要はない。70 / 73
We are hiring!Scala で開発したいAkka Cluster を実務で使ってみたい私服勤務/フルフレックス/在宅勤務制度あり© 2019 TIS Inc. 71 / 73
TIS で培われたシステム開発のプラクティス集Lerna についても掲載予定!(公開日未定)https://fintan.jp/© 2019 TIS Inc. 72 / 73
TIS Inc.© 2019 TIS Inc. 73 / 73