レポート

スケールするメッセージングシステムを構築せよ ―チャットワークとNTTデータが挑んだKafkaベースの"土管"づくり

この記事を読むのに必要な時間:およそ 4 分

クラウドコンピューティングが普及し,多くの企業が日常的に膨大で多様なデータを扱うようになるにともない,ITの世界では"スケール"という言葉がごく一般的に使われるようになりました。ニーズに応じて利用するコンピューティングリソースを柔軟に増減し,処理を分散してシステム全体の稼働力を上げる"スケール"というしくみは,いまや"あって当然"の概念となり,加えてここ数年はスケールにおいてもよりリアルタイムに近いパフォーマンスが求められるようになっています。

これはサーバやストレージといったハードウェアリソースだけではなく,データベースやミドルウェアにおいても同様で,スケールしやすい技術としてHadoopやPostgreSQLといったオープンソースプロダクトが選ばれるケースが飛躍的に増えました。最大の理由はどれだけスケールしてもライセンス費用がかからないというコストメリットにありますが,信頼性や透明性,あるいは標準的な技術であるという点もまた高く評価されています。

リアルタイムなスケーリングへのニーズは現在,世界中のあらゆる企業において急速に拡がっています。しかし,提供するサービスのユーザが増え,扱うデータが増えれば増えるほど,インフラを自在にスケールさせることは非常に難しくなります。この課題にどう向き合えばよいのか ―本稿では6月中旬に米サンノゼで開催された世界最大規模のHadoopカンファレンスDataWorks Summit 2017 San Joseの一セッションとして発表された,ChatWorkとNTTデータによる「Worldwide Scalable and Resilient Messaging Services by CQRS and Event Sourcing Using Akka, Kafka Streams and HBase」の内容を紹介しながら,リアルタイムなスケーリングシステムを構築するために必要なポイントを考えていきたいと思います。

セッション中のChatWork 大村氏(左)とNTTデータ 土橋氏

セッション中のChatWork 大村氏(左)とNTTデータ 土橋氏

増え続けるメッセージをリアルタイムに処理するために

「コミュニケーションの変革を通じて,新しい働き方を実践する」を提唱するChatWorkは,自社開発のビジネスコミュニケーションツール「チャットワーク」を通して,グループチャットやファイル共有,タスクマネジメント,ビデオ会議といったサービスをオールインワンで提供しています。サービスはすべてAWSクラウド上で展開されており,PCやスマートフォン,タブレットといった標準的なデバイスはほぼすべてサポート,言語も6ヵ国語に対応しています。現在,205の国と地域で13万8,000社に採用されており,急速にビジネスを伸ばしている会社でもあります。

セッションに登壇したChatWork コアテクノロジー開発室 ソフトウェアエンジニア 大村伸吾氏はChatWorkのサービスの特徴として「組織を超えたコミュニケーションが容易に実現できること」を挙げています。数年前まではセキュリティ上の観点から,社内に閉じた環境でしか使えないビジネスコラボレーションツールとが多かったのですが,最近では1つのプロジェクトを複数の社外担当者とともに進めるケースが劇的に増えており,社内/社外という壁を感じさせないコミュニケーションのあり方が一般的になっています。大村氏によれば「チャットワークのユーザのうち60%が社内と社外の両方のコミュニケーションに利用しており,10%のユーザは社外とのコミュニケーションにしか使っていない」とのことで,組織を超えたコミュニケーション/コラボレーションは,今後もさらに一般化すると見られています。

コミュニケーションの多様化というトレンドを受け,ChatWorkのビジネスは急速に拡大しましたが,それは同時に,同社が扱うメッセージの数も増大していることを意味しています。大村氏は「ChatWorkが扱うメッセージの数は年率200%で増えており,2017年は20億にも達する」と説明していますが,おそらくこの数はさらに増えるはずです。ここでChatWorkはメッセージングシステムとしての"スケールの壁(技術的負債)"にぶつかることになります。

急速に伸びるビジネスとともにメッセージの量も倍々で拡大中。2017年度は20億を超える見込み

急速に伸びるビジネスとともにメッセージの量も倍々で拡大中。2017年度は20億を超える見込み

現状を超えた"スケールアップ"ができない
チャットワークがバックエンドとして利用しているAWSのデータベースインスタンスはAmazon Auroraの「db.r3.8xlarge」⁠メモリ最適化に特化したクラスの中でも最上級のスペック(vCPU 32,メモリ244GB,ネットワーク10Gbit)を備えたインスタンスであり,これ以上のスケールアップは現状では不可能となります。
ACIDではスケールしない
Auroraはクラウドネイティブなデータベースですが,基本的にRDBMSであり,ACID特性を満たすことを要求されるため,とうしてもスケールしにくいというトレードオフが発生します。これを回避するには「一貫性(Consistency)のレベルをゆるめることを受け入れる必要がある」と大村氏は語っています。
モノリシックな構成では困難
デプロイ,メンテナンス,最適化といった面からも,モノリシックなバックエンドではシステムを維持することが困難になっていました。

