Flink 實時計算 QPS 面試題
題目:
假設某互聯網應用日活用戶 100 萬,每天產生 1 億條數據(日志/事件),要求使用?Apache Flink?實現實時計算系統的?QPS(Queries Per Second),并考慮以下需求:
實時統計當前 QPS(每秒請求數),并輸出到監控系統(如 Prometheus、Kafka、MySQL 等)。
處理數據傾斜,某些 key(如熱門用戶或接口)可能產生大量數據,如何優化?
保證 Exactly-Once 語義,確保 QPS 計算不丟不重。
應對高峰流量,假設瞬時 QPS 可能達到 10,000,如何保證 Flink 作業的穩定性和低延遲?
問題:
請設計 Flink 作業的數據流(Source → Transformation → Sink),并說明關鍵算子(如?
window
、keyBy
、aggregate
)的作用。如何實現 QPS 的滑動窗口(如每 1s 計算一次最近 10s 的 QPS)?
如果某些 key 的數據量遠高于其他 key(數據傾斜),你會如何優化?
如何保證 Exactly-Once 語義?請結合 Checkpoint 和 StateBackend 說明。
如果 QPS 突增導致反壓(Backpressure),你會如何調整 Flink 作業配置?
考察點
??Flink 核心概念:Window、KeyedStream、State、Checkpoint
??性能優化:數據傾斜處理、反壓調優
??容錯機制:Exactly-Once 實現方式
??生產經驗:監控、Sink 適配、資源分配
參考答案(簡要版)
1. Flink 作業設計
DataStream<LogEvent> source = env.addSource(new KafkaSource<>(...)); // 從 Kafka 消費日志
DataStream<Tuple2<String, Long>> mapped = source .map(event -> Tuple2.of(event.getEndpoint(), 1L)) // 轉換為 (endpoint, 1) .returns(Types.TUPLE(Types.STRING, Types.LONG)); // 按接口名分組,計算每 10s 滑動窗口(每 1s 輸出一次)
DataStream<QpsResult> qpsStream = mapped .keyBy(t -> t.f0) // 按接口分組(可能數據傾斜) .window(SlidingProcessingTimeWindows.of(Time.seconds(10), Time.seconds(1))) .aggregate(new QpsAggregator()) // 自定義聚合函數 .addSink(new PrometheusSink()); // 輸出到監控系統
2. 數據傾斜優化
方案 1:加隨機前綴,如?
hot_key
?→?hot_key_1
,?hot_key_2
,聚合后再合并。方案 2:使用?
rebalance()
?強制均勻分發,犧牲局部有序性。
3. Exactly-Once 保證
Checkpoint 機制:開啟?
enableCheckpointing(5000)
,設置?CheckpointingMode.EXACTLY_ONCE
。StateBackend:使用?
RocksDBStateBackend
(大狀態)或?FsStateBackend
(低延遲)。Sink 端:Kafka 事務 / 冪等寫入(如 MySQL 用?
INSERT ON DUPLICATE KEY UPDATE
)。
4. 反壓調優
增加并行度:
setParallelism(4)
?分散負載。調整緩沖區:
taskmanager.network.memory.floating-buffers-per-gate
。啟用 RocksDB 本地 SSD:減少 State 訪問延遲。
進階問題:
如果 QPS 計算需要區分成功/失敗請求(如 HTTP 200 vs 500),如何修改?
如何用 Flink SQL 實現相同的 QPS 計算?
(面試者可選擇繼續深入討論~)