クラウドコンピューティングが普及し、多くの企業が日常的に膨大で多様なデータを扱うようになるにともない、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は、自社開発のビジネスコミュニケーションツール「チャットワーク」を通して、グループチャットやファイル共有、タスクマネジメント、ビデオ会議といったサービスをオールインワンで提供しています。サービスはすべてAWSクラウド上で展開されており、PCやスマートフォン、タブレットといった標準的なデバイスはほぼすべてサポート、言語も6ヵ国語に対応しています。現在、205の国と地域で13万8,000社に採用されており、急速にビジネスを伸ばしている会社でもあります。
セッションに登壇したChatWork コアテクノロジー開発室 ソフトウェアエンジニア 大村伸吾氏はChatWorkのサービスの特徴として「組織を超えたコミュニケーションが容易に実現できること」を挙げています。数年前まではセキュリティ上の観点から、社内に閉じた環境でしか使えないビジネスコラボレーションツールとが多かったのですが、最近では1つのプロジェクトを複数の社外担当者とともに進めるケースが劇的に増えており、社内/社外という壁を感じさせないコミュニケーションのあり方が一般的になっています。大村氏によれば「チャットワークのユーザのうち60%が社内と社外の両方のコミュニケーションに利用しており、10%のユーザは社外とのコミュニケーションにしか使っていない」とのことで、組織を超えたコミュニケーション/コラボレーションは、今後もさらに一般化すると見られています。
コミュニケーションの多様化というトレンドを受け、ChatWorkのビジネスは急速に拡大しましたが、それは同時に、同社が扱うメッセージの数も増大していることを意味しています。大村氏は「ChatWorkが扱うメッセージの数は年率200%で増えており、2017年は20億にも達する」と説明していますが、おそらくこの数はさらに増えるはずです。ここでChatWorkはメッセージングシステムとしての"スケールの壁(技術的負債)"にぶつかることになります。
急速に伸びるビジネスとともにメッセージの量も倍々で拡大中。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と、イベントソーシングを組み合わせることで、リードにフォーカスしながらもイベントごとにモデルをビルドできるスケーラブルなシステムを構築できる
リード(クエリ)とライト(コマンド)に別々のモデルを適用できるということは、リードヘビー、あるいはライトヘビーなワークロードのどちらにもフォーカスしやすいことを意味します。チャットワークの場合、扱うメッセージデータの約95%がリードメッセージであり、しかもその多くが直近のメッセージに集中しているという、まさにリードヘビーの典型でした。しかし当然ながら、誰もがつねに書き込みできる状態は維持しておく必要があり、またすべてのタスク/ファイルがメッセージリンクにひもづいているので、誰かが突然、古いメッセージを閲覧するケースも往々にしてあります。
チャットワークのワークロードは95%がリードで、そのほとんど直近のメッセージを対象にしたもの。リードを前提としたバックエンドの構築が求められる
このように、基本的には直近のメッセージを対象にしたリードヘビーなワークロードを前提にしつつも、メッセージの書き込みや古いメッセージの閲覧といったリクエストに対してもつねにレディな状態であるために、NTTデータはCQRSに加え、イベントソーシングも同時に提案しています。イベントソーシングはCQRSとセットで語られることが多いアーキテクチャで、"イベント=不変の事実"という概念に従っており、一度記録されたイベントが変更(更新)や削除されることはありません。イベントはシーケンシャルにストアされ、最新の状態(ステータス)を知るにはイベントを履歴にそって再現することが必要となります。
今回のケースでは、コマンドサイドにイベントソーシングを実装し、イベント(新規メッセージの書き込みなど)の発生順に、書き込まれたメッセージをパイプラインを通じて変換してクエリサイドに渡す、まれに古いメッセージの読み込み要求などがあっても、イベントから再現する機構を実装することで、リクエストに応じる、といったモデルを構築しています。ポイントはイベントが発生するたびにビルドを実行するという点で、大量のイベントが発生してもレイテンシを低く抑えたまま、スケール可能なアーキテクチャを実装できるかが重要なカギになります。
Kafkaを中心としたOSSでシステムを構築
NTTデータが今回のCQRS+イベントソーシングシステムを実装するにあたって、採用したプロダクトは以下になります。いずれもオープンソースのプロダクトです。
Akka
非同期で疎結合なメッセージングを実現する並列分散処理のためのアクターモデルなフレームワーク。ノンブロッキングI/Oを前提に設計。今回のシステムではコマンドサイドとクエリサイドのAPIサーバで使用。レジリエントな設計が可能で高いパフォーマンスを実現
Kafka
データプロセッシングのパイプラインとして機能するpub/sub型のメッセージングシステム。今回のケースではイベントソーシングのハブとなるセントラルログシステムとして活用。低レイテンシ/高スループットとスケールのしやすさ、耐障害性の高さで、メッセージングシステムのデファクトになりつつある
Kafka Streams
Kafkaに同梱されているライブラリで、ストリーム処理をシンプルに記述できる。Kafkaの一部であるため、今回のシステムのコアであるKafkaとの親和性が高く、容易で迅速な実装が可能に。Akkaと組み合わせてリードモデルの変換アダプタ(アップデータ)を記述
HBase
HadoopエコシステムのNoSQLデータベースで大量のリード/ライトのリクエストに効率的に対応可能。今回はクエリサイドでリードモデルやコミュニケーションサービスのマスターデータをストアするために利用
今回のシステムにおけるアーキテクチャ全体図。主役はやはりKafka
このシステムの最大のポイントは、やはり現在もっともスタンダードなメッセージングシステムとしての地位を獲得しつつあるKafkaをパイプラインとして活用しているところだと思われます。NTTデータ システム技術本部 方式技術部 第一統括部 OSSプロフェッショナルサービス 課長代理 土橋氏はKafkaを選択した理由として「スケーラビリティに加え、パーティション単位のメッセージの順番が担保されており、かつ、さまざまなサービスとインテグレートしやすい」という点を挙げていました。Kafkaには負荷分散の効率を高めるためにトピック(メッセージの単位)を分割する「パーティション」という機能が実装されており、同じパーティション内であればメッセージの順番は保証されます。このシステムでは「チャットルームのIDをベースにパーティショニングのキーを設計し、メッセージの順番を保っている」( 大村氏)とのこと。
ただし、ChatWorkでは1,000以上のパーティションを管理しており、またKafkaには自動でパーティションをリバランスする機能がサポートされていないため、運用で苦労している部分もあるようです。また「パーティションの数はメッセージのプロデュースのコストに直結するため、割り当てはできるだけシンプルかつデフォルトを推奨」「 パーティションのキーは一度設定したら変更しない」など、パーティション設定におけるTipsを把握しておくことも重要だそうです。
さらに新機能の統合へ
PoCも含めて約1年の開発期間を経て本番稼働となった本システムですが、「 既存のシステムと比較してパフォーマンスにおいて大きな改善が見られている」と大村氏は説明します。本番稼働後も目立ったトラブルはなく、順調に稼働しているとのこと。以下、既存のシステムとの比較として大村氏が挙げたポイントを抜粋します。
コマンドサイド(Write API)
スループット(負荷テスト)は2つのwrite-apiポッド(コンテナ)だけで既存システムのピーク時の40倍に、レイテンシは200ミリ秒から80ミリ秒に、イベント発生からKafkaブローカーへの配信までの時間は20ミリ秒
クエリサイド(Read API)
スループット(負荷テスト)は4つのread-apiポッドで既存のピーク時とほぼ同等、レイテンシは70ミリ秒で同じ、HBaseのブロックキャッシュヒット率は99%
リードモデルアップデータ
リードモデルがアップデートされるまでのタイムラグは80ミリ秒、障害時(ローリングアップデートのためにコンシューマポッドがダウンした場合など)にもパーティショニングの再割当てが自動で行われ、処理が継続されるなど、AkkaおよびKafkaがレジリエントに機能
現在はKafkaがPub/Subモデルに基づき複数のシステムと連係しやすいことを活かして、他のマイクロサービスを統合することも始めており、たとえばモバイルデバイスへの通知サービスや全文検索サービスなどに使うイベントフォワード機能や、Webフックサービスを提供する機能も追加しているそうです。
CQRSやイベントソーシング、あるいはKafkaやAkkaといったオープンソースプロダクトは、とりたてて最新の技術トレンドというわけではなく、またミドルウェアという目に見えにくいレイヤを担当する部分でもあるため、あまり目立った適用事例はこれまで発表されてきませんでした。ですが今回のChatWorkの事例は、現在展開中のコラボレーションサービスにおけるスケールを前提としたKafkaのエンタープライズな導入事例として、国内のみならず、グローバルでも非常にユニークなケースであるといえます。
また大村氏は「今回のシステム構築にあたってはNTTデータがもつオープンソースに関する技術力や知見に大いに助けられた」と振り返っていました。今回のシステム構築は、ChatWork側の要件がクリアであり、同社にクラウドやデータベースに関する相応の技術力があったからこそスムースに運んだ部分は大きいのですが、それに加えてオープンソースのエキスパートが揃ったインテグレータが支援にあたったことで、より高いレベルのゴールを達成できた印象があります。
KafkaやAkka、HBaseなどは単体での導入もさることながら、それぞれの特徴を理解してコンポーネントとしてこれらを組み合わせ、堅牢で信頼性のあるシステムを構築できる人材はそう多くはありません。オープンソースが社会の重要なシステムで使われる機会が増えているからこそ、ビジネスの要件に見合った適切なアプローチとプロダクトを選び、実装できるスキルセットを備えた人材の育成が今後はますます求められるようになることは間違いないでしょう。
セッション後の1枚
余談ですが、筆者は年に10回ほど米国を中心に海外のITイベントを取材しますが、今回のように日本のユーザ企業とインテグレータがグローバルなカンファレンスの場で登壇し、最先端のユースケースを英語で発信するという光景を見る機会は、残念ながらまだそれほど多くはありません。ですが今回のように日本企業がみずから進んで情報公開を行うことで、グローバルで関心をもたれる機会が増えれば、日本企業のIT業界における存在感もすこしずつ増していく気がします。そうした意味において、今回の両社による発表はあとに続くIT関係者に次の一歩を踏み出させるきっかけとなったセッションであったように思います。