Kafkaでイベントを流す土台はできた、次は「そのイベントをどう処理するか」が問題になります。1分ごとの注文を地域別に集計したい、5分間に発生した異常パターンを検知したい、複数のイベントを相関させたい。こうした本格的なストリーム処理を担うのがApache Flinkです。

「真のストリーミング」(イベント単位処理)で設計されており、低遅延・高スループット・厳密な状態管理を同時に実現します。学習コストは高めですが、本格的なリアルタイム処理が必要な場面では第一選択になるOSSです。基本構造と使い方を整理します。

Flinkの基本構造

コンポーネント役割
JobManagerジョブの調整・タスク配置
TaskManager実体タスクを動かす
State Backend状態の永続化(RocksDB等)
Checkpoint定期的に状態をスナップショット
Source / SinkKafka、ファイル、DBとの入出力

Sparkに似たクラスタアーキテクチャですが、ストリーム処理に特化した状態管理とチェックポイント機能が中核です。「障害が起きても、最後のチェックポイントから処理を再開する」のがFlinkの安心感の源です。

DataStream API:Javaコードで書く

// Kafkaから注文イベントを読み、1分窓で売上集計
DataStream<Order> orders = env.fromSource(
    KafkaSource.builder()
        .setBootstrapServers("localhost:9092")
        .setTopics("orders")
        .setDeserializer(new OrderDeserializer())
        .build(),
    WatermarkStrategy.forBoundedOutOfOrderness(Duration.ofSeconds(10)),
    "kafka-source"
);

DataStream<RevenueByMinute> revenue = orders
    .keyBy(Order::getCustomerId)
    .window(TumblingEventTimeWindows.of(Time.minutes(1)))
    .aggregate(new RevenueAggregator());

revenue.sinkTo(new SnowflakeSink());

「Kafkaから読み」「customer_idで分割」「1分窓で集計」「Snowflakeに書く」という流れがコードで明確に書けます。Watermarkで遅延イベントへの対処も組み込まれます。

Flink SQL:SQLで書ける

FlinkはSQL APIも提供しており、ストリーム処理をSQLで書けます。学習コストが大幅に下がります。

-- Kafkaソースを宣言
CREATE TABLE orders (
    order_id BIGINT,
    customer_id BIGINT,
    amount DECIMAL(10,2),
    ordered_at TIMESTAMP(3),
    WATERMARK FOR ordered_at AS ordered_at - INTERVAL '10' SECOND
) WITH (
    'connector' = 'kafka',
    'topic' = 'orders',
    'properties.bootstrap.servers' = 'localhost:9092',
    'format' = 'json'
);

-- 1分窓で売上集計
SELECT
    TUMBLE_START(ordered_at, INTERVAL '1' MINUTE) AS window_start,
    customer_id,
    SUM(amount) AS revenue
FROM orders
GROUP BY TUMBLE(ordered_at, INTERVAL '1' MINUTE), customer_id;

クラウドDWHでSQLを書き慣れていれば、Flink SQLは比較的取っ付きやすいです。Decodable・Aiven for Apache Flink・Confluent Cloudのマネージド版でFlink SQLが提供されており、運用負担を下げて始められます。

状態管理と Checkpoint

Flinkの真骨頂が「状態管理」です。ジョブが保持する集計値や、過去イベントの記憶を、RocksDB等の永続化ストアに保存しながら処理します。Checkpointで定期的に状態をスナップショットし、障害時にそこから復旧します。

State Backend特徴
HashMapJVMメモリ。小さな状態に
RocksDBローカルディスク+圧縮。大規模状態に
ExternalS3等にCheckpoint保存(推奨)

「複数イベントを跨いだ集計や相関」が必要な処理では、状態管理の堅牢さが運用品質を左右します。Flinkがこの領域で他のストリーム処理エンジンと差別化される点です。

Spark Streamingとの違い

FlinkSpark Streaming(Structured Streaming)
処理モデル真のストリーミング(イベント単位)マイクロバッチ(短いバッチを連続)
遅延サブ秒〜秒秒〜数十秒
状態管理強力(RocksDB標準)あり(Checkpointと統合)
学習コストSparkユーザーならX低
本番実績大規模本番で多数Sparkエコシステム内で多い

