SlideShare une entreprise Scribd logo
1  sur  38
Télécharger pour lire hors ligne
2016年12月15日
1
ヤフー株式会社 データ&サイエンスソリューション統括本部
データプラットフォーム本部 開発1部 パイプライン
森谷 大輔
噛み砕いてKafka Streams
自己紹介
• 氏名
• 森谷 大輔 @kokumutyoukan
• 業務
• 次世代データパイプラインの開発
• Kafka, Storm,
Cassandra, Elasticsearch
• 好き
• 横浜ベイスターズ
• ハングリータイガー(の会会長)
2
今日のゴール
• おっ、調べてみるかなという気になってもらう
• Kafka Streamsを触った内容を噛み砕いて紹介
• 布教というわけではない
• 気になるところあれば遠慮なくツッコんでください
3
アジェンダ
• 概要
• Word Count
• Time, Window, Join
• つかってみた
• まとめ
4
アジェンダ
• 概要
• Word Count
• Time, Window, Join
• つかってみた
• まとめ
5
Kafka Streams is 何
• ストリーム処理のアプリケーションを書くためのライブラリ
• Apache Kafka に同梱されている
• 0.10.0 からアップデートの目玉として追加 (2016年5月)
6
群雄割拠勢
Confluentが開発・導入促進を
頑張っている
ストリーム処理アプリケーションをつくるには
• よく必要になる「難しい機能」
• パーティショニング・拡張性
• 故障してもうまいこと復旧する(ステート管理)
• 遅れてやってきたデータもうまいこと処理する(時間の扱い)
• 再処理
• ウィンドウ集計
• 方法①:素のKafka Java APIを使う
• 方法②:ストリーム処理フレームワークを使う
• 方法③:Kafka Streamsを使う
7
①:素の Kafka Java API を使う
• お手軽
• Java ライブラリなのでアプリケーションを書いて jar にかためて java コ
マンドで起動さえすれば良い
• デプロイがシンプル
• 覚えることはAPIの使い方だけ
• ただし「難しい機能」を自分で考えて実装しなければならない
8
Consumer<byte[], byte[]> consumer = new KafkaConsumer<>(props);
consumer.subscribe(topics);
②:ストリーム処理フレームワークを使う
• Stormなど群雄割拠勢
• 「難しい機能」を含めリッチな機能が使える
• ただしフレームワークの専用クラスタが必要
• フレームワークならではの構成、設定、書き方
• デプロイ複雑
• 覚えることが多い
9
③:Kafka Streamsを使う
• 「Kafka Streamsはフレームワークではなく、ライブラリ」
• 「難しい機能」も抽象化されている
• 大体のパターンのストリーム処理アプリケーションを書くには充分
• リアルタイム性
• Spark Streamingのようなマイクロバッチではなく、Stormのような逐次処理(at least once)
• レイテンシ要求が厳しい案件でもOK
10
・サーバを分散処理モードで動かすためにセッティングし、
・フレームワークのとりきめに従ったアプリケーションの実装をし、
・専用のデプロイツールでデプロイしてはじめて分散処理
・ライブラリをクラスパスに含めてjarにかためてjavaコマンドうてば動く
比較
11
方法
(難しい機能)
実装の簡単さ
学習
コスト
運用(デプロイ)
コスト
① 素のKafka
Java APIを使う ✕ ◯ ◯
② ストリーム処理
フレームワークを使う ◯ ✕ ✕
③ Kafka Streams
◯ △ ◯
※独断と偏見
※ストリーム処理フレームワークにしかない機能もある
アジェンダ
• 概要
• Word Count
• Time, Window, Join
• つかってみた
• まとめ
12
ことはじめ
13
• ビルド設定(maven)
• APIを選ぶ
• high-level DSL ←今回はこれ
• low-level API
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-streams</artifactId>
<version>0.10.0.1</version>
</dependency>
プログラム
14
@Test
public final void wordCount() {
KStreamBuilder builder = new KStreamBuilder();
KStream<String, String> queryStream
= builder.stream(stringSerde, stringSerde, “search-query-topic”); // 入力トピック名は複数指定可能
KStream<String, Long> wordCounts = queryStream
.flatMapValues(value -> Arrays.asList(value.split(“¥¥s+”))) // 空白区切り分割
.map((key, value) -> new KeyValue<>(value, value)) // key 毎カウント下準備
.countByKey(stringSerde, “Counts”) // KStream -> KTable
.toStream(); // KTable -> KStream
wordCounts.to(stringSerde, longSerde, “wordcount-output”); // sink トピックに結果を書く
KafkaStreams streams = new KafkaStreams(builder, props); // props は Kafka Streams の設定
streams.start(); // アプリケーション実行
}
入力・結果例
15
// 入力
producer.send(new ProducerRecord<>(“search-query-topic”, “ぬこ 飼い方”));
producer.send(new ProducerRecord<>(“search-query-topic”, “犬 飼い方”));
producer.send(new ProducerRecord<>(“search-query-topic”, “本当すこ ぬこ"));
consumer.subscribe(Arrays.asList("wordcount-output"));
while (true) {
ConsumerRecords<String, Long> records = consumer.poll(100);
for (ConsumerRecord<String, Long> record : records) {
System.out.println("record = " + record.key() + ", " + record.value());
}
}
// 出力
record = ぬこ, 1
record = 飼い方, 1
record = 犬, 1
record = 飼い方, 2
record = 本当すこ, 1
record = ぬこ, 2
アプリケーションの動作確認は
Kafka Unit Testを使うと便利
※Kafka 公式 FAQ 参照
KStream? KTable?
• KStream
• record streamを扱う場合はKStreamクラスを使う
• 自己完結のデータストリーム
• 例えばPVログ、サーバログ、ツイート
• KTable
• changelog streamを扱う場合はKTableクラスを使う
• 状態を持つ、keyで値が更新されるデータのストリーム
• 例えばこの単語が今までに何件出現したか、のようなデータ
• Stateとしてローカルに保持される
16
アジェンダ
• 概要
• Word Count
• Time, Window, Join
• つかってみた
• まとめ
17
Time
• ストリームであるイベントが流れてきた時、そのイベントのタイムスタンプとしてどんな情
報を使うべきか
• 例えばイベントがツイートだとして、一時間毎のツイート数を計算したいといった場合、な
んのタイムスタンプ毎に計算する?
1. ユーザがツイートした瞬間
2. ツイートをAPIからバックエンドサーバが受け取ってKafkaに投げた瞬間
3. Kafkaに入った瞬間
4. Kafka Streamsがそのイベントを処理した瞬間
18
Tweet!
Twitter
API
my BE
server
Kafka Streams
① ② ③ ④
Time
• ストリームであるイベントが流れてきた時、そのイベントのタイムスタンプとしてどんな情
報を使うべきか
• 例えばイベントがツイートだとして、一時間毎のツイート数を計算したいといった場合、な
んのタイムスタンプ毎に計算する?
1. ユーザがツイートした瞬間
2. ツイートをAPIからバックエンドサーバが受け取ってKafkaに投げた瞬間
3. Kafkaに入った瞬間
4. Kafka Streamsがそのイベントを処理した瞬間
• 多くは1だと思うが、アプリケーションの仕様によって異なる
• Kafka Streamsでは設定項目 timestamp.extractor でどれを選択するか簡単に決められ
る
19
Kafka Streams的分類
• event-time
• ログ内の独自タイムスタンプの場合
• 「ユーザがツイートした瞬間」
• Kafka messageに付与されているタイムスタンプを使う場合
• 「ツイートをAPIからバックエンドサーバが受け取ってKafkaに投げた瞬間」
• broker設定 log.message.timestamp.type=CreateTime (デフォルト)
• このタイムスタンプはKafka0.10からMessageに付与される
• 0.9以前のproducerから投げると -1
• ingestion-time
• 「Kafkaに入った瞬間」
• log.message.timestamp.type=LogAppendTime だった場合
• そのイベントがKafka Brokerに入ったときの時刻がmessageタイムスタンプに付与
• processing-time
• 「Kafka Streamsがそのイベントを処理した瞬間」
20
timestamp.extractor
21
Time分類 timestamp.extractor
event-time(独自) 自分で実装する
event-time(message) ConsumerRecordTimestampExtractor
ingestion-time ConsumerRecordTimestampExtractor
processing-time WallclockTimestampExtractor
import java.util.Properties;
import org.apache.kafka.streams.StreamsConfig;
Properties props = new Properties();
props.put(StreamsConfig.TIMESTAMP_EXTRACTOR_CLASS_CONFIG,
WallclockTimestampExtractor.class.getName());
設定例
独自クラス実装例
22
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.streams.processor.TimestampExtractor;
// TimestampExtractorインタフェースを実装する
public class MyEventTimeExtractor implements TimestampExtractor {
@Override public long extract(ConsumerRecord<Object, Object> record) {
// ログをパースしてtimestampを取り出す
Foo myPojo = (Foo) record.value();
if (myPojo != null) {
return myPojo.getTimestampInMillis();
} else {
// valueがnullだったらとりあえず現在時刻をいれておく
return System.currentTimeMillis();
}
}
}
http://docs.confluent.io/3.0.0/streams/developer-guide.html#timestamp-extractor (コメント以外引用)
Window
23
• Tumbling time window
• 5分毎のユーザ毎のPV数とか
• Hopping time window
• 1つのイベントが複数のウィンドウにまたがる
KStream<String, String> viewsByUser = ユーザIDがkeyのPVログStreamなど;
KTable<Windowed<String>, Long> userCounts =
viewsByUser.countByKey(TimeWindows.of(”WindowName", 5 * 60 * 1000L));
TimeWindows.of(”WindowName", 5 * 60 * 1000L).advanceBy(60 * 1000L);
Join
24
• ストリーム処理でよくやるストリームとテーブルのJoinができる
• KTableはローカルにあり、常に最新である
• メッセージ処理毎にネットワークを超えてKVSを叩く必要も、鮮度を諦めて定期的にRDBを
メモリにロードする必要もない
KStream<String, String> voteRegionStream = ...(“vote-topic”)
KTable<String, String> partyTable = ...("party-topic");
KStream<String, String> voteParty
= voteRegionStream.leftJoin(
partyTable, (region, party) -> region + ”," + party);
k: Hillary v: California k: candidate v: party
Hillary Democratic
Trump Republican
k: Hillary v: California, Democratic
アジェンダ
• 概要
• Word Count
• Time, Window, Join
• つかってみた
• まとめ
25
Kafka Streamsで開発してみた
• Kafkaクラスタから引いた全メッセージをグルーピング、ウィンドウ集計して指標をsinkに
書くシンプルなアプリ
• ローカルでテストは通った、本番デプロイいこう
• バグを踏む:Kafka-4160 (´・ω・`)
• Kafka Streamsのフォアグラウンドスレッドとバッググラウンド
ハートビートスレッドの間に単一のロックがある
• タスク生成中にハートビートをブロックするのでタスク生成が長い
とセッションタイムアウトを超える
• consumerがグループから追い出されて再度タスク生成を始める
• 永遠に繰り返してデッドロックみたくなる
• 入力パーティション数が少ないと問題にならないのだが
本番では1topicあたり最大60あったため本番で初めて発覚した
26
続き
• バグは Kafka 0.10.1.0 で解消されたよ!(今client, server共に 0.10.0.1)
• Kafka Streams をバージョンアップすれば解決しそう
• > Apps built with Kafka Streams 0.10.1 only work against Kafka clusters running
0.10.1+.
• 古いサーバに対しても互換性なんとかしたいとは書いてあった
• 0.10.0.1のKafkaにバグフィックスだけパッチ当ててアプリに入れるか・・・
• 対象コードが 0.10.1 で大きく変わってて厳しい
• やっぱりサーバあげよう ← イマココ
27
___________
/|:: ┌──────┐ ::|
/. |:: | Exception | ::| / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
|.... |:: | Use 0.10.1 !| ::| | マイナーバージョンアップなら…アレ?
|.... |:: | .| ::| \_ ______
|.... |:: └──────┘ ::| ∨
\_| ┌────┐ .| ∧∧
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ( _)
/ ̄ ̄ ̄ ̄ ̄旦 ̄(_, )
/ \
| ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄|、_)
 ̄| ̄| ̄ ̄ ̄ ̄ ̄ ̄|
思ったこと
• 向くユースケースなら向く
• Kafka Streamsのコンセプトがわかってきてからシステム設計した方がいいかも
• 既にカッチリ決まった要件にKafka Streamsを合わせようとするとハックするはめになるかも
• ライブラリならアプリケーション開発を楽にしてくれなくちゃいけない
• Kafkaの素のハイレベルAPIがそもそもかなりちょうどいい抽象化
• Kafka Streams APIの利点が活かせるかどうか
• インターナルトピックをかなり大量に作ることを想定している(アプリのバージョンアップご
とにトピックは増える)
• 小さめのサービス専用クラスタとかならいいが、マルチテナント向けのクラスタだとちょっと気持ち悪
いかも
• 現在は1 Kafkaクラスタしか指定できないが将来的には複数可能になるかも
28
アジェンダ
• 概要
• Word Count
• Time, Window, Join
• つかってみた
• まとめ
29
まとめ
• Kafka Streamsはストリーム処理のアプリケーションを実装するためのライブ
ラリ
• シンプルながらストリーム処理でよく必要になる、自分で実装するには難し
い機能を実現する
• 時間軸に何を使うか開発者が選択できる
• Kafka Streamsが便利に使えるようにシステム設計をすると吉
30
Appendix
31
Kafka Streamsはどこで動くの?
32
• consumerアプリケーション
• 普通はKafkaクラスタの(物理的に)近くのアプリケーション専用サーバ上でJavaプロセスとして動
かすと思う
• ライブラリなので何でもできるが、Kafkaとしか接続しないように全体設計すると楽そう
Kafkaクラスタ
source topic
internal topic
sink topic
Kafka
Streams
Kafka
Connect 等
Kafka
Connect 等
Configuration
33
import java.util.Properties;
import org.apache.kafka.streams.StreamsConfig;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.clients.producer.ConsumerConfig;
Properties settings = new Properties();
settings.put(StreamsConfig.APPLICATION_ID_CONFIG, “my-app”); // StreamConfigのこの3つは必須
settings.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, ”localhost:9092");
settings.put(StreamsConfig.ZOOKEEPER_CONNECT_CONFIG, ”localhost:2181");
settings.put(ProducerConfig...., “”); // 必須でない
settings.put(ConsumerConfig...., “”); // 必須でない
application.id アプリケーション認識名. consumer group名やinternal topic名等に利用される.
bootstrap.servers 接続するKafkaクラスタのhost/portペアのリスト.
zookeeper.connect 接続するZooKeeperのコネクション文字列(host:port/chroot).
num.stream.threads ストリーム処理のために使うスレッド数.
replication.factor internal topicを作るときのレプリケーションファクタ
state.dir State Storeのディレクトリパス
timestamp.extractor 後述
フォールトトレラント
• 故障時にStateを復旧させるため、Kafkaクラスタにchangelog topicという内部topicが作ら
れる
34
Node
Task
source part-1
changelog part-1
Node
Task
source part-0
changelog part-0
フォールトトレラント
• 故障時にStateを復旧させるため、Kafkaクラスタにchangelog topicという内部topicが作ら
れる
35
Node
Task
source part-1
changelog part-1
Node
Tasksource part-0
changelog part-0
Task
changelog topic(おまけ)
• topicはKafka Streamsアプリケーションの実行時に自動で作成される
• 手動でtopicを作るときと同じような感じで、Kafka設定
auto.create.topics.enable=falseでも作成される
• topic設定はcompact
• 同じkeyで頻繁にvalueが変わるはずだから
• タスク数分パーティションが作られる
36
プログラム(full)
37
@Test
public final void wordCount() {
final Serde<String> stringSerde = Serdes.String(); // Serde is Serializer/Deserializerの略、Kafka共通のクラス
final Serde<Long> longSerde = Serdes.Long(); // 基本的なビルトインをSerdesから呼べる、もちろん自作可能
KStreamBuilder builder = new KStreamBuilder();
// 入力名からKStreamを作る. 1: key Serde, 2: value Serde, 3: 入力トピック名(複数指定可能)
KStream<String, String> queryStream = builder.stream(stringSerde, stringSerde, “search-query-topic”);
KStream<String, Long> wordCounts = queryStream
// valueに対して空白区切りで文字列を分割して次に送る処理
.flatMapValues(value -> Arrays.asList(value.split(“¥¥s+”)))
// key毎カウントしたいからkeyにvalueを入れる
.map((key, value) -> new KeyValue<>(value, value))
.countByKey(stringSerde, “Counts”) // KStream -> KTable、第二引数はKTable名
.toStream(); // KTable -> KStream
wordCounts.to(stringSerde, longSerde, “wordcount-output”); // sinkトピックに結果を書く
KafkaStreams streams = new KafkaStreams(builder, props); // propsはKafka StreamsやClientの設定Properties
streams.start(); // アプリケーション実行
}
比較(full)
38
方法
(難しい機能)
実装の簡単さ
学習
コスト
運用(デプロイ)
コスト
実績
ドキュメント
充実度
① 素のKafka
Java APIを使う ✕ ◯ ◯ ◯ ◯
② ストリーム処理
フレームワークを使う ◯ ✕ ✕ △
(差異が大きい)
△?
③ Kafka Streams
◯ △ ◯ ✕ △
※独断と偏見

Contenu connexe

Tendances

Pacemaker+PostgreSQLレプリケーションで共有ディスクレス高信頼クラスタの構築@OSC 2013 Tokyo/Spring
Pacemaker+PostgreSQLレプリケーションで共有ディスクレス高信頼クラスタの構築@OSC 2013 Tokyo/SpringPacemaker+PostgreSQLレプリケーションで共有ディスクレス高信頼クラスタの構築@OSC 2013 Tokyo/Spring
Pacemaker+PostgreSQLレプリケーションで共有ディスクレス高信頼クラスタの構築@OSC 2013 Tokyo/Spring
Takatoshi Matsuo
 

Tendances (20)

Kafkaを活用するためのストリーム処理の基本
Kafkaを活用するためのストリーム処理の基本Kafkaを活用するためのストリーム処理の基本
Kafkaを活用するためのストリーム処理の基本
 
分散トレーシング技術について(Open tracingやjaeger)
分散トレーシング技術について(Open tracingやjaeger)分散トレーシング技術について(Open tracingやjaeger)
分散トレーシング技術について(Open tracingやjaeger)
 
Apache Spark on Kubernetes入門(Open Source Conference 2021 Online Hiroshima 発表資料)
Apache Spark on Kubernetes入門(Open Source Conference 2021 Online Hiroshima 発表資料)Apache Spark on Kubernetes入門(Open Source Conference 2021 Online Hiroshima 発表資料)
Apache Spark on Kubernetes入門(Open Source Conference 2021 Online Hiroshima 発表資料)
 
Apache Kafka 0.11 の Exactly Once Semantics
Apache Kafka 0.11 の Exactly Once SemanticsApache Kafka 0.11 の Exactly Once Semantics
Apache Kafka 0.11 の Exactly Once Semantics
 
[GKE & Spanner 勉強会] Cloud Spanner の技術概要
[GKE & Spanner 勉強会] Cloud Spanner の技術概要[GKE & Spanner 勉強会] Cloud Spanner の技術概要
[GKE & Spanner 勉強会] Cloud Spanner の技術概要
 
Linux-HA Japanプロジェクトのこれまでとこれから
Linux-HA JapanプロジェクトのこれまでとこれからLinux-HA Japanプロジェクトのこれまでとこれから
Linux-HA Japanプロジェクトのこれまでとこれから
 
ヤフー発のメッセージキュー「Pulsar」のご紹介
ヤフー発のメッセージキュー「Pulsar」のご紹介ヤフー発のメッセージキュー「Pulsar」のご紹介
ヤフー発のメッセージキュー「Pulsar」のご紹介
 
Hadoop -NameNode HAの仕組み-
Hadoop -NameNode HAの仕組み-Hadoop -NameNode HAの仕組み-
Hadoop -NameNode HAの仕組み-
 
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
 
Prestoで実現するインタラクティブクエリ - dbtech showcase 2014 Tokyo
Prestoで実現するインタラクティブクエリ - dbtech showcase 2014 TokyoPrestoで実現するインタラクティブクエリ - dbtech showcase 2014 Tokyo
Prestoで実現するインタラクティブクエリ - dbtech showcase 2014 Tokyo
 
単なるキャッシュじゃないよ!?infinispanの紹介
単なるキャッシュじゃないよ!?infinispanの紹介単なるキャッシュじゃないよ!?infinispanの紹介
単なるキャッシュじゃないよ!?infinispanの紹介
 
Pacemaker+PostgreSQLレプリケーションで共有ディスクレス高信頼クラスタの構築@OSC 2013 Tokyo/Spring
Pacemaker+PostgreSQLレプリケーションで共有ディスクレス高信頼クラスタの構築@OSC 2013 Tokyo/SpringPacemaker+PostgreSQLレプリケーションで共有ディスクレス高信頼クラスタの構築@OSC 2013 Tokyo/Spring
Pacemaker+PostgreSQLレプリケーションで共有ディスクレス高信頼クラスタの構築@OSC 2013 Tokyo/Spring
 
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Dockerからcontainerdへの移行
Dockerからcontainerdへの移行
 
SQL大量発行処理をいかにして高速化するか
SQL大量発行処理をいかにして高速化するかSQL大量発行処理をいかにして高速化するか
SQL大量発行処理をいかにして高速化するか
 
分析指向データレイク実現の次の一手 ~Delta Lake、なにそれおいしいの?~(NTTデータ テクノロジーカンファレンス 2020 発表資料)
分析指向データレイク実現の次の一手 ~Delta Lake、なにそれおいしいの?~(NTTデータ テクノロジーカンファレンス 2020 発表資料)分析指向データレイク実現の次の一手 ~Delta Lake、なにそれおいしいの?~(NTTデータ テクノロジーカンファレンス 2020 発表資料)
分析指向データレイク実現の次の一手 ~Delta Lake、なにそれおいしいの?~(NTTデータ テクノロジーカンファレンス 2020 発表資料)
 
Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)
Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)
Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)
 
ストリーム処理プラットフォームにおけるKafka導入事例 #kafkajp
ストリーム処理プラットフォームにおけるKafka導入事例 #kafkajpストリーム処理プラットフォームにおけるKafka導入事例 #kafkajp
ストリーム処理プラットフォームにおけるKafka導入事例 #kafkajp
 
PostgreSQL: XID周回問題に潜む別の問題
PostgreSQL: XID周回問題に潜む別の問題PostgreSQL: XID周回問題に潜む別の問題
PostgreSQL: XID周回問題に潜む別の問題
 
Apache Sparkに手を出してヤケドしないための基本 ~「Apache Spark入門より」~ (デブサミ 2016 講演資料)
Apache Sparkに手を出してヤケドしないための基本 ~「Apache Spark入門より」~ (デブサミ 2016 講演資料)Apache Sparkに手を出してヤケドしないための基本 ~「Apache Spark入門より」~ (デブサミ 2016 講演資料)
Apache Sparkに手を出してヤケドしないための基本 ~「Apache Spark入門より」~ (デブサミ 2016 講演資料)
 
IoT時代におけるストリームデータ処理と急成長の Apache Flink
IoT時代におけるストリームデータ処理と急成長の Apache FlinkIoT時代におけるストリームデータ処理と急成長の Apache Flink
IoT時代におけるストリームデータ処理と急成長の Apache Flink
 

En vedette

Yahoo! JAPAN MeetUp #8 (インフラ技術カンファレンス)セッション②
Yahoo! JAPAN MeetUp #8 (インフラ技術カンファレンス)セッション②Yahoo! JAPAN MeetUp #8 (インフラ技術カンファレンス)セッション②
Yahoo! JAPAN MeetUp #8 (インフラ技術カンファレンス)セッション②
Yahoo!デベロッパーネットワーク
 
Yahoo! JAPANが持つデータ分析ソリューションの紹介 #yjdsnight
Yahoo! JAPANが持つデータ分析ソリューションの紹介 #yjdsnightYahoo! JAPANが持つデータ分析ソリューションの紹介 #yjdsnight
Yahoo! JAPANが持つデータ分析ソリューションの紹介 #yjdsnight
Yahoo!デベロッパーネットワーク
 
Kafkaによるリアルタイム処理
Kafkaによるリアルタイム処理Kafkaによるリアルタイム処理
Kafkaによるリアルタイム処理
Naoki Yanai
 
Yahoo! JAPANのサービス開発を10倍早くした社内PaaS構築の今とこれから
Yahoo! JAPANのサービス開発を10倍早くした社内PaaS構築の今とこれからYahoo! JAPANのサービス開発を10倍早くした社内PaaS構築の今とこれから
Yahoo! JAPANのサービス開発を10倍早くした社内PaaS構築の今とこれから
Yahoo!デベロッパーネットワーク
 
Presto - Hadoop Conference Japan 2014
Presto - Hadoop Conference Japan 2014Presto - Hadoop Conference Japan 2014
Presto - Hadoop Conference Japan 2014
Sadayuki Furuhashi
 

En vedette (20)

Kafka通常オペレーションで遭遇する問題集 #kafkajp
Kafka通常オペレーションで遭遇する問題集 #kafkajpKafka通常オペレーションで遭遇する問題集 #kafkajp
Kafka通常オペレーションで遭遇する問題集 #kafkajp
 
Kafkaを使った マイクロサービス基盤 part2 +運用して起きたトラブル集
Kafkaを使った マイクロサービス基盤 part2 +運用して起きたトラブル集Kafkaを使った マイクロサービス基盤 part2 +運用して起きたトラブル集
Kafkaを使った マイクロサービス基盤 part2 +運用して起きたトラブル集
 
Queryable State for Kafka Streamsを使ってみた
Queryable State for Kafka Streamsを使ってみたQueryable State for Kafka Streamsを使ってみた
Queryable State for Kafka Streamsを使ってみた
 
Processing Kafka Topics for Monitoring with Prometheus
Processing Kafka Topics for Monitoring with PrometheusProcessing Kafka Topics for Monitoring with Prometheus
Processing Kafka Topics for Monitoring with Prometheus
 
Kafka 0.10.0 アップデート、プロダクション100ノードでやってみた #yjdsnight
Kafka 0.10.0 アップデート、プロダクション100ノードでやってみた #yjdsnightKafka 0.10.0 アップデート、プロダクション100ノードでやってみた #yjdsnight
Kafka 0.10.0 アップデート、プロダクション100ノードでやってみた #yjdsnight
 
KafkaとAWS Kinesisの比較
KafkaとAWS Kinesisの比較KafkaとAWS Kinesisの比較
KafkaとAWS Kinesisの比較
 
Awsでつくるapache kafkaといろんな悩み
Awsでつくるapache kafkaといろんな悩みAwsでつくるapache kafkaといろんな悩み
Awsでつくるapache kafkaといろんな悩み
 
Elasticsearch 5.2とJava Clientで戯れる #elasticsearchjp
Elasticsearch 5.2とJava Clientで戯れる #elasticsearchjpElasticsearch 5.2とJava Clientで戯れる #elasticsearchjp
Elasticsearch 5.2とJava Clientで戯れる #elasticsearchjp
 
Yahoo! JAPAN MeetUp #8 (インフラ技術カンファレンス)セッション②
Yahoo! JAPAN MeetUp #8 (インフラ技術カンファレンス)セッション②Yahoo! JAPAN MeetUp #8 (インフラ技術カンファレンス)セッション②
Yahoo! JAPAN MeetUp #8 (インフラ技術カンファレンス)セッション②
 
Yahoo! JAPANが持つデータ分析ソリューションの紹介 #yjdsnight
Yahoo! JAPANが持つデータ分析ソリューションの紹介 #yjdsnightYahoo! JAPANが持つデータ分析ソリューションの紹介 #yjdsnight
Yahoo! JAPANが持つデータ分析ソリューションの紹介 #yjdsnight
 
Kafkaによるリアルタイム処理
Kafkaによるリアルタイム処理Kafkaによるリアルタイム処理
Kafkaによるリアルタイム処理
 
第2回 NIPS+読み会・関西 発表資料 山本
第2回 NIPS+読み会・関西 発表資料 山本第2回 NIPS+読み会・関西 発表資料 山本
第2回 NIPS+読み会・関西 発表資料 山本
 
Prestoクエリログの保存/分析機能の構築 #yjdsnight
Prestoクエリログの保存/分析機能の構築 #yjdsnightPrestoクエリログの保存/分析機能の構築 #yjdsnight
Prestoクエリログの保存/分析機能の構築 #yjdsnight
 
Presto in Yahoo! JAPAN #yjdsnight
Presto in Yahoo! JAPAN #yjdsnightPresto in Yahoo! JAPAN #yjdsnight
Presto in Yahoo! JAPAN #yjdsnight
 
Yahoo! JAPANのサービス開発を10倍早くした社内PaaS構築の今とこれから
Yahoo! JAPANのサービス開発を10倍早くした社内PaaS構築の今とこれからYahoo! JAPANのサービス開発を10倍早くした社内PaaS構築の今とこれから
Yahoo! JAPANのサービス開発を10倍早くした社内PaaS構築の今とこれから
 
Storm の新機能について @HSCR #hadoopreading
Storm の新機能について @HSCR #hadoopreadingStorm の新機能について @HSCR #hadoopreading
Storm の新機能について @HSCR #hadoopreading
 
Presto - Hadoop Conference Japan 2014
Presto - Hadoop Conference Japan 2014Presto - Hadoop Conference Japan 2014
Presto - Hadoop Conference Japan 2014
 
グロースハック なぜ我々は無意味な施策を打ってしまうのか
グロースハック なぜ我々は無意味な施策を打ってしまうのかグロースハック なぜ我々は無意味な施策を打ってしまうのか
グロースハック なぜ我々は無意味な施策を打ってしまうのか
 
市場で勝ち続けるための品質とテストの技術①
市場で勝ち続けるための品質とテストの技術①市場で勝ち続けるための品質とテストの技術①
市場で勝ち続けるための品質とテストの技術①
 
市場で勝ち続けるための品質とテストの技術②
市場で勝ち続けるための品質とテストの技術②市場で勝ち続けるための品質とテストの技術②
市場で勝ち続けるための品質とテストの技術②
 

Similaire à 噛み砕いてKafka Streams #kafkajp

Webサーバの性能測定
Webサーバの性能測定Webサーバの性能測定
Webサーバの性能測定
Ryo Maruyama
 
fluentd を利用した大規模ウェブサービスのロギング
fluentd を利用した大規模ウェブサービスのロギングfluentd を利用した大規模ウェブサービスのロギング
fluentd を利用した大規模ウェブサービスのロギング
Yuichi Tateno
 
ソーシャルゲームにレコメンドエンジンを導入した話
ソーシャルゲームにレコメンドエンジンを導入した話ソーシャルゲームにレコメンドエンジンを導入した話
ソーシャルゲームにレコメンドエンジンを導入した話
Tokoroten Nakayama
 

Similaire à 噛み砕いてKafka Streams #kafkajp (20)

Hadoop Summit 2016 San Jose ストリーム処理関連の報告 #streamctjp
Hadoop Summit 2016 San Jose ストリーム処理関連の報告 #streamctjpHadoop Summit 2016 San Jose ストリーム処理関連の報告 #streamctjp
Hadoop Summit 2016 San Jose ストリーム処理関連の報告 #streamctjp
 
Spark Summit 2014 の報告と最近の取り組みについて
Spark Summit 2014 の報告と最近の取り組みについてSpark Summit 2014 の報告と最近の取り組みについて
Spark Summit 2014 の報告と最近の取り組みについて
 
Reactive Kafka with Akka Streams
Reactive Kafka with Akka StreamsReactive Kafka with Akka Streams
Reactive Kafka with Akka Streams
 
Spark Structured StreamingでKafkaクラスタのデータをお手軽活用
Spark Structured StreamingでKafkaクラスタのデータをお手軽活用Spark Structured StreamingでKafkaクラスタのデータをお手軽活用
Spark Structured StreamingでKafkaクラスタのデータをお手軽活用
 
Akka-Streams in Production
Akka-Streams in ProductionAkka-Streams in Production
Akka-Streams in Production
 
さくらのDockerコンテナホスティング-Arukasの解説とインフラを支える技術(July Tech Festa 2016 『IoTxAIxインフラ時代...
さくらのDockerコンテナホスティング-Arukasの解説とインフラを支える技術(July Tech Festa 2016 『IoTxAIxインフラ時代...さくらのDockerコンテナホスティング-Arukasの解説とインフラを支える技術(July Tech Festa 2016 『IoTxAIxインフラ時代...
さくらのDockerコンテナホスティング-Arukasの解説とインフラを支える技術(July Tech Festa 2016 『IoTxAIxインフラ時代...
 
Cassandra Summit 2016 注目セッション報告
Cassandra Summit 2016 注目セッション報告Cassandra Summit 2016 注目セッション報告
Cassandra Summit 2016 注目セッション報告
 
Webサーバの性能測定
Webサーバの性能測定Webサーバの性能測定
Webサーバの性能測定
 
Java Clientで入門する Apache Kafka #jjug_ccc #ccc_e2
Java Clientで入門する Apache Kafka #jjug_ccc #ccc_e2Java Clientで入門する Apache Kafka #jjug_ccc #ccc_e2
Java Clientで入門する Apache Kafka #jjug_ccc #ccc_e2
 
fluentd を利用した大規模ウェブサービスのロギング
fluentd を利用した大規模ウェブサービスのロギングfluentd を利用した大規模ウェブサービスのロギング
fluentd を利用した大規模ウェブサービスのロギング
 
Spark Structured Streaming with Kafka
Spark Structured Streaming with KafkaSpark Structured Streaming with Kafka
Spark Structured Streaming with Kafka
 
Fast Data を扱うためのデザインパターン
Fast Data を扱うためのデザインパターンFast Data を扱うためのデザインパターン
Fast Data を扱うためのデザインパターン
 
Kafka Summit NYCに見るストリーミングデータETLの話 #streamdatajp
Kafka Summit NYCに見るストリーミングデータETLの話 #streamdatajpKafka Summit NYCに見るストリーミングデータETLの話 #streamdatajp
Kafka Summit NYCに見るストリーミングデータETLの話 #streamdatajp
 
Flowtype Introduction
Flowtype IntroductionFlowtype Introduction
Flowtype Introduction
 
名古屋セキュリティ勉強会LT~学内CTFの話~
名古屋セキュリティ勉強会LT~学内CTFの話~名古屋セキュリティ勉強会LT~学内CTFの話~
名古屋セキュリティ勉強会LT~学内CTFの話~
 
利用者主体で行う分析のための分析基盤
利用者主体で行う分析のための分析基盤利用者主体で行う分析のための分析基盤
利用者主体で行う分析のための分析基盤
 
Search on AWS - IVS CTO Night and Day 2016 Spring
Search on AWS - IVS CTO Night and Day 2016 SpringSearch on AWS - IVS CTO Night and Day 2016 Spring
Search on AWS - IVS CTO Night and Day 2016 Spring
 
ソーシャルゲームにレコメンドエンジンを導入した話
ソーシャルゲームにレコメンドエンジンを導入した話ソーシャルゲームにレコメンドエンジンを導入した話
ソーシャルゲームにレコメンドエンジンを導入した話
 
Lars George HBase Seminar with O'REILLY Oct.12 2012
Lars George HBase Seminar with O'REILLY Oct.12 2012Lars George HBase Seminar with O'REILLY Oct.12 2012
Lars George HBase Seminar with O'REILLY Oct.12 2012
 
Zabbix study5lt
Zabbix study5ltZabbix study5lt
Zabbix study5lt
 

Plus de Yahoo!デベロッパーネットワーク

Plus de Yahoo!デベロッパーネットワーク (20)

ゼロから始める転移学習
ゼロから始める転移学習ゼロから始める転移学習
ゼロから始める転移学習
 
継続的なモデルモニタリングを実現するKubernetes Operator
継続的なモデルモニタリングを実現するKubernetes Operator継続的なモデルモニタリングを実現するKubernetes Operator
継続的なモデルモニタリングを実現するKubernetes Operator
 
ヤフーでは開発迅速性と品質のバランスをどう取ってるか
ヤフーでは開発迅速性と品質のバランスをどう取ってるかヤフーでは開発迅速性と品質のバランスをどう取ってるか
ヤフーでは開発迅速性と品質のバランスをどう取ってるか
 
オンプレML基盤on Kubernetes パネルディスカッション
オンプレML基盤on Kubernetes パネルディスカッションオンプレML基盤on Kubernetes パネルディスカッション
オンプレML基盤on Kubernetes パネルディスカッション
 
LakeTahoe
LakeTahoeLakeTahoe
LakeTahoe
 
オンプレML基盤on Kubernetes 〜Yahoo! JAPAN AIPF〜
オンプレML基盤on Kubernetes 〜Yahoo! JAPAN AIPF〜オンプレML基盤on Kubernetes 〜Yahoo! JAPAN AIPF〜
オンプレML基盤on Kubernetes 〜Yahoo! JAPAN AIPF〜
 
Persistent-memory-native Database High-availability Feature
Persistent-memory-native Database High-availability FeaturePersistent-memory-native Database High-availability Feature
Persistent-memory-native Database High-availability Feature
 
データの価値を最大化させるためのデザイン~データビジュアライゼーションの方法~ #devsumi 17-E-2
データの価値を最大化させるためのデザイン~データビジュアライゼーションの方法~ #devsumi 17-E-2データの価値を最大化させるためのデザイン~データビジュアライゼーションの方法~ #devsumi 17-E-2
データの価値を最大化させるためのデザイン~データビジュアライゼーションの方法~ #devsumi 17-E-2
 
eコマースと実店舗の相互利益を目指したデザイン #yjtc
eコマースと実店舗の相互利益を目指したデザイン #yjtceコマースと実店舗の相互利益を目指したデザイン #yjtc
eコマースと実店舗の相互利益を目指したデザイン #yjtc
 
ヤフーを支えるセキュリティ ~サイバー攻撃を防ぐエンジニアの仕事とは~ #yjtc
ヤフーを支えるセキュリティ ~サイバー攻撃を防ぐエンジニアの仕事とは~ #yjtcヤフーを支えるセキュリティ ~サイバー攻撃を防ぐエンジニアの仕事とは~ #yjtc
ヤフーを支えるセキュリティ ~サイバー攻撃を防ぐエンジニアの仕事とは~ #yjtc
 
Yahoo! JAPANのIaaSを支えるKubernetesクラスタ、アップデート自動化への挑戦 #yjtc
Yahoo! JAPANのIaaSを支えるKubernetesクラスタ、アップデート自動化への挑戦 #yjtcYahoo! JAPANのIaaSを支えるKubernetesクラスタ、アップデート自動化への挑戦 #yjtc
Yahoo! JAPANのIaaSを支えるKubernetesクラスタ、アップデート自動化への挑戦 #yjtc
 
ビッグデータから人々のムードを捉える #yjtc
ビッグデータから人々のムードを捉える #yjtcビッグデータから人々のムードを捉える #yjtc
ビッグデータから人々のムードを捉える #yjtc
 
サイエンス領域におけるMLOpsの取り組み #yjtc
サイエンス領域におけるMLOpsの取り組み #yjtcサイエンス領域におけるMLOpsの取り組み #yjtc
サイエンス領域におけるMLOpsの取り組み #yjtc
 
ヤフーのAIプラットフォーム紹介 ~AIテックカンパニーを支えるデータ基盤~ #yjtc
ヤフーのAIプラットフォーム紹介 ~AIテックカンパニーを支えるデータ基盤~ #yjtcヤフーのAIプラットフォーム紹介 ~AIテックカンパニーを支えるデータ基盤~ #yjtc
ヤフーのAIプラットフォーム紹介 ~AIテックカンパニーを支えるデータ基盤~ #yjtc
 
Yahoo! JAPAN Tech Conference 2022 Day2 Keynote #yjtc
Yahoo! JAPAN Tech Conference 2022 Day2 Keynote #yjtcYahoo! JAPAN Tech Conference 2022 Day2 Keynote #yjtc
Yahoo! JAPAN Tech Conference 2022 Day2 Keynote #yjtc
 
新技術を使った次世代の商品の見せ方 ~ヤフオク!のマルチビュー機能~ #yjtc
新技術を使った次世代の商品の見せ方 ~ヤフオク!のマルチビュー機能~ #yjtc新技術を使った次世代の商品の見せ方 ~ヤフオク!のマルチビュー機能~ #yjtc
新技術を使った次世代の商品の見せ方 ~ヤフオク!のマルチビュー機能~ #yjtc
 
PC版Yahoo!メールリニューアル ~サービスのUI/UX統合と改善プロセス~ #yjtc
PC版Yahoo!メールリニューアル ~サービスのUI/UX統合と改善プロセス~ #yjtcPC版Yahoo!メールリニューアル ~サービスのUI/UX統合と改善プロセス~ #yjtc
PC版Yahoo!メールリニューアル ~サービスのUI/UX統合と改善プロセス~ #yjtc
 
モブデザインによる多職種チームのコミュニケーション改善 #yjtc
モブデザインによる多職種チームのコミュニケーション改善 #yjtcモブデザインによる多職種チームのコミュニケーション改善 #yjtc
モブデザインによる多職種チームのコミュニケーション改善 #yjtc
 
「新しいおうち探し」のためのAIアシスト検索 #yjtc
「新しいおうち探し」のためのAIアシスト検索 #yjtc「新しいおうち探し」のためのAIアシスト検索 #yjtc
「新しいおうち探し」のためのAIアシスト検索 #yjtc
 
ユーザーの地域を考慮した検索入力補助機能の改善の試み #yjtc
ユーザーの地域を考慮した検索入力補助機能の改善の試み #yjtcユーザーの地域を考慮した検索入力補助機能の改善の試み #yjtc
ユーザーの地域を考慮した検索入力補助機能の改善の試み #yjtc
 

噛み砕いてKafka Streams #kafkajp

  • 2. 自己紹介 • 氏名 • 森谷 大輔 @kokumutyoukan • 業務 • 次世代データパイプラインの開発 • Kafka, Storm, Cassandra, Elasticsearch • 好き • 横浜ベイスターズ • ハングリータイガー(の会会長) 2
  • 3. 今日のゴール • おっ、調べてみるかなという気になってもらう • Kafka Streamsを触った内容を噛み砕いて紹介 • 布教というわけではない • 気になるところあれば遠慮なくツッコんでください 3
  • 4. アジェンダ • 概要 • Word Count • Time, Window, Join • つかってみた • まとめ 4
  • 5. アジェンダ • 概要 • Word Count • Time, Window, Join • つかってみた • まとめ 5
  • 6. Kafka Streams is 何 • ストリーム処理のアプリケーションを書くためのライブラリ • Apache Kafka に同梱されている • 0.10.0 からアップデートの目玉として追加 (2016年5月) 6 群雄割拠勢 Confluentが開発・導入促進を 頑張っている
  • 7. ストリーム処理アプリケーションをつくるには • よく必要になる「難しい機能」 • パーティショニング・拡張性 • 故障してもうまいこと復旧する(ステート管理) • 遅れてやってきたデータもうまいこと処理する(時間の扱い) • 再処理 • ウィンドウ集計 • 方法①:素のKafka Java APIを使う • 方法②:ストリーム処理フレームワークを使う • 方法③:Kafka Streamsを使う 7
  • 8. ①:素の Kafka Java API を使う • お手軽 • Java ライブラリなのでアプリケーションを書いて jar にかためて java コ マンドで起動さえすれば良い • デプロイがシンプル • 覚えることはAPIの使い方だけ • ただし「難しい機能」を自分で考えて実装しなければならない 8 Consumer<byte[], byte[]> consumer = new KafkaConsumer<>(props); consumer.subscribe(topics);
  • 9. ②:ストリーム処理フレームワークを使う • Stormなど群雄割拠勢 • 「難しい機能」を含めリッチな機能が使える • ただしフレームワークの専用クラスタが必要 • フレームワークならではの構成、設定、書き方 • デプロイ複雑 • 覚えることが多い 9
  • 10. ③:Kafka Streamsを使う • 「Kafka Streamsはフレームワークではなく、ライブラリ」 • 「難しい機能」も抽象化されている • 大体のパターンのストリーム処理アプリケーションを書くには充分 • リアルタイム性 • Spark Streamingのようなマイクロバッチではなく、Stormのような逐次処理(at least once) • レイテンシ要求が厳しい案件でもOK 10 ・サーバを分散処理モードで動かすためにセッティングし、 ・フレームワークのとりきめに従ったアプリケーションの実装をし、 ・専用のデプロイツールでデプロイしてはじめて分散処理 ・ライブラリをクラスパスに含めてjarにかためてjavaコマンドうてば動く
  • 11. 比較 11 方法 (難しい機能) 実装の簡単さ 学習 コスト 運用(デプロイ) コスト ① 素のKafka Java APIを使う ✕ ◯ ◯ ② ストリーム処理 フレームワークを使う ◯ ✕ ✕ ③ Kafka Streams ◯ △ ◯ ※独断と偏見 ※ストリーム処理フレームワークにしかない機能もある
  • 12. アジェンダ • 概要 • Word Count • Time, Window, Join • つかってみた • まとめ 12
  • 13. ことはじめ 13 • ビルド設定(maven) • APIを選ぶ • high-level DSL ←今回はこれ • low-level API <dependency> <groupId>org.apache.kafka</groupId> <artifactId>kafka-streams</artifactId> <version>0.10.0.1</version> </dependency>
  • 14. プログラム 14 @Test public final void wordCount() { KStreamBuilder builder = new KStreamBuilder(); KStream<String, String> queryStream = builder.stream(stringSerde, stringSerde, “search-query-topic”); // 入力トピック名は複数指定可能 KStream<String, Long> wordCounts = queryStream .flatMapValues(value -> Arrays.asList(value.split(“¥¥s+”))) // 空白区切り分割 .map((key, value) -> new KeyValue<>(value, value)) // key 毎カウント下準備 .countByKey(stringSerde, “Counts”) // KStream -> KTable .toStream(); // KTable -> KStream wordCounts.to(stringSerde, longSerde, “wordcount-output”); // sink トピックに結果を書く KafkaStreams streams = new KafkaStreams(builder, props); // props は Kafka Streams の設定 streams.start(); // アプリケーション実行 }
  • 15. 入力・結果例 15 // 入力 producer.send(new ProducerRecord<>(“search-query-topic”, “ぬこ 飼い方”)); producer.send(new ProducerRecord<>(“search-query-topic”, “犬 飼い方”)); producer.send(new ProducerRecord<>(“search-query-topic”, “本当すこ ぬこ")); consumer.subscribe(Arrays.asList("wordcount-output")); while (true) { ConsumerRecords<String, Long> records = consumer.poll(100); for (ConsumerRecord<String, Long> record : records) { System.out.println("record = " + record.key() + ", " + record.value()); } } // 出力 record = ぬこ, 1 record = 飼い方, 1 record = 犬, 1 record = 飼い方, 2 record = 本当すこ, 1 record = ぬこ, 2 アプリケーションの動作確認は Kafka Unit Testを使うと便利 ※Kafka 公式 FAQ 参照
  • 16. KStream? KTable? • KStream • record streamを扱う場合はKStreamクラスを使う • 自己完結のデータストリーム • 例えばPVログ、サーバログ、ツイート • KTable • changelog streamを扱う場合はKTableクラスを使う • 状態を持つ、keyで値が更新されるデータのストリーム • 例えばこの単語が今までに何件出現したか、のようなデータ • Stateとしてローカルに保持される 16
  • 17. アジェンダ • 概要 • Word Count • Time, Window, Join • つかってみた • まとめ 17
  • 18. Time • ストリームであるイベントが流れてきた時、そのイベントのタイムスタンプとしてどんな情 報を使うべきか • 例えばイベントがツイートだとして、一時間毎のツイート数を計算したいといった場合、な んのタイムスタンプ毎に計算する? 1. ユーザがツイートした瞬間 2. ツイートをAPIからバックエンドサーバが受け取ってKafkaに投げた瞬間 3. Kafkaに入った瞬間 4. Kafka Streamsがそのイベントを処理した瞬間 18 Tweet! Twitter API my BE server Kafka Streams ① ② ③ ④
  • 19. Time • ストリームであるイベントが流れてきた時、そのイベントのタイムスタンプとしてどんな情 報を使うべきか • 例えばイベントがツイートだとして、一時間毎のツイート数を計算したいといった場合、な んのタイムスタンプ毎に計算する? 1. ユーザがツイートした瞬間 2. ツイートをAPIからバックエンドサーバが受け取ってKafkaに投げた瞬間 3. Kafkaに入った瞬間 4. Kafka Streamsがそのイベントを処理した瞬間 • 多くは1だと思うが、アプリケーションの仕様によって異なる • Kafka Streamsでは設定項目 timestamp.extractor でどれを選択するか簡単に決められ る 19
  • 20. Kafka Streams的分類 • event-time • ログ内の独自タイムスタンプの場合 • 「ユーザがツイートした瞬間」 • Kafka messageに付与されているタイムスタンプを使う場合 • 「ツイートをAPIからバックエンドサーバが受け取ってKafkaに投げた瞬間」 • broker設定 log.message.timestamp.type=CreateTime (デフォルト) • このタイムスタンプはKafka0.10からMessageに付与される • 0.9以前のproducerから投げると -1 • ingestion-time • 「Kafkaに入った瞬間」 • log.message.timestamp.type=LogAppendTime だった場合 • そのイベントがKafka Brokerに入ったときの時刻がmessageタイムスタンプに付与 • processing-time • 「Kafka Streamsがそのイベントを処理した瞬間」 20
  • 21. timestamp.extractor 21 Time分類 timestamp.extractor event-time(独自) 自分で実装する event-time(message) ConsumerRecordTimestampExtractor ingestion-time ConsumerRecordTimestampExtractor processing-time WallclockTimestampExtractor import java.util.Properties; import org.apache.kafka.streams.StreamsConfig; Properties props = new Properties(); props.put(StreamsConfig.TIMESTAMP_EXTRACTOR_CLASS_CONFIG, WallclockTimestampExtractor.class.getName()); 設定例
  • 22. 独自クラス実装例 22 import org.apache.kafka.clients.consumer.ConsumerRecord; import org.apache.kafka.streams.processor.TimestampExtractor; // TimestampExtractorインタフェースを実装する public class MyEventTimeExtractor implements TimestampExtractor { @Override public long extract(ConsumerRecord<Object, Object> record) { // ログをパースしてtimestampを取り出す Foo myPojo = (Foo) record.value(); if (myPojo != null) { return myPojo.getTimestampInMillis(); } else { // valueがnullだったらとりあえず現在時刻をいれておく return System.currentTimeMillis(); } } } http://docs.confluent.io/3.0.0/streams/developer-guide.html#timestamp-extractor (コメント以外引用)
  • 23. Window 23 • Tumbling time window • 5分毎のユーザ毎のPV数とか • Hopping time window • 1つのイベントが複数のウィンドウにまたがる KStream<String, String> viewsByUser = ユーザIDがkeyのPVログStreamなど; KTable<Windowed<String>, Long> userCounts = viewsByUser.countByKey(TimeWindows.of(”WindowName", 5 * 60 * 1000L)); TimeWindows.of(”WindowName", 5 * 60 * 1000L).advanceBy(60 * 1000L);
  • 24. Join 24 • ストリーム処理でよくやるストリームとテーブルのJoinができる • KTableはローカルにあり、常に最新である • メッセージ処理毎にネットワークを超えてKVSを叩く必要も、鮮度を諦めて定期的にRDBを メモリにロードする必要もない KStream<String, String> voteRegionStream = ...(“vote-topic”) KTable<String, String> partyTable = ...("party-topic"); KStream<String, String> voteParty = voteRegionStream.leftJoin( partyTable, (region, party) -> region + ”," + party); k: Hillary v: California k: candidate v: party Hillary Democratic Trump Republican k: Hillary v: California, Democratic
  • 25. アジェンダ • 概要 • Word Count • Time, Window, Join • つかってみた • まとめ 25
  • 26. Kafka Streamsで開発してみた • Kafkaクラスタから引いた全メッセージをグルーピング、ウィンドウ集計して指標をsinkに 書くシンプルなアプリ • ローカルでテストは通った、本番デプロイいこう • バグを踏む:Kafka-4160 (´・ω・`) • Kafka Streamsのフォアグラウンドスレッドとバッググラウンド ハートビートスレッドの間に単一のロックがある • タスク生成中にハートビートをブロックするのでタスク生成が長い とセッションタイムアウトを超える • consumerがグループから追い出されて再度タスク生成を始める • 永遠に繰り返してデッドロックみたくなる • 入力パーティション数が少ないと問題にならないのだが 本番では1topicあたり最大60あったため本番で初めて発覚した 26
  • 27. 続き • バグは Kafka 0.10.1.0 で解消されたよ!(今client, server共に 0.10.0.1) • Kafka Streams をバージョンアップすれば解決しそう • > Apps built with Kafka Streams 0.10.1 only work against Kafka clusters running 0.10.1+. • 古いサーバに対しても互換性なんとかしたいとは書いてあった • 0.10.0.1のKafkaにバグフィックスだけパッチ当ててアプリに入れるか・・・ • 対象コードが 0.10.1 で大きく変わってて厳しい • やっぱりサーバあげよう ← イマココ 27 ___________ /|:: ┌──────┐ ::| /. |:: | Exception | ::| / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ |.... |:: | Use 0.10.1 !| ::| | マイナーバージョンアップなら…アレ? |.... |:: | .| ::| \_ ______ |.... |:: └──────┘ ::| ∨ \_| ┌────┐ .| ∧∧  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ( _) / ̄ ̄ ̄ ̄ ̄旦 ̄(_, ) / \ | ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄|、_)  ̄| ̄| ̄ ̄ ̄ ̄ ̄ ̄|
  • 28. 思ったこと • 向くユースケースなら向く • Kafka Streamsのコンセプトがわかってきてからシステム設計した方がいいかも • 既にカッチリ決まった要件にKafka Streamsを合わせようとするとハックするはめになるかも • ライブラリならアプリケーション開発を楽にしてくれなくちゃいけない • Kafkaの素のハイレベルAPIがそもそもかなりちょうどいい抽象化 • Kafka Streams APIの利点が活かせるかどうか • インターナルトピックをかなり大量に作ることを想定している(アプリのバージョンアップご とにトピックは増える) • 小さめのサービス専用クラスタとかならいいが、マルチテナント向けのクラスタだとちょっと気持ち悪 いかも • 現在は1 Kafkaクラスタしか指定できないが将来的には複数可能になるかも 28
  • 29. アジェンダ • 概要 • Word Count • Time, Window, Join • つかってみた • まとめ 29
  • 30. まとめ • Kafka Streamsはストリーム処理のアプリケーションを実装するためのライブ ラリ • シンプルながらストリーム処理でよく必要になる、自分で実装するには難し い機能を実現する • 時間軸に何を使うか開発者が選択できる • Kafka Streamsが便利に使えるようにシステム設計をすると吉 30
  • 32. Kafka Streamsはどこで動くの? 32 • consumerアプリケーション • 普通はKafkaクラスタの(物理的に)近くのアプリケーション専用サーバ上でJavaプロセスとして動 かすと思う • ライブラリなので何でもできるが、Kafkaとしか接続しないように全体設計すると楽そう Kafkaクラスタ source topic internal topic sink topic Kafka Streams Kafka Connect 等 Kafka Connect 等
  • 33. Configuration 33 import java.util.Properties; import org.apache.kafka.streams.StreamsConfig; import org.apache.kafka.clients.producer.ProducerConfig; import org.apache.kafka.clients.producer.ConsumerConfig; Properties settings = new Properties(); settings.put(StreamsConfig.APPLICATION_ID_CONFIG, “my-app”); // StreamConfigのこの3つは必須 settings.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, ”localhost:9092"); settings.put(StreamsConfig.ZOOKEEPER_CONNECT_CONFIG, ”localhost:2181"); settings.put(ProducerConfig...., “”); // 必須でない settings.put(ConsumerConfig...., “”); // 必須でない application.id アプリケーション認識名. consumer group名やinternal topic名等に利用される. bootstrap.servers 接続するKafkaクラスタのhost/portペアのリスト. zookeeper.connect 接続するZooKeeperのコネクション文字列(host:port/chroot). num.stream.threads ストリーム処理のために使うスレッド数. replication.factor internal topicを作るときのレプリケーションファクタ state.dir State Storeのディレクトリパス timestamp.extractor 後述
  • 36. changelog topic(おまけ) • topicはKafka Streamsアプリケーションの実行時に自動で作成される • 手動でtopicを作るときと同じような感じで、Kafka設定 auto.create.topics.enable=falseでも作成される • topic設定はcompact • 同じkeyで頻繁にvalueが変わるはずだから • タスク数分パーティションが作られる 36
  • 37. プログラム(full) 37 @Test public final void wordCount() { final Serde<String> stringSerde = Serdes.String(); // Serde is Serializer/Deserializerの略、Kafka共通のクラス final Serde<Long> longSerde = Serdes.Long(); // 基本的なビルトインをSerdesから呼べる、もちろん自作可能 KStreamBuilder builder = new KStreamBuilder(); // 入力名からKStreamを作る. 1: key Serde, 2: value Serde, 3: 入力トピック名(複数指定可能) KStream<String, String> queryStream = builder.stream(stringSerde, stringSerde, “search-query-topic”); KStream<String, Long> wordCounts = queryStream // valueに対して空白区切りで文字列を分割して次に送る処理 .flatMapValues(value -> Arrays.asList(value.split(“¥¥s+”))) // key毎カウントしたいからkeyにvalueを入れる .map((key, value) -> new KeyValue<>(value, value)) .countByKey(stringSerde, “Counts”) // KStream -> KTable、第二引数はKTable名 .toStream(); // KTable -> KStream wordCounts.to(stringSerde, longSerde, “wordcount-output”); // sinkトピックに結果を書く KafkaStreams streams = new KafkaStreams(builder, props); // propsはKafka StreamsやClientの設定Properties streams.start(); // アプリケーション実行 }
  • 38. 比較(full) 38 方法 (難しい機能) 実装の簡単さ 学習 コスト 運用(デプロイ) コスト 実績 ドキュメント 充実度 ① 素のKafka Java APIを使う ✕ ◯ ◯ ◯ ◯ ② ストリーム処理 フレームワークを使う ◯ ✕ ✕ △ (差異が大きい) △? ③ Kafka Streams ◯ △ ◯ ✕ △ ※独断と偏見