BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース NATSにKafka風ログAPIを加えたLiftbridge

NATSにKafka風ログAPIを加えたLiftbridge

原文(投稿日:2018/08/20)へのリンク

調査会社のGartnerは、企業がイベント駆動ITに注目している、と主張する。同社の調査によると、2020年にはCIOにとって優先順位トップ3になるという。成長著しいApache Kafka — 広く利用されているイベントストリーミングプラットフォーム — の存在は、その主張を裏付けているようだ。パブリッククラウドプロバイダの大手3社すべてがイベントストリーム処理を直接サービスとして提供し、多くの業界リーダがCloudEvents仕様についてコメントしている。この加熱するイベント駆動の世界に新たに加わったのが、NATSメッセージングシステムをスケーラブルなKafka風APIで拡張した、オープンソースプロジェクトのLiftbridgeである。

Liftbridgeは、NATSエンジンの長年にわたるコントリビュータである、ベテラン技術者のTyler Treat氏の手によるものだ。NATSエンジンは現在、Cloud Native Computing Foundationのホストプロジェクトとなっている。プロジェクトのオープンソース化を発表したブログ記事の中で、Treat氏は、プロジェクトの目標を、“Apache KafkaやApache Pulsarような高度なログベースのメッセージングシステムと、もっとシンプルなクラウドネイティブシステムの間のギャップを埋めること”だと説明している。プロジェクトのより詳しい情報を、これら接続システムの技術的変化の状況とともに知るべく、Treat氏に話を聞いた。

InfoQ: どのような問題が解決されるのでしょう?

Tyler Treat: 基本的にLiftbridgeは、Apache Kafkaなどのシステムと同じタイプの問題を解決します。その核となるのが、データのプロデューサとコンシューマの分離を可能にするメッセージングシステムです。ただし、Kafkaと同じく、Liftbridgeはメッセージログですので、RabbitMQのような従来のメッセージブローカとは異なり、メッセージは変更不能なコミットログに追加されます。従来のブローカでは、メッセージは通常、コンシューマによってキューから削除されますが、Liftbridgeでは、メッセージがコンシュームされてもメッセージがログに残りますので、同じログを多くのユーザが読むことが可能なのです。データベースの先行書き込みログを取り出して、サービスとして公開しているようなものです。これによって、システムを通じて送信されたメッセージの再生が可能になります。

このアプローチは、イベントソースとストリーム処理に関する多くの興味深いユースケースに適しています。例えばログ集約では、アプリケーションログとシステムログをすべてLiftbridgeに書き込んで、バッファとして機能させ、Splunk、Datadog、静的なストレージなど、さまざまなバックエンドにパイプ送信することができます。私が以前関与したある企業では、このアプローチを使って、データを分岐(tee)する手段を提供することで、複数のロギングプロバイダの同時評価を可能にしていました。LiftbridgeやKafkaのようなシステムは、非常に強力なデータパイプラインを提供することができるのです。

ただし、Liftbridgeは、Kafkaを置き換えるために開発されたのではありません。高性能だが撃ち放し(fire-and-forget)形式のメッセージングシステムであるNATSに、Kafkaのようなセマンティクスを提供することが、より大きな目標でした。NATSは分散型システムの“ダイヤルトーン”と呼ばれることがよくあります。常時オンで、単にダウンするように設計されているからです。この方法の欠点は、機能が限定されていることです。同じアナロジを使うならば、Liftbridgeはいわば、NATSへのボイスメールです。メッセージがNATSにパブリッシュされて、関係するコンシューマがオフラインの場合でも、Liftbridgeがメッセージをログに記録して、配信を保証してくれます。完璧なアナロジではありませんが、おおよその意味は理解できると思います。

InfoQ: このアーキテクチャに至るまでにどのようなことを学んだのか、重要な点を要約して頂くことはできますか?

Treat: それについては、Kafkaを設計したConfluentの人たちに感謝しなければなりません。このアーキテクチャにおける本当のパイオニアは彼らだと思うからです。LiftbridgeはKafkaから直接インスパイアされました。事実として、レプリケーションやコミットログの実装に関しては、同じコンセプトをいくつか借用しています。

私はこれまでに、いくつかのメッセージングシステムに従事してきました。NATSとNATS Streamingのコアコミッタでもありました。Liftgrideでも、これらから多くの発想を得ています。NATSを開発したDerek Collison氏や、チームのメンバにも感謝しなければなりません — 彼らの多くはTIBCOなど、メッセージングに関する大手企業に在籍している人たちです。

私が学んだ最も大きなことは、シンプルさが過小評価されている、という点です。多くのシステムが、あまりにも多くのことをしようとする過ちを犯しています。スコープを広げすぎて、いくつかの面 — パフォーマンス、スケーラビリティ、操作性など — で苦労しているのです。従来のESBがこのよい例で、動作が遅かったり、拡張性に欠けたり、あるいは操作や使用がとんでもなく難しかったりしています。