Sparkでバッチを書き慣れているチームが軽い準リアルタイムを始めるならSpark Streaming、本格的な低遅延・複雑な状態管理が要件ならFlink、と分かれます。

マネージドの選択肢

サービス特徴
Ververica PlatformFlink本家系(Alibaba傘下)のエンタープライズ版
AWS Managed Service for Apache FlinkAWSのマネージド(旧Kinesis Data Analytics for Flink)
Confluent Cloud FlinkConfluentによるFlink SQLマネージド
DecodableFlink SQL中心のマネージドサービス
Aiven for Apache Flinkマルチクラウド対応のマネージド

Flinkは特にOSS自社運用が重く、クラスタの管理、Checkpointストレージ、ジョブのスケーリング設計が要る。マネージドが現実的な選択になりつつある。

運用上のハマりどころ

  • 状態のサイズが爆発:KeyByの粒度を誤ると、状態がメモリ・ディスクを食い潰す。Key設計に経験が要る。
  • Watermarkの設定:遅延イベントへの対処はWatermarkで制御するが、適切な値の見極めが難しい。
  • Checkpoint間隔と障害復旧時間:間隔を短くすると安心だがオーバーヘッド、長くすると復旧時間が伸びる。バランス調整が必要。
  • ジョブのバージョンアップ:状態スキーマが変わると、既存Checkpointから復旧できない。Savepoint運用が必須。

向く・向かない場面

  • 向く:本格的な低遅延処理、複雑な状態管理が必要、CEP(複合イベント処理)、不正検知、リアルタイムアラート、CDC+複雑な変換
  • 向かない:シンプルなリアルタイムビュー(→Materialize)、SQLで完結する集計、運用人員が薄い

まとめ

  • Apache Flinkは「真のストリーミング」を実現する分散処理エンジン。
  • 状態管理とCheckpointが中核で、複雑な処理を低遅延・堅牢に実行できる。
  • DataStream API(Java)とFlink SQL(SQL)の両方で書ける。
  • Spark Streamingとは「マイクロバッチか真のストリーミングか」が大きな違い。
  • OSS自社運用は重く、Decodable等のFlink SQLマネージドから始めるのが現実的。

全体像はバッチ vs ストリーミングの選び方、隣接の選択肢はKafka とはMaterialize とはにあります。Flink導入や設計の壁打ちは、DE-STKの初回相談(30分・無料)もご利用ください。

よくある質問(FAQ)

Q. Flinkの学習コストはどの程度?

A. ストリーム処理の概念(時間窓・Watermark・状態管理)に慣れる必要があり、Java/Scalaの経験があっても2〜3ヶ月の本格的な学習期間が要る。Flink SQLから入れば、SQLが書ける人なら数週間で基本的なジョブが組めるレベルになる。新規導入なら、Flink SQLで始めて、必要に応じてDataStream APIへ降りる順序がコスト効率が良い。

Q. Flinkでデータウェアハウスに書き込めますか?

A. 公式・コミュニティ製のSinkで、Snowflake、BigQuery、Iceberg、Delta Lakeへの書き込みが可能です。リアルタイム処理の結果をDWHに永続化する典型構成です。クラウドDWHの基本はクラウドDWH入門、Icebergへの書き込みはApache Iceberg とはを参照してください。

Q. Flinkのジョブを安全にアップグレードする方法は?

A. Savepointを取って、新しいバージョンのジョブをそのSavepointから起動するのが定石です。状態スキーマに互換性があれば、ジョブのコード変更後も状態を引き継いで処理を続けられます。互換性がない変更は事前にテストし、必要なら状態移行ロジックを準備します。本番運用ではジョブのリリースサイクルとSavepoint運用を組織で標準化します。

Q. Flinkを使わずにストリーミング処理する選択肢は?

A. シンプルなリアルタイムSQL集計ならMaterializeが代替になります。Sparkユーザーなら Spark Structured Streaming、Kafkaの軽い処理だけならKafka Streams(Javaライブラリ)が選択肢です。「Flinkほどの本格機能が要らない」「もっと素早く始めたい」場合は、これらの軽量代替を検討してください。

▼ このトピックをポチポチ学ぶ

ストリーミングとCDC

関連記事を順序立てて読みながら、ステップごとに4択クイズで理解を確認できる学習パスです。登録不要・進捗自動保存。

学習パスを始める →