Hadoop + Kafka + Iceberg 環境に Flink を追加してリアルタイム可視化する設計
はじめに
前回の記事で構築してきた syslog/authlog 収集解析基盤では、以下のような流れでログを扱っている。
- rsyslog / Fluentd などでログ収集
- Kafka に投入
- HDFS に RAW 保存
- Hive curated / Iceberg に整形格納
- Spark / Trino / Grafana で分析・可視化
この構成でも「前日分の集計」や「任意タイミングで当日分を再取り込みして分析」は十分実用的だった。
一方で、以下のような要求が出てくると、もう一段リアルタイム寄りの仕組みが欲しくなる。
- 数秒〜数十秒単位で件数推移を見たい
- SSH失敗急増などの異常傾向を早く検知したい
- Kafka に入ってきたイベントをそのままストリーム集計したい
- HDFS/Spark バッチを待たずにダッシュボードへ反映したい
そこで候補になるのが Apache Flink である。
本記事では、既存の Hadoop/Kafka/Iceberg 基盤に Flink を追加し、Zeppelin / Grafana でどう可視化するか を設計レベルで整理する。
想定する現状構成
まず、現在のざっくり構成を以下とする。
- Kafka: syslog / authlog トピック
- HDFS: RAW ログ保管
- Hive curated: Parquet 化した分析用テーブル
- Iceberg: 高速分析用テーブル
- Spark: バッチ取り込み・整形
- Trino: Grafana からのクエリ用
- Zeppelin: 検証・試験分析
- Grafana: ダッシュボード
現状の主な特徴は次の通り。
- 履歴分析には強い
- 大量データの再集計に向く
- 時系列の長期保存・検索に向く
- 一方で「今この瞬間の増減」を常時出す用途は少し重い
Flink を入れる目的
Flink を入れる目的は、既存基盤を置き換えることではない。
既存のバッチ・蓄積系に対して、リアルタイム集計レイヤを追加する のが狙いになる。
たとえば次のような用途に向いている。
- 1分ごとの syslog 件数をリアルタイム更新
- ホスト別 authlog 件数をリアルタイム更新
- SSHログイン失敗の急増検知
- 特定メッセージパターンのストリーム集計
- Kafka の到着データをそのまま窓関数で集計
つまり、役割分担はこうなる。
- Kafka: イベントの受け皿
- Flink: リアルタイム変換・集計
- Iceberg / HDFS: 長期保存
- Trino / Grafana: 可視化
- Zeppelin: SQL確認
作成するリアルタイム収集テーブル
テーブル構成としては、まず次の 2 段階で考えるのが現実的だった。
段階1: リアルタイムログ収集
- Kafka から Flink が読む
- ログが適宜入り次第Flinkから適宜Icdbergへ保管
- Grafana は Trino 経由で Iceberg を見る
- Zeppelin は spark 経由で Iceberg を見る
段階2: 分毎ログ件数収集
- Kafka から Flink が読む
- Flink で 1分窓集計
- 集計結果を Iceberg に書く
- Grafana は Trino 経由で Iceberg を見る
- Zeppelin は spark 経由で Iceberg を見る
追加アーキテクチャ
ポイント
- Kafka は既存流用
- Flink はストリーム処理専用で追加
- 保存先は Iceberg に寄せる
- Grafana は Trino 経由で見る
- Zeppelin は分析・試験用途に限定する
構成図(既存構成 → 拡張後)
既存構成
Flink 追加後の推奨構成
役割の見方
- Kafka: イベント受け皿
- Kafka Connect / HDFS RAW: 元データ保全
- Flink: リアルタイム変換・集計
- Iceberg: 生イベント整形後と集計結果の共通保存先
- Trino: Grafana からの参照口
- Spark: Zeppelin からの参照口
- Grafana: データ参照
- Zeppelin: データ解析
なぜ保存先は Iceberg がよいのか
Flink の出力先はいくつか考えられる。
- Kafka 再出力
- JDBC
- Elasticsearch / OpenSearch
- HDFS
- Iceberg
今回の既存構成では Iceberg が最有力 になる。
理由は以下。
1. 既存の分析基盤とつながる
すでに Spark / Trino / Grafana / Zeppelin側で Iceberg を見ているなら、Flink もそこへ寄せたほうが一貫性がある。
2. 履歴も持てる
「今の値」だけではなく、後から過去のリアルタイム集計結果も追える。
3. バッチとストリームを同じ土台に寄せやすい
Spark で日次再集計、Flink で即時反映、という役割分担がしやすい。
4. 将来の拡張に強い
異常検知や再処理の際にも、Iceberg テーブルを共通基盤にしやすい。
Zeppelin と Grafana の使い分け
ここは最初に整理しておいたほうがよい。
Zeppelin が向いていること
- イベント形式の確認
- 途中集計結果の確認
- 解析SQLの試作
- 運用者向けの調査ノート
Grafana が向いていること
- 常時監視
- 時系列ダッシュボード
- 件数推移の継続監視
- 閾値監視とアラート
- 運用画面としての見やすさ
結論
- Zeppelin は作る場所・試す場所
- Grafana は見る場所・監視する場所
この役割分担が分かりやすい。
Zeppelin を本番ダッシュボード代わりに使うより、Grafana に寄せたほうが運用は安定しやすい。
ストリーム設計
Flink 集計結果を Iceberg に保存して Grafana で見る
Kafka -> Flink -> Iceberg(agg) -> Trino -> Grafana
長所
- 既存構成との親和性が高い
- Grafana 連携が自然
- 履歴が残る
- 再利用しやすい
短所
- 数秒単位の完全リアルタイムには少し遅延がある
- Flink/Iceberg のコミット周期設計が必要
どんなテーブルを持つべきか
Flink を入れるとき、最初から大きく作りすぎない方がよい。
最低限、次のような集計テーブルがあると使いやすい。
1. syslogイベント一覧
- ts
- host
- program
- message
- dt
2. authlogイベント一覧
- ts
- host
- program
- message
- dt
3. syslog 分単位件数
- window_start
- window_end
- host
- count
- dt
4. authlog 分単位件数
- window_start
- window_end
- host
- count
- dt
これだけでも Grafana でかなり見やすくなる。
監視観点の例
Flink を入れるなら、ただ件数を見せるだけでなく、何を見たいかを決めておくとよい。
syslog 側
- 全体件数の急増/急減
- ホスト別件数の偏り
- 特定 program の増加
- error / warn レベルの増加
authlog 側
- SSH 失敗件数の増加
- ホスト別失敗件数上位
- 特定ユーザー宛の失敗増加
- Accepted / Failed の比率変動
Kafka/Flink 側
- 取り込み遅延
- 消費遅れ
- チェックポイント失敗
- ジョブ再起動回数
Flink クラスタはどこに置くか
新規ホスト前提で考えるなら、最初は以下のような置き方が無難。
最小
- Flink JobManager/TaskManager: 1台
役割
- JobManager: 制御
- TaskManager: 実処理
分ける理由
- Kafka / Spark / Trino / Zeppelin と役割分離しやすい
- 障害切り分けしやすい
- リソース競合を減らせる
目安
リアルタイム件数集計だけなら、最初は大規模でなくてよい。
ただし Kafka / Iceberg / checkpoint を考えると、メモリ不足は避けたい。
本検証では4GBを付与。
参考スペック感(設計レベル)
最初の検証〜小規模運用なら次のイメージでよい。
JobManager/TaskManager
- vCPU: 2
- Memory: 4GB 前後
- Disk: 30GB 程度
備考
- チェックポイント保存先は HDFS または十分安定したストレージが望ましい
- Kafka トピック数と並列度で必要リソースは増える
- まずは「小さく始めて測る」が正解
Flink を入れることで何が変わるか
変わること
- リアルタイム処理層が増える
- 運用監視ポイントが増える
- 集計タイミングがバッチ待ちでなくなる
変わらないこと
- 長期保存の主役は引き続き Iceberg/HDFS
- 履歴分析に Spark/Trino は有効
- Grafana の見せ方自体は大きく変えなくてよい
つまり、Flink は 既存基盤の代替ではなく補強 である。
Grafana での見せ方
Grafana 側は、Flink 導入後に次のようなダッシュボード構成が分かりやすい。
リアルタイム件数ダッシュボード
- syslog 分単位件数
- authlog 分単位件数
- ホスト別上位
- 直近1日の推移
重要な考え方
Grafana は「最新値しか見られない」のではなく、
Flink が集計した時系列をテーブルとして残せば、普通の時系列ダッシュボードとして見られる。
つまり、保存先設計が大事になる。
Flink の障害・再起動と savepoint 運用方針
Flink を運用する上で、「checkpoint / savepoint をどこまで厳密に扱うか」は重要な設計ポイントになる。
一般的には以下のような運用が推奨されることが多い。
checkpoint による自動復旧
savepoint による安全な手動再起動
ジョブ停止時は必ず savepoint を取得
ただし、本構成では以下の前提がある。
Flink は 当日分のリアルタイム集計レイヤ
Kafka / HDFS RAW / Hive curated により 元データは保持されている
過去データは Spark / バッチで再取得可能
このため、設計としては以下のように割り切ることができる。
採用方針
checkpoint は有効化(障害時の短時間復旧用)
savepoint は常用しない
計画メンテ時のみ、必要に応じて手動取得
Flink 障害時の「当日分の一部欠損」は許容
過去分はバッチ処理で補完する
この方針の理由
Flink を「唯一のデータ取得経路」として扱う場合は、savepoint を含めた厳密な状態管理が必要になる。
一方、本構成では以下のように役割が分離されている。
Kafka / HDFS: 元データの保全
Spark / Hive / Iceberg: 正規データの生成
Flink: リアルタイム集計(速報用途)
そのため、Flink 側で多少の欠損が発生しても、後続のバッチ処理で補完できる。
運用イメージ
通常運用
Flink は通常起動・通常停止(savepointなし)
checkpoint による自動復旧のみ利用
計画停止
必要な場合のみ savepoint を手動取得
その後ジョブ停止
障害発生時
savepoint 復旧は必須としない
通常再起動を優先
必要に応じて当日分をバッチで補完
ポイント
この設計により、
運用の複雑さを抑えられる
savepoint 管理コストを削減できる
既存のバッチ基盤との役割分担が明確になる
つまり、
Flink は「欠損ゼロを保証する基盤」ではなく、
「リアルタイム可視化のための補助レイヤ」として扱う
という整理になる。
Kafka retention とデータ補完の関係
本構成では Kafka のデータは Kafka Connect により HDFS に常時保存されるため、
Kafka retention を超えたデータであっても HDFS RAW から再取得が可能である。
そのため、
Kafka retention は再処理可能期間ではなく
Flink が追従するためのバッファ時間として扱う
設計としている。
ただし、以下には注意が必要である。
Kafka → HDFS の連携が停止した場合
HDFS RAW が欠損した場合
この場合はデータ補完ができなくなるため、
HDFS 側の保全が重要となる。
今の基盤に対する現実的な導入ステップ
Step 1
Flink クラスタを別ホストで追加する
Step 2
Kafka の syslog / authlog を読む簡単なジョブを作る
Step 3
1分窓で host 別件数を集計して Iceberg に書く
Step 4
Trino から集計テーブルを参照できるようにする
Step 5
Grafana にリアルタイムダッシュボードを作る
Step 6
savepoint活用構成への運用拡張
この順で進めると、既存基盤を壊さずに拡張できる。
どこまで Flink に寄せるべきか
これはかなり重要。
結論として、最初は 全部を Flink に寄せない 方がよい。
最初は寄せるもの
- 直近監視に必要なリアルタイム集計
- 単純なカウント
- 短い窓集計
- 監視向けメトリクス
まだ寄せなくてよいもの
- 大規模な履歴再計算
- 複雑な日次集計
- 既存 curated 全置換
- 全分析ロジックの移植
まずは「見るためのリアルタイム集計」だけ追加するのが安全。
まとめ
既存の Kafka / HDFS / Iceberg / Spark / Trino / Grafana 基盤に Flink を加えるなら、
最初の設計としては以下が最も現実的だった。
- Flink は Kafka のストリーム集計担当
- 保存先は Iceberg
- Grafana は Trino 経由で可視化
- Zeppelin は試験・確認用途
- まずは 1分窓の件数集計から始める
つまり全体像はこうなる。
- 保存・履歴分析 は今の基盤を活かす
- リアルタイム集計 だけ Flink を追加する
- 可視化 は Grafana を中心にする
- 解析 は Zeppelin を使う
この方針なら、既存構成を大きく崩さずに、リアルタイム性だけを強化できる。
補足:リアルタイムとバッチの役割分担
Flink:当日リアルタイム(速報)
Spark / Hive:過去データ(正本)この二層構造にすることで、
リアルタイム性
正確性
運用性のバランスを取りやすくなる。
おわりに
Flink を入れると、「昨日の集計を見る基盤」から「今の変化を見る基盤」へ一歩進める。
ただし、最初から全部を Flink 化する必要はない。
まずは、
- Kafka → Flink → Iceberg
- Trino → Grafana
- Zeppelin は解析
この最小構成で始めるのがよい。
リアルタイム可視化の価値が見えた段階で、
異常検知やアラート、さらには raw→Iceberg のストリーム化へ広げていくのが現実的だと思う。
構築手順
ここまで構築した内容について以下にまとめています。
興味があればぜひ挑戦してみてください。