JavaでのKafkaStreamsの紹介

JavaでのKafkaStreamsの概要

1. 概要

この記事では、KafkaStreams libraryを見ていきます。

KafkaStreamsは、Apache Kafkaの作成者によって設計されています。.このソフトウェアの主な目標は、プログラマーがマイクロサービスとして機能する効率的なリアルタイムのストリーミングアプリケーションを作成できるようにすることです。

KafkaStreamsを使用すると、Kafkaトピックからデータを消費し、データを分析または変換し、場合によっては別のKafkaトピックに送信できます。

KafkaStreams,を示すために、トピックから文を読み取り、単語の出現回数をカウントし、単語ごとのカウントを出力する簡単なアプリケーションを作成します。

KafkaStreamsライブラリはリアクティブではなく、非同期操作とバックプレッシャ処理をサポートしていないことに注意してください。

2. メーベン依存

KafkaStreams,を使用してストリーム処理ロジックの記述を開始するには、kafka-streamskafka-clientsに依存関係を追加する必要があります。


    org.apache.kafka
    kafka-streams
    1.0.0


    org.apache.kafka
    kafka-clients
    1.0.0

また、Kafkaトピックを使用するため、ApacheKafkaをインストールして開始する必要があります。 このトピックは、ストリーミングジョブのデータソースになります。

Kafkaおよびその他の必要な依存関係をthe official websiteからダウンロードできます。

3. KafkaStreams入力の構成

最初に行うことは、入力されたKafkaトピックの定義です。

ダウンロードしたConfluentツールを使用できます。このツールにはKafkaサーバーが含まれています。 また、Kafkaにメッセージを公開するために使用できるkafka-console-producerも含まれています。

開始するには、Kafkaクラスターを実行してみましょう。

./confluent start

Kafkaが起動したら、APPLICATION_ID_CONFIGを使用してデータソースとアプリケーションの名前を定義できます。

String inputTopic = "inputTopic";
Properties streamsConfiguration = new Properties();
streamsConfiguration.put(
  StreamsConfig.APPLICATION_ID_CONFIG,
  "wordcount-live-test");

重要な構成パラメーターはBOOTSTRAP_SERVER_CONFIG.です。これは、開始したばかりのローカルKafkaインスタンスへのURLです。

private String bootstrapServers = "localhost:9092";
streamsConfiguration.put(
  StreamsConfig.BOOTSTRAP_SERVERS_CONFIG,
  bootstrapServers);

次に、inputTopic:から消費されるメッセージのキーのタイプと値を渡す必要があります

streamsConfiguration.put(
  StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG,
  Serdes.String().getClass().getName());
streamsConfiguration.put(
  StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG,
  Serdes.String().getClass().getName());

Stream processing is often stateful. When we want to save intermediate results, we need to specify the STATE_DIR_CONFIG parameter

テストでは、ローカルファイルシステムを使用しています。

streamsConfiguration.put(
  StreamsConfig.STATE_DIR_CONFIG,
  TestUtils.tempDirectory().getAbsolutePath());

4. ストリーミングトポロジの構築

入力トピックを定義したら、ストリーミングトポロジを作成できます。これは、イベントの処理方法と変換方法の定義です。

この例では、ワードカウンターを実装したいと思います。 inputTopic,に送信されるすべての文について、それを単語に分割し、すべての単語の出現を計算します。

KStreamsBuilderクラスのインスタンスを使用して、トポロジの構築を開始できます。

KStreamBuilder builder = new KStreamBuilder();
KStream textLines = builder.stream(inputTopic);
Pattern pattern = Pattern.compile("\\W+", Pattern.UNICODE_CHARACTER_CLASS);

KTable wordCounts = textLines
  .flatMapValues(value -> Arrays.asList(pattern.split(value.toLowerCase())))
  .groupBy((key, word) -> word)
  .count();

ワードカウントを実装するには、まず、正規表現を使用して値を分割する必要があります。

splitメソッドは配列を返しています。 flatMapValues()を使用してフラット化します。 そうしないと、配列のリストが作成されてしまい、そのような構造を使用してコードを記述するのは不便になります。

最後に、すべての単語の値を集計し、特定の単語の出現を計算するcount()を呼び出します。

5. 結果の処理

入力メッセージの単語数はすでに計算されています。 Now let’s print the results on the standard output using the foreach() method:

wordCounts
  .foreach((w, c) -> System.out.println("word: " + w + " -> " + c));

本番環境では、このようなストリーミングジョブが出力を別のKafkaトピックに公開することがよくあります。

to() method:を使用してこれを行うことができます

String outputTopic = "outputTopic";
Serde stringSerde = Serdes.String();
Serde longSerde = Serdes.Long();
wordCounts.to(stringSerde, longSerde, outputTopic);

Serdeクラスは、オブジェクトをバイト配列にシリアル化するために使用されるJavaタイプ用に事前構成されたシリアライザーを提供します。 バイトの配列は、Kafkaトピックに送信されます。

トピックのキーとしてStringを使用し、実際のカウントの値としてLongを使用しています。 to()メソッドは、結果のデータをoutputTopicに保存します。

6. KafkaStreamジョブの開始

ここまでで、実行可能なトポロジを構築しました。 しかし、仕事はまだ始まっていません。

KafkaStreamsインスタンスでstart()メソッドを呼び出して、ジョブを明示的に開始する必要があります。

KafkaStreams streams = new KafkaStreams(builder, streamsConfiguration);
streams.start();

Thread.sleep(30000);
streams.close();

ジョブが終了するまで30秒待機していることに注意してください。 実際のシナリオでは、そのジョブは常に実行され、到着したKafkaからのイベントを処理します。

Kafkaトピックにいくつかのイベントを公開することで、仕事をテストできます。

kafka-console-producerを開始し、いくつかのイベントを手動でinputTopic:に送信しましょう

./kafka-console-producer --topic inputTopic --broker-list localhost:9092
>"this is a pony"
>"this is a horse and pony"

このようにして、2つのイベントをKafkaに公開しました。 アプリケーションはこれらのイベントを消費し、次の出力を出力します。

word:  -> 1
word: this -> 1
word: is -> 1
word: a -> 1
word: pony -> 1
word:  -> 2
word: this -> 2
word: is -> 2
word: a -> 2
word: horse -> 1
word: and -> 1
word: pony -> 2

最初のメッセージが到着したとき、単語ponyが1回だけ出現したことがわかります。 しかし、2番目のメッセージを送信したとき、「word: pony → 2″」という単語が2回目に表示されました。

6. 結論

この記事では、Apache Kafkaをデータソースとして使用し、KafkaStreamsライブラリをストリーム処理ライブラリとして使用して、プライマリストリーム処理アプリケーションを作成する方法について説明します。

これらの例とコードスニペットはすべてGitHub projectにあります。これはMavenプロジェクトであるため、そのままインポートして実行するのは簡単です。