もうひとつ学んだのは、シンプルさはパフォーマンスに有用である、ということです。例えばLiftbridgeとKafkaでは、シンプルな追加専用のログを使用しています。そうすることで、シーケンシャルディスクアクセスやOSページキャッシュといったもののメリットを活用できるのです。また、LiftbridgeとKafkaは、多くのメッセージブローカのようにコンシューマの状態をトラックすることはありません。これはシステムを単純化するだけでなく、パフォーマンスにも影響します。

もっとも、目標とトレードオフの競合は常にあります。パフォーマンスに関しては、フォールトトレランスやスケーラビリティに目をつぶれば、何かを速くするのは簡単なことです。同じように、スケーラビリティとフォールトトレランスは、どちらもシンプルさに相反します。Kafkaでは、クラスタリングとフェールオーバの処理をZooKeeperに依存しています。その結果として、Kafkaは簡単に実行できるシステムではありません。LiftbridgeがKafkaと違うのは、Raftを内部的に使用して、ZooKeeperの役割を担わせていることです。コードベースが複雑になるという面もありますが、システムの操作は概ね簡単になっています。

“シンプルさ”というのが、結局は複雑性をシステム外に押し出しているだけである、ということもよくあります。Kafkaは比較的シンプルなシステムですが、複雑性の多くはZooKeeperやクライアントに押しやられています。ESBの場合は、クライアントのセマンティクスはシンプルかも知れませんが、それは複雑性がサーバ側に押し付けられた結果なのです。サーバで複雑な処理をするのは困難ではありませんが、フォールトトレランスを考慮した分散処理やデータの正確性の保持、処理速度の維持が必要な場合は難しくなります。ほとんどのブローカが、これらの分野のひとつ以上に相当しているのです。

最後は、フォールトトレランスは当てにならない、ということです。どういう意味かと言うと、既存の複雑なシステムにクラスタリングやデータレプリケーションのようなものを追加するのは、非常に難しい、ということです。これらのようにアーキテクチャ上の意味合いが大きいものは、十分な検討を行った上で、初期段階から設計しなければなりません。私についてご存知ならば、私がJohn Gall氏のSystemanticsの支持者であることもご存知だと思います。この場合は、“動作する複雑なシステムは必ず、動作する単純なシステムから進化したものである”、“スクラッチから設計された複雑なシステムは、動作させることも、動作するようにパッチを当てることもできない。最初はシンプルな、動作するシステムから初めなければならない。”という、Systemanticsの2つの原則が適応できます。私はレプリケーションシステムをスクラッチから設計し、実装して、既存の複雑なシステムに組み込んだのですが、大変な作業でした。フォールトトレランスに関しては、最初から実装しておく必要はありませんが、将来的に拡張可能なビジョンと、それを考慮した設計をしておく必要があります。

InfoQ: トラフィックの継続はNATS“のみ”で可能でしょうか、あるいは、ログベースのイベント処理専用にひとつのインスタンスが必要ですか?

Treat: LiftbridgeはNATの代替や動作を変更するのではなく、それを補完するように設計されています。これは設計上の重要な部分であって、NATS Streamingとは違う部分のひとつです。Liftbridgeをもう少し上手に例えるならば、メッセージをせっせと録音して後で再生可能にする、NATSの速記者(stenographer)といったところでしょうか。つまり、Liftbridgeがバックグラウンドで記録していても、NATSのトラフィックは通常通り継続するということです。特別な設定やコード変更は必要ありません。

InfoQ: ESB、軽量メッセージブローカ、(NATSのような)インメモリのイベントプロセッサ、ログベースのイベントプロセッサなどには、それぞれユニークな用途があるのでしょうか?あるいは他のユースケースに統合可能なメッセージエンジンのタイプが、いくつかはあると思いますか?

Treat: 興味深いことに、最近のシステムの中には、このようなユースケースをたくさんサポートしようとしているものがあります。例えばApache Pulsarは、RabbitMQがサポートしているような従来型のキューセマンティクスと、Kafaのようなストリーミングセマンティクスを“統一”したソリューションを提供しています。最近では、ストリームの計算処理 — 一般的にはApache StormやFlink、あるいはAWS Lamndaなどの役割です — が可能な関数をサポートするものも目にしました。NATS Streamingにも、もう少し制限はありますが、例えばキューセマンティクスを提供するキューグループのような、同種の機能が用意されています。

Confluentのメンバならば、Kafkaがあれば十分だと言うでしょう。リアルタイムデータ処理については、おそらくその通りだと思いますが、マイクロサービスのデカップリングは難しいでしょう。少なくとも、開発者の考え方をこのように変えさせるのは大変だと思います。パブリッシュ/サブスクライブを納得させた時も、大変でしたから。ストリーム処理で複雑なアプリケーションを構築するというのは、多くの人たちにとって自然な考え方ではないのです。事実として、Kafkaの競争相手はRabbitMQやActive MQ、ESBなどだけではありません。データベースとも競合しますし、Istioのようなサービスメッシュとも、RESTとも競合します。なぜかと言うと、基本的にConfluentは、システムの設計方法を変えようとしているのだからです。これは大きな課題です。

