非同期ストリーム処理の標準化を目指す "Reactive Streams" とは

TL でこんなのが流れてたので少し調べてみた。

Reactive Streams って?

JVM 上でのノンブロッキングなバックプレッシャーを持つ非同期ストリーム処理の標準の提案”(公式サイトより)。

ざっくり言うと、既にある JVM ベースの様々な非同期ストリーム処理フレームワーク実装の共通部分を括りだして API 化、SPI 化しようというもの。最終的には JSR での標準化を目指している。

ここで言う”非同期ストリーム処理”とは、(広義の)リアルタイム性が求められるデータ処理中心のアプリケーション、より具体的にはビデオストリーミングや数百万ユーザのトランザクション処理など。

下のインタビュー記事では、Reactive Streams を策定する理由として、API 策定による相互運用性の向上と共に、バックプレッシャー (back pressure) による流量制御の必要性が挙げられている。

以上から分かるように、この "API" はユーザが直接使うものではなく、各フレームワークが、この API を使ってエンドユーザ向けの DSL を提供するためのもの。これにより、異なるフレームワーク間の相互運用性を担保できる。逆に言うと、ユーザがデータ変換や分割・結合を記述する方法は守備範囲ではない

なお、この仕様が出てきた背景としては、去年の秋くらいから "Reactive Manifesto"日本語訳)というキャンペーンが始まっていて、Reactive Streams はその流れに連なっていると思われる。

どんな仕様なの?

概要がこの辺に、より詳細な仕様がこの辺に書かれている。

現状、SPI コンポーネントの構成要素は以下の三つ。普通の Pub/Sub だけど、バックプレッシャーを伝える方法が定義されているのが特徴?

  • Publisher
    • Subscriber からの要求に応じて、潜在的に無制個の順序付けされた要素を提供する。Publisher は複数の Subscriber に配信することができ、処理率に応じて配分する。
    • これ以上、要素を提供できないときは Subscriber の onComplete メソッドを呼ぶ。
  • Subscriber
    • 一つ以上の Publisher を購読して、順序付けされた要素ストリームを受け取る。Producer が Subscriber に要素を渡すときは onNext コールバックを呼ぶ。Subscriber は、Producer をブロックせずに非同期処理するかキューイングする必要がある。
  • Subscription
    • Subscriber から Producer へ要求を伝えるときに使う。Subscriber が Subscription の requestMore(int) メソッドを呼ぶと、Publisher は 制限時間 T が経つ前に最高 N 回まで onNext メソッドを呼び出せる。

API レベルでは、上記の Publisher に対応する型として Producer が、Subscriber に対応するものとして Consumer が定義される。また、両者を組み合わせて入力と出力の両方を行う Processor も提供される。

【追記】組み合わせるとこんな感じ?

誰が関わってるの?

Scala 言語Akka フレームワークの開発をしている Typesafe 社が中心となって仕様策定を進めている。Akka 開発者による解説記事はこちら

それ以外にも、以下のような人々やプロダクトが関わっている。

JVM エコシステムの各方面で実績のある人物・プロダクトが、ズラッと一堂に会しているのが印象的。特に、Oracle の人や Doug Lea 氏が関わっている辺りを見ても、標準化に対する本気が伺える。(元)Microsoft の人が一枚噛んでるのも興味深い。

批判とか

Reactive Streams の”思想的根拠”である Reactive Manifesto に対する批判。たしかに、”そもそも "Reactive" って何だよ” というのがよく分からない感じはある。

ただ、Akka というプロダクトは明らかに Erlang/OTP に対するリスペクトから出てきたものだし、本人達もそれを隠しているわけではない(例えば、Akka の公式サイトの名前は "Let it crash")。アクターモデルを広めたいという意図こそあれ、Erlang の成果を横取りしようとしている、というのは考え過ぎじゃないかなぁと。【追記】: @pokarim さんから「(引用した発言に)そのような意図はない」とご指摘を受けたので訂正します。失礼しました。

まとめ

非同期ストリーム処理フレームワークは乱立気味、というか思い切り乱立しているので、使う側からすると「標準化してくれるのは助かるなぁ」という感想。

とりあえず、これから出てくる実装を開発者が各々の立場から調べて、フレームワークの相互運用性や流量制御といったフィーチャーが、自分たちのユースケースに対してどの程度メリットがあるのか判断していけば良いのではないかと思う。

あと、そういえば Storm に声は掛かってないんだろうか? 明らかにこのモデルに乗っけられそうだけど。