塚原氏の自己紹介

塚原諒氏:こんばんは。今日は「マイクロサービス・モジュラモノリス化によるシステム負債の解消プロジェクト」というタイトルで発表します。

(スライドを示して)まずは自己紹介をさせてください。名前は塚原諒といいます。2022年の4月に中途でDMMに入社して、オンラインサロン事業部のアーキテクトチームに所属しています。

ふだんは本日紹介するマイクロサービス、モジュラモノリスでのリプレイス業務を主にやっています。(スライドには)書いていないんですが、好きなテキストエディタは「Vim」です。よろしければ(コメントに)好きなテキストエディタとかを書いてください。(こちらも)なにか反応できればなと思っています。

Twitter、GitHubは「trrrrrys」というIDで活動していて……。あまり(この名前で)呼ばれたことはないんですが、こういうIDで活動しています。「r」は間に5つ入っています。DMで好きなテキストエディタについて送ってきてもらっても大丈夫です(笑)。

本セッションで話すこと

とりあえず、今日話すことについて紹介します。まず現状のシステム的な課題について。そして「マイクロサービス・モジュラモノリス化プロジェクト」についての紹介。あとはこれまでやってきたこと、現在取り組んでいること、これらについて話していければと思っています。残念ながらVimについては話さないので、別で話したいなと思っています(笑)。

DMMオンラインサロンが抱えているシステム的な課題

まずシステム的な課題についてですね。(スライドを示して)DMMオンラインサロンは、このような3つのシステムで動作をしています。まず、2016年に入会・管理画面をリリースしました。リリース当初はユーザーの管理や支払い周りの機能のみを提供していて、実際のユーザーの交流にはFacebookのグループを利用してサービスの運営をしていました。

その後、2018年に専用のコミュニティサービスをリリースして、オンラインサロン内部で、コミュニティがサービスのみで完結するようになりました。

2020年に、ライブ配信システムをリリースして、現在この3つのシステムが主に動いている状態になっています。

2年置きに都度追加してきたので、現状は分散モノリスみたいなかたちになってきていて。その時々というか、リリースしたタイミングでは最適な選択をしてきたつもりではあるんですが、サービスが大きくなるにつれて徐々に技術的負債のようなかたちになってきています。

ざっくり例を挙げるんですが、入会・管理画面と専用のコミュニティサービスのデータベースが分かれていて、アカウント情報がそれぞれのデータベースにあるようになっています。

例えば同期をしたり……。あとは、あるデータが片方にあるんですが、片方にはなくて。片方にはないデータをシステム上で使うので、片方のシステムに問い合わせをして、けっこう密な連携をしていたりしますね。

開発初期、2016年初期は外注して開発を行っていた、あとは社内にあまりドキュメントが存在していなかったり、異動や退職もあって。(かつての)メンバーが(今は)残っていません。

(そのため)システムのフローが複雑になって、仕様の把握がけっこう複雑になっているような状況があって。新機能の要望があっても、追加するのに時間がかかってしまうような、リードタイムの悪化を招いているシステムの構造になっています。

プロジェクト「neon」の発足

このようなシステムの負債によるリードタイムの問題を解決するために、2022年1月にシステムのリプレイスの専任のチームを立ち上げて、「neon」というプロジェクトを進めています。この専任チームというのが、僕が今所属しているアーキテクトチームというチームです。neonは「the nexus of onlinesalon」の略称です。

先述した分散モノリスのシステムを、マイクロサービスとモジュラモノリスでリプレイスを行って、システムの課題を解決して、ビジネスのスケールに耐えて。あとは類似サービスやほかの競合の機能だったり要望だったりに対して、迅速に対応ができるプロダクト基盤(を作ること)を目的としてプロジェクトを進めています。

分散モノリスから適切な単位で分割を行い、基本的なスケーラビリティの向上や、リードタイムの短縮を目的としています。完全なマイクロサービスではなくて、主要なサービスをモジュラモノリスとして扱うようなアーキテクチャを採用しています。

主要なサービスというのは、DMMオンラインサロンでいうと、オンラインサロンの会員を扱うサービスやコミュニティを扱うサービスみたいなものをモジュラモノリスとして扱っています。あとはID情報や通知、決済周りみたいなものは、マイクロサービスとして個別で切り出すかたちになっています。

マイクロサービスにおいてチーム編成や組織をどうするか、みたいな。アーキテクチャに対して組織をどうするか、みたいなものはどこの組織でもよくある課題だとは思います。

弊社の場合は直近だと、サービスごとにチームを分割する想定はなくて、1チームでの運用を想定しています。なので完全なマイクロサービスにすることなく、過度な分割を避けて、扱いやすい単位でモジュラの一部、一部というか主要なサービスをモジュラモノリスを選択して設計をしました。

これからの開発規模に応じて柔軟にサービスを切り出せるように、モジュラモノリスという選択をして、現状の分散モノリスではできていなかったシステムの責務の明確化をして、5年後、10年後に対応できるようなアーキテクチャを目指して開発を行っています。クライアント側からはBFF(Backend For Frontend)を介して「neon」というサービスを利用するかたちになります。

「neon」の技術スタック