Streamlioならば、Pulsarですべて対応可能だと言うでしょう。ひとつのソリューションで十分なのに、システムを根本から再構築したり、あるいはメッセージキューストリーミングデータパイプラインストリーム処理フレームワークを個々に用意する必要があるのでしょうか?CIOならばこちらを選ぶでしょう。

アーキテクチャに対する私の個人的なアプローチは、比較的小さくて構成可能な、理想的にはある程度の労力で取り換えられるコンポーネントを使用することです。システムにいろいろなものを投げ込み始めると、キッチンシンクにならないか不安になってくるのです。変な話ですが、私はそれが、ESBが支持を大きく失っている理由のひとつだと思っています。私がNATSに共感を覚える部分もそこにあります。NATSは驚くほどシンプルで、スコープも適切だからです。

複数のタイプのシステムを運用する場合もあると思いますが、NATSには非常に軽量であるという長所があります。ある会社では、ホストVM上でデーモンとして動作する、一種のプロトサービスメッシュとして、実際にNATSを使用しています。IoTで使用したり、組込みデバイスで使用している人たちともたくさん話しています。射撃練習場のロボットをコントロールするために使用している人もいました。とても面白いと思います(ちょっと怖くもありますが)。数十万のノードを抱えるクラスタのコントロールプレーンとして使用している人もいます。Kafkaは大規模なデータ処理には最適ですが、JVMとZooKeeperのせいでヘビーウェイトになっています。それに見合うだけのワークロードとサポートするリソースがあるのならば、問題はありません(それが結果として、Kafkaをサービスとして提供するビジネスの存在理由にもなっています)。私はできればAmazon SQSやGoogle Cloud Pub/Subといったマネージドサービスを利用したい方なので、従来的なメッセージキューでもその役割を果たせると思っています。

InfoQ: Liftbridgeが実用的なシステムになるためには、あなた(とコミュニティ)にとって何が必要でしょうか?

Treat: いくつかあります。まずはTLSのサポートです。暗号化は当然必要だと思っています。実装自体はそれほど大変ではありませんが、それよりも問題なのは、パフォーマンスや信頼性の問題を排除するために、ロードテストやより堅牢なフォールトインジェクションテストなど、これまでよりも厳しいテストを行なう必要があることです。正確性の面では、最小限のin-syncレプリカセットをサポートする必要があります。これは基本的に、ユーザが書き込み時にクォーラム(Quorum)を要求することで、データの堅牢性の保証を可能にするものです。最後に、私の個人的な希望として、ログの圧縮(最新キーのメッセージのみを残すことでログを小さくする)、タイムスタンプと経過時間によるログのプレイバック、実装内容と監視機能の改善、Liftbridge内にNATSを組み込んで実行するオプションなどの機能を実現したいと思っています。

InfoQ: 従来のESBをやめてLiftbrigeなどに移行するには、どうすればよいのでしょう?

Treat: 従来型のミドルウェアを使用している人には、まず最初に、キューが必要な理由について考えてみるように話します。それが妥当な場合もありますが、実際には必要でないシステムに対して、キューが拙速に導入されることが非常に多いのです。“How do you cut a monolith in half?”と題した、素晴らしいブログ記事があるのですが、 この中に、短命なタスクの場合、キューは必然的に“フル”と“エンプティ”の状態で動作するため、本当に必要なのはロードバランサである、という説明があります。キューがフルであれば、エッジにプッシュするタスク数が不足しているという意味であって、短命タスクであるクライアントは待機することになります。キューが空ならば、低速のロードバランサとして動作している、ということです。この場合はNATSがロードバランサの役になります。NATSはキューではなく、ルータだからです。長寿命のタスクならば、データベースが必要です。結果処理やエラー処理のようなクライアントの寿命より長いタスクの管理には、多くのニュアンスがあるからです。

まだ確信が持てない方には、ESBからLiftbridgeへのマイグレーションパスは、あなたが思うほど大変なものではないかも知れません。まずNATSでは、NATSとレガシ技術のブリッジを容易にするために設計されたコネクタフレームワークが提供されています(LiftbridgeはNATSを拡張したものなので、データはNATSを経由します)。これを使えば、メッセージングミドルウェアからのデータを直接NATSに(すなわちLiftbridgeに)パイプすることが可能です。コンテンツベースのルーティングのように高度なESB機能を使用すれば、コネクタを使ってそれをNATSにマップできます。第2に、NATSはESBのような幅広い機能をサポートしていませんが、特にAMQPでは一般的な機能であるワイルドカードサブスクリプションをサポートしています。これは複雑なルーティングスキームをNATSにマッピングする場合に便利な、非常に強力な機能です。そしてLiftbrdigeは — NATS Streamingとは違って — NATSの拡張版なので、ワイルドカードをフルサポートしています。

 
 

この記事を評価

採用ステージ
スタイル
 
 

この記事に星をつける

おすすめ度
スタイル

BT