これらの課題から,いまこの瞬間も増え続けている膨大なメッセージをリアルタイムに処理していくにはどんなバックエンドが必要なのか ―ChatWorkがたどり着いたのは

スケールとレジリエンスを担保するレベルを分離する
APIサーバ(ステートレス)はレジリエンス優先で高スループット&低レイテンシな設計に,加えてフォルトトレラントで障害時の自動復旧も行う。一方でストレージ(ステートフル)は永続性と予測が重要,必要なときにスケールできる状態にしておく。レジリエンスやフォルトトレラントはAPIサーバほど重要ではないが,あったほうがよい
弱いレベルの一貫性(イベンチュアル一貫性)を受け入れる
一時的に一貫性が保たれていない状況がある(読み込んだデータが多少古い可能性がある)ことを許容する。最低限,同じチャットルームにいる全員が同じ状況下でメッセージを閲覧できていることを担保する

という2つの結論でした。そしてこの要件を満たすシステムのデザインと構築を共同で実施したのがNTTデータでした。

「リード」「ライト」に別々のモデルを適用

NTTデータはHadoopやSpark,PostgreSQLといったオープンソースのシステム構築で国内でもトップクラスの導入実績を誇ります。今回,ChatWorkと共に検討し採用したのは「CQRS(Command and Query Responsibility Segregation: コマンド/クエリ責務分離)⁠というアプローチでした。大村氏はCQRSについて「データベースの操作をリード(読み込み: query)とライト(書き込み: command)に分離するアーキテクチャで,リードとライトにそれぞれ別のモデルを適用できるため,柔軟性の高い,最適化されたシステムを構築しやすい」と説明しています。

コマンドとクエリを分離するCQRSと,イベントソーシングを組み合わせることで,リードにフォーカスしながらもイベントごとにモデルをビルドできるスケーラブルなシステムを構築できる

コマンドとクエリを分離するCQRSと,イベントソーシングを組み合わせることで,リードにフォーカスしながらもイベントごとにモデルをビルドできるスケーラブルなシステムを構築できる

リード(クエリ)とライト(コマンド)に別々のモデルを適用できるということは,リードヘビー,あるいはライトヘビーなワークロードのどちらにもフォーカスしやすいことを意味します。チャットワークの場合,扱うメッセージデータの約95%がリードメッセージであり,しかもその多くが直近のメッセージに集中しているという,まさにリードヘビーの典型でした。しかし当然ながら,誰もがつねに書き込みできる状態は維持しておく必要があり,またすべてのタスク/ファイルがメッセージリンクにひもづいているので,誰かが突然,古いメッセージを閲覧するケースも往々にしてあります。

チャットワークのワークロードは95%がリードで,そのほとんど直近のメッセージを対象にしたもの。リードを前提としたバックエンドの構築が求められる

チャットワークのワークロードは95%がリードで,そのほとんど直近のメッセージを対象にしたもの。リードを前提としたバックエンドの構築が求められる

このように,基本的には直近のメッセージを対象にしたリードヘビーなワークロードを前提にしつつも,メッセージの書き込みや古いメッセージの閲覧といったリクエストに対してもつねにレディな状態であるために,NTTデータはCQRSに加え,イベントソーシングも同時に提案しています。イベントソーシングはCQRSとセットで語られることが多いアーキテクチャで,"イベント=不変の事実"という概念に従っており,一度記録されたイベントが変更(更新)や削除されることはありません。イベントはシーケンシャルにストアされ,最新の状態(ステータス)を知るにはイベントを履歴にそって再現することが必要となります。

今回のケースでは,コマンドサイドにイベントソーシングを実装し,イベント(新規メッセージの書き込みなど)の発生順に,書き込まれたメッセージをパイプラインを通じて変換してクエリサイドに渡す,まれに古いメッセージの読み込み要求などがあっても,イベントから再現する機構を実装することで,リクエストに応じる,といったモデルを構築しています。ポイントはイベントが発生するたびにビルドを実行するという点で,大量のイベントが発生してもレイテンシを低く抑えたまま,スケール可能なアーキテクチャを実装できるかが重要なカギになります。

著者プロフィール

五味明子(ごみあきこ)

IT系の出版社で編集者としてキャリアを積んだ後,2011年からフリーランスライターに。フィールドワークはオープンソースやクラウドコンピューティング,データアナリティクスなどエンタープライズITが中心。海外カンファレンス取材多め。Twitter(@g3akk)やFacebookで日々IT情報を発信中。

北海道札幌市出身/東京都立大学経済学部卒。

コメント

コメントの記入