簡単に技術スタックの紹介をします。マイクロサービス部分に関してはGo言語でできたアプリケーションで動いていて、サービス間の通信にgRPCを採用しています。

一部、Pub/Subや非同期通信を利用したサービスも存在しています。BFFとしてNode.js、TypeScriptに「fastify」と「GraphQL Yoga」を採用したGraphQLサーバーをBFFとして用いています。クラウドインフラはAWSの「Fargate」を利用して運用しています。

チームの発足からこれまでやってきたこと

では、チームの発足からこれまでやってきたことについて、一部紹介できればなと思っています。

(スライドを示して)まず、管理画面と専用コミュニティのデータを新DBに同期するシステムを作りました。先ほど問題として挙げたと思いますが、各システムに情報、データが分散されていて、システム的に密結合になってしまっている状況を避ける、解消するために、アカウント情報を統一し、分散されているDBを新しいDB1つに統一しようというプロジェクトをやりました。

これはAWSの「MSK」、「Apache Kafka」のマネージドサービスの「Debezium connector」。これはいわゆるCDC(Change Data Capture)みたいなものを利用して、管理画面・専用コミュニティサービスのデータベースの変更を検知して、これを「Lambda」でデータを加工して新しいDBにデータを同期しています。

もともとAWSの「DMS(Database Migration Service)」みたいなものもあって、それも検討していたんですが、管理画面と専用コミュニティの2つのデータベースをソースにして、新しいDBへ加工をしてデータ同期を行うような要件に対して実現できなかったため、今回はMSKとDebeziumのコネクターを採用して実装を行いました。

基本的にLambda内ではイベントとしてDBの変更情報が渡されます。この渡された情報を元に新しいDBへ加工をして、新しいDBへINSERTを行っています。

データの元DBでデータの更新を行った後、だいたい1秒ぐらいで同期が完了するシステムになっています。このシステムは実際に今も動いていて、サービスリリース後、既存のサービスが使えなくなるまでは引き続き稼働して同期を行う想定でシステムを作っています。

(スライドを示して)次はAPIのゲートウェイの構築ですね。先ほどBFFの話をしたと思いますが、neonではAPIゲートウェイパターンというアーキテクチャを採用していて、複数のサーバーやサービスを統一的に管理する仕組みを作っています。統一的に管理することで、システム全体をスムーズに運用できるようになります。

ゲートウェイにはGraphQLを採用していて、Over-fetching、Under-fetchingを防いだり、あとはクライアント側が必要なデータを柔軟に操作できることによって、新規機能の開発時のリードタイムの短縮も期待しています。

ただ、RESTのAPIにはないようなキャッシュ周りだったり、N1みたいなものも、RESTにはない懸念点としてありますが、こちら(に)も対応して実装を行いました。

あとは認可基盤の作成ですね。マイクロサービスのサービス間の認可のために、「SpiceDB」という、Googleが内部で利用している「Zanzibar」という認可システムにインスパイアされたOSSを利用して認可基盤を構築しました。

Zanzibarベースのサービスは、ユーザーとリソースに対して、リレーションのようなものを表現してアクセスを行うシステムです。

しかし、オンラインサロンではけっこう柔軟な権限設定を行うような要件があり、それをマイクロサービス間で認可として扱うために、今回はZanzibarベースのシステムを選択しました。

同様なサービスだとAuth0の「FGA」や「Ory Keto」。このようなOSSやほかのものも候補にありました。

もともとZanzibarの論文がGoogleから発表されたのが確か2019年ぐらいで、けっこう最近なこともあって、SpiceDB以外のサービスがステーブルバージョンではなかったため、今回はステーブルバージョンであったSpiceDBを選択しました。

今回は時間がないので、SpiceDBの深掘りはあまりしませんが、どこか別の場所、別の登壇の機会に深く話しができればなと思っています。

現在取り組んでいること

では現在取り組んでいることですね。現在は今開発しているneon基盤を利用して、管理画面のリプレイスを行っています。

もともとオーナーの管理画面のサロン開設までのフローが複雑で、それをわかりやすくしたいという課題があったので、それをneon基盤を用いてリプレイスを行っています。

既存の管理画面をすべてリプレイスすると、規模が大きくなってしまうので、分割して少しずつ、一部ずつリリースをする想定です。(スライドを示して)既存の管理画面はこういうものがあるんですが、新しくスマホビューに対応してみたり、今っぽくデザインもおしゃれな感じに作っています。(まだ)これはワイヤーですが、「リリースをお楽しみ(に)」という感じになっています。

システム負債になりづらいアーキテクチャを目指す

まとめです。システム的負債を解消するために、マイクロサービスとモジュラモノリスで新規基盤を開発しています。

組織の状況に合わせてアーキテクチャを設計することが大切で、マイクロサービスをやりたいからといってマイクロサービスを選択するのではなく、直近の未来や状況に合わせてアーキテクチャを設計することが大切だなと思っています。

あとは、5年後、10年後にアーキテクチャがどうなっているかはわからないんですが、5年後、10年後でも動作するような、システム負債になりづらいようなアーキテクチャを目指していきたいなと思っています。

ご清聴ありがとうございました。