狀態生命周期hint
FlinkSQL
?的?state ttl
(Time-To-Live,生存時間)是一個用于管理狀態數據生命周期的機制。在 Flink 流處理中,狀態是一個重要的概念,它允許跨時間窗口或事件時間處理的狀態化操作。然而,隨著時間的推移,這些狀態數據可能會變得不再相關或過時。為了有效地管理這些狀態并避免無限期地保留它們,Flink 引入了?state ttl
?機制。
state ttl
?允許你為狀態設置一個生存時間。一旦狀態數據的生存時間超過了指定的 TTL 值,Flink 就會自動清理這些狀態。這有助于減少不必要的狀態數據占用,提高系統的穩定性和性能。
對于有狀態計算的流連接和分組聚合操作,用戶可以通過?STATE_TTL
?來指定算子粒度的空閑狀態維持時間,該方式能夠使得在上述狀態算子中使用與作業級別?table.exec.state.ttl?不同的值。
流連接示例?#?
CREATE TABLE my_table ( ...
) WITH ( 'connector' = '...', 'scan.startup.mode' = 'latest-offset', 'state.ttl' = '3h' -- 設置狀態生存時間為3小時
);
在上面的例子中,state.ttl
?被設置為?3h
,意味著任何狀態數據的生存時間超過 3 小時后都會被自動清理。
更多例子:
CREATE TABLE orders (o_orderkey INT,o_custkey INT,o_status BOOLEAN,o_totalprice DOUBLE
) WITH (...);CREATE TABLE lineitem (l_linenumber int,l_orderkey int,l_partkey int,l_extendedprice double
) WITH (...);CREATE TABLE customers (c_custkey int,c_address string
) WITH (...);-- 表名作為 hint 鍵
SELECT /*+ STATE_TTL('orders'='3d', 'lineitem'='1d') */ * FROM
orders LEFT JOIN lineitem
ON orders.o_orderkey = lineitem.l_orderkey;-- 別名作為 hint 鍵
SELECT /*+ STATE_TTL('o'='3d', 'l'='1d') */ * FROM
orders o LEFT JOIN lineitem l
ON o.o_orderkey = l.l_orderkey;-- 臨時視圖作為 hint 鍵
CREATE TEMPORARY VIEW left_input AS SELECT ... FROM orders WHERE ...;
CREATE TEMPORARY VIEW right_input AS SELECT ... FROM lineitem WHERE ...;
SELECT /*+ STATE_TTL('left_input'= '360000s', 'right_input' = '15h') */ *
FROM left_input JOIN right_input
ON left_input.join_key = right_input.join_key;-- 級聯 join
SELECT /*+ STATE_TTL('o' = '3d', 'l' = '1d', 'c' = '10d') */ *
FROM orders o LEFT OUTER JOIN lineitem l
ON o.o_orderkey = l.l_orderkey
LEFT OUTER JOIN customers c
ON o.o_custkey = c.c_custkey;
分組聚合示例?#?
-- 表名作為 hint 鍵
SELECT /*+ STATE_TTL('orders' = '1d') */ o_orderkey, SUM(o_totalprice) AS revenue
FROM orders
GROUP BY o_orderkey;-- 別名作為 hint 鍵
SELECT /*+ STATE_TTL('o' = '1d') */ o_orderkey, SUM(o_totalprice) AS revenue
FROM orders AS o
GROUP BY o_orderkey;-- 查詢塊作為 hint 鍵
SELECT /*+ STATE_TTL('tmp' = '1d') */ o_orderkey, SUM(o_totalprice) AS revenue
FROM (SELECT o_orderkey, o_totalpriceFROM ordersWHERE o_shippriority = 0) tmp
GROUP BY o_orderkey;
注意:
- 用戶既可以選擇表(或視圖)名也可以選擇別名作為提示鍵,但在指定別名時需要使用別名。
- 對于多流連接場景,直接指定每張表的生命周期只會在第一個連接算子的左右流和第二個連接算子的右流上生效(因為流上關聯操作是二元的)。如果想為每個連接算子的左右流都指定不同生命周期,需要將查詢拆成多個查詢塊,如下所示。
CREATE TEMPORARY VIEW V AS SELECT /*+ STATE_TTL('A' = '1d', 'B' = '12h')*/ * FROM A JOIN B ON...; SELECT /*+ STATE_TTL('V' = '1d', 'C' = '3d')*/ * FROM V JOIN C ON ...;
STATE_TTL
?提示僅作用在當前查詢塊上。- 當?
STATE_TTL
?提示鍵重復時取最后一個值。舉例來說,在出現?SELECT /*+ STATE_TTL('A' = '1d', 'A' = '2d')*/ * FROM ...
?時,輸入 A 的 TTL 值將會取 2d。- 當出現多個?
STATE_TTL
?且提示鍵重復時取第一個值。舉例來說,在出現?SELECT /*+ STATE_TTL('A' = '1d', 'B' = '2d'), STATE_TTL('C' = '12h', 'A' = '6h')*/ * FROM ...
?時,輸入 A 的 TTL 值將會取 1d。