ksqlDB は Apache Kafka の上で動くストリーム処理エンジンで、Kafka Streams を土台にしつつ SQL ライクに継続クエリを書けます。プロデューサ/コンシューマのコードを書かずに、フィルタ、集計、ジョイン、派生トピックの作成を行えます。
本稿では、CCDAK(Confluent Certified Developer for Apache Kafka)の出題範囲に寄せながら、実務で迷いがちなキー設計、タイムセマンティクス、内部トピック、スキーマ管理の要点を具体的に解説します。
ksqlDB は Kafka のトピックを入力として継続クエリを実行し、結果を別トピックに書き出す、あるいは内部ストアにマテリアライズして問い合わせ可能にします。永続クエリ(CSAS/CTAS)はサーバ側で常時実行され、障害時は内部トピックと状態ストアから再構築されます。
開発者は SQL で論理を宣言し、キーやパーティション、シリアライゼーション形式、タイムスタンプなどの Kafka 固有事項を明示的に設定します。これらは CCDAK でも頻出で、特にジョイン/集計前の再パーティション(PARTITION BY)を忘れないことが肝要です。
| 項目 | ksqlDB | Kafka Streams (Java API) | Kafka Connect |
|---|---|---|---|
| 主用途 | SQL でのストリーミング変換/集計/ジョイン | コードでの細粒度なストリーム処理 | 外部システムとのデータ連携 |
| 記述スタイル | 宣言的(SQL) | 命令的(Java) | 宣言的(コネクタの設定) |
| 状態管理 | 自動(状態ストア + 内部トピック) | コードで制御(RocksDB + changelog) | なし(基本は stateless) |
| デプロイ | ksqlDB サーバにクエリを送信 | アプリケーションとして配備 | Connect クラスターにコネクタを配備 |
イベントの流れとクエリ実行のイメージ
最小構成のストリーム定義と派生トピック作成
CREATE STREAM clicks (
user_id STRING KEY,
page STRING,
ts TIMESTAMP
) WITH (
kafka_topic='raw_clicks',
value_format='JSON',
timestamp='ts'
);
CREATE STREAM clicks_en AS
SELECT user_id, page, ts
FROM clicks
WHERE page LIKE 'en/%'
EMIT CHANGES;STREAM は不変のイベントの連続(append-only)として解釈され、フィルタやマッピング、ウィンドウ集計の前段に向きます。TABLE は最新値の集合(変更ログの畳み込み結果)を表し、キーごとの最新状態を保持します。
Push クエリは変化を逐次取得する購読で、ダッシュボード更新などに向きます。Pull クエリはマテリアイズ済み TABLE に対するキー検索で、リクエスト/レスポンス型に適します。Pull は主キー制約に基づく等価比較が基本です。
STREAM と TABLE、Push/Pull の例
-- 集計で TABLE を作成(CTAS)
CREATE TABLE pv_per_user AS
SELECT user_id, COUNT(*) AS pv
FROM clicks
WINDOW TUMBLING (SIZE 5 MINUTES)
GROUP BY user_id
EMIT CHANGES;
-- Push: 変化を逐次取得
SELECT user_id, pv FROM pv_per_user EMIT CHANGES;
-- Pull: 特定ユーザーの現在値を 1 回取得(TABLE が必要)
-- SELECT pv FROM pv_per_user WHERE user_id='u-123';ウィンドウ集計はイベント時刻で時間区切りを設け、TUMBLING(固定幅・非重複)、HOPPING(固定幅・重複)、SESSION(アクティビティの塊)の 3 形態が代表的です。遅延到着イベントに対する許容期間(グレース)や出力タイミングは設計上の重要点です。
ジョインはキーとパーティション整合が前提です。STREAM-STREAM は時間的な WITHIN ウィンドウ指定が必要、STREAM-TABLE は参照系でウィンドウ不要、TABLE-TABLE は最新値同士の結合です。いずれもキーが合わなければ PARTITION BY で再パーティションします。
ウィンドウ集計とジョインの例
-- 5 分の TUMBLING 集計
CREATE TABLE page_views_5m AS
SELECT user_id, COUNT(*) AS cnt
FROM clicks
WINDOW TUMBLING (SIZE 5 MINUTES)
GROUP BY user_id
EMIT CHANGES;
-- STREAM-STREAM ジョイン(到着の近いイベント同士を結合)
CREATE STREAM enriched AS
SELECT c.user_id, c.page, p.product_id
FROM clicks c
JOIN purchases p
WITHIN 10 MINUTES
ON c.user_id = p.user_id
EMIT CHANGES;ksqlDB は VALUE_FORMAT と KEY_FORMAT を指定して Avro/JSON/Protobuf/KAFKA(バイト列)などを扱います。Schema Registry を併用するとスキーマの互換性チェックと進化(後方互換など)が運用しやすくなります。既定のサブジェクト名は <topic>-value / <topic>-key です。
集計やジョインではキーが正しく定義されていることが重要です。キーが不適切だとパーティションがバラけ、集計結果が期待通りになりません。PARTITION BY でジョイン・集計前に正しいキーへ並び替えるのが定石です。
スキーマとフォーマット、再パーティションの例
-- Avro で値を管理し、イベント時刻を明示
CREATE STREAM orders (
order_id STRING KEY,
user_id STRING,
amount DECIMAL(10,2),
event_time TIMESTAMP
) WITH (
kafka_topic='orders_raw',
key_format='KAFKA',
value_format='AVRO',
timestamp='event_time'
);
-- 集計前にユーザー単位へ再パーティション
CREATE STREAM orders_by_user AS
SELECT * FROM orders PARTITION BY user_id EMIT CHANGES;永続クエリ(CSAS/CTAS)は内部トピックと状態ストアを自動的に持ちます。スケールさせるには入力トピックのパーティション数とキー分布が均等であることが前提です。内部トピックのレプリケーションやクリーンアップポリシーも運用ポリシーに合わせて見直します。
障害時は内部の changelog から状態を再構築します。保留中のコミットや再実行に備え、少なくとも 3 ブローカー、十分なレプリケーション係数、堅牢なストレージを推奨します。Exactly-once の処理保証は Kafka/ksqlDB 双方で適切に設定したときに有効になります。
運用時に使う代表コマンド
-- クエリ一覧と説明
SHOW QUERIES;
EXPLAIN <QUERY_ID>;
-- 一時的な動作確認(早期テストに有効)
SET 'auto.offset.reset'='earliest';
PRINT 'raw_clicks' FROM BEGINNING LIMIT 5;試験では、キーとパーティション整合、ジョイン種別の前提、STREAM と TABLE の違い、Push/Pull の使い分け、スキーマ互換性と進化、内部トピックの役割、処理保証の違いが狙われます。ksqlDB 固有の文法暗記よりも、Kafka の設計原則に沿って理由を説明できることが重要です。
特に、集計・ジョイン前の PARTITION BY、イベント時刻の取り扱い(timestamp 指定)、Pull クエリには TABLE が必要、といった定石は落としがちなので確実に押さえましょう。
出題で迷いがちな書き方の最小例
-- 典型的な CSAS と再パーティション
CREATE STREAM s AS SELECT * FROM src EMIT CHANGES;
CREATE STREAM s_by_key AS SELECT * FROM s PARTITION BY some_key EMIT CHANGES;
-- Pull クエリは TABLE が対象
-- SELECT v FROM some_table WHERE id='k';CCDAK
問題 1
ユーザーごとの 10 分ウィンドウ PV 集計(TABLE)と、ユーザー属性(TABLE)を結合してページ上位をダッシュボードに Push 配信したい。正しい前提と手順の組み合わせはどれか。
正解: A
ウィンドウ集計は GROUP BY により TABLE を生成し、属性は TABLE 参照のため STREAM-TABLE ジョイン(ウィンドウ不要)が定石。ジョインや集計はキーとパーティション整合が必要で、不一致時は PARTITION BY により再パーティションする。
Push と Pull の違いは何ですか?
Push は SELECT ... EMIT CHANGES のように変更を継続送出する購読型。Pull はマテリアイズ済み TABLE の主キーに対する Point Lookup(現在値の 1 回取得)です。Pull には TABLE と主キー条件が必要です。
ksqlDB と Kafka Streams の選び分けは?
SQL で迅速にパイプラインを組みたい、運用をプラットフォーム側に任せたい場合は ksqlDB。細かい制御やカスタムロジック、複雑な状態管理が必要なら Kafka Streams(Java API)を選びます。
Exactly-once は使えますか?
Kafka/ksqlDB の設定が適切であれば Exactly-once の処理保証を利用可能です。ブローカー/プロデューサ/コンシューマ(Streams)側での構成が一貫していること、内部トピックのレプリケーションとストレージが十分であることが前提です。
NicheeLab編集部
データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。
Kafka Topic と Partition の基礎: 分散とスケーラビリティの要
CCDAK 対策と実務の両立を意識し、Topic/Partition/Replica/Consumer Group の役...
CCDAK 試験ガイド:出題範囲・配点・申込み・対策
Confluent Certified Developer for Apache Kafka (CCDAK) の出題範囲...
Confluent Certified Administrator (CCAAK) 対策: 出題範囲・配点の考え方・運用観点の要点
CCAAKに向けて、試験領域の押さえどころを運用目線で整理。プロダクションで通用する設定・監視・セキュリティの実践知を、...
Kafka の Replica と In-Sync Replicas を正しく設計する: 耐障害性と一貫性
レプリカとISRの仕組みを起点に、acks と min.insync.replicas、クリーン/アンクリーンリーダー選...
Kafka の Offset とコミット: ポジション管理と at-least-once の基礎
CCDAK 対策と実務の両立を意識して、Kafka コンシューマのオフセット管理とコミット戦略を整理。at-least-...