sparkストリーミングkafkaを使用してしばらくの間、現在までcreateStream
のKafkaUtils
メソッドを使用していた。
createDirectStream
の調査を開始したばかりで、次の2つの理由で気に入っています。
1)「正確に1回」のセマンティクスの改善/容易化
2)kafkaトピックパーティションとRDDパーティションの相関性の向上
createDirectStream
が実験的としてマークされていることに気付きました。私が持っている質問は(これがあまり具体的でない場合は申し訳ありません):
createDirectStream
メソッドを調査する必要があるのは、1回だけが非常に重要な場合ですか皆さんがあなたの経験をそれと共有できれば素晴らしいでしょう。信頼性などの他の問題に対処しなければならないリスクを負っていますか?
直接的なアプローチの作成者(Cody) here によるすばらしい、広範囲のブログ投稿があります。
一般に、Kafka=配信セマンティクスのセクションを読んで、最後の部分はこう言います:
したがって、実質的にKafkaは、デフォルトで少なくとも1回の配信を保証し、ユーザーがプロデューサーの再試行を無効にし、メッセージのバッチを処理する前にそのオフセットをコミットすることにより、最大で1回の配信を実装できるようにします。正確に-1回の配信では、宛先ストレージシステムとの連携が必要ですが、Kafkaは、これを簡単に実装するためのオフセットを提供します。
これは基本的に「箱から出して少なくとも1回は提供しますが、正確に1回だけ必要な場合はそれはあなたにあります」。さらに、ブログの投稿では、Sparkから得られる「正確に1回」のセマンティクスの保証について、両方のアプローチ(直接および受信者ベース、強調鉱山))について説明しています。
次に、Sparkが出力アクションの1回限りのセマンティクスを保証しないことを理解してください。Sparkストリーミングガイドが説明するとき正確に一度、それは純粋に機能的な意味で、計算された値に含まれているRDDの特定の項目を参照するだけです。副作用の出力操作(つまり、結果を保存するためにforeachRDDで行う操作)は繰り返されます。プロセスのいずれかのステージが失敗して再試行される可能性があるためです。
また、これはSparkドキュメントがレシーバーベースの処理について言っていることです:
最初のアプローチ(Receiverベース)では、Kafkaの高レベルAPIを使用して消費されたオフセットをZookeeperに格納します。これは伝統的にカフカからのデータを消費する方法です。 このアプローチは(先読みログと組み合わせて)データ損失ゼロ(つまり、少なくとも1回のセマンティクス)を保証できますが、一部の障害では、一部のレコードが2回消費される可能性が少しあります。
これは基本的に、ReceiverベースのストリームをSparkで使用している場合、出力変換が失敗した場合でもデータが重複している可能性があることを意味します。少なくとも1回はです。
私のプロジェクトでは、ダイレクトストリームアプローチを使用しています。この場合、配信のセマンティクスは処理方法に依存します。つまり、セマンティクスを1回だけ確認したい場合は、データとともにオフセットをtransactionのような方法で格納できます。一方が失敗した場合も、もう一方も失敗します。
ブログの投稿(上記のリンク)と Kafkaドキュメントページ)の配信セマンティクス を読むことをお勧めします。結論として、ダイレクトストリームアプローチを検討することをお勧めします。