【问题标题】:Flink State TTL expiration for CollectionsCollections 的 Flink State TTL 过期
【发布时间】:2019-07-31 19:02:21
【问题描述】:

感谢您花时间阅读本文,想请教各位高手关于 Flink 1.8.0 中的 Flink 状态 TTL 特性,看完后 这个,对我来说还是很模糊的。

https://ci.apache.org/projects/flink/flink-docs-release-1.8/dev/stream/state/state.html#state-time-to-live-ttl

我想确定在哪里启用了 TTL 功能,是在键字段上还是在值字段上。特别是,假设我有一个这样的 mapState 结构:

mapState = Map[String,List[String]]
e.g. val mapState = Map("haha" -> List("foo","bar")) in Scala
where "haha" is the key of the mapState and List("foo","bar") is the value

如果我要通过 StateTtlConfig 在 mapState 上设置 1 分钟的 TTL,然后立即(不到 1 分钟)写入 List 中的一个值,例如“foo”。

那么1分钟后,当TTL触发时,是key“haha”过期还是value“bar”过期?

换句话说,如果它要在 key 上过期,我的理解是 mapState 将保持不变

mapState = Map("haha" -> List("foo","bar"))

因为写入值“foo”会重置键上的 TTL,因此整个 mapState 保持不变

另一种情况是,如果它在值上过期,mapState 将变为

mapState = Map("haha" -> List("foo"))

因为值“bar”会在 1 分钟后过期而不会被访问。

希望我把问题说清楚了,提前感谢您提供任何形式的帮助。

【问题讨论】:

    标签: scala apache-flink flink-streaming


    【解决方案1】:

    通过 TTL 访问状态的代码如下:

    <SE extends Throwable, CE extends Throwable, CLE extends Throwable, V> TtlValue<V> getWrappedWithTtlCheckAndUpdate(
            SupplierWithException<TtlValue<V>, SE> getter,
            ThrowingConsumer<TtlValue<V>, CE> updater,
            ThrowingRunnable<CLE> stateClear) throws SE, CE, CLE {
            TtlValue<V> ttlValue = getter.get();
            if (ttlValue == null) {
                return null;
            } else if (expired(ttlValue)) {
                stateClear.run();
                if (!returnExpired) {
                    return null;
                }
            } else if (updateTsOnRead) {
                updater.accept(rewrapWithNewTs(ttlValue));
            }
            return ttlValue;
        }
    

    验证值是否过期的方法如下:

        static <V> boolean expired(@Nullable TtlValue<V> ttlValue, long ttl, long currentTimestamp) {
            return ttlValue != null && expired(ttlValue.getLastAccessTimestamp(), ttl, currentTimestamp);
        }
    
    

    这基本上意味着在这种情况下,它将检查整个列表的 TTL,而不是单独的元素。因此,取决于StateTtlConfig,整个列表将过期或整个列表不会过期。

    可用的 TTL 配置是 OnReadAndWriteOnCreateAndWrite。所以,基本上为了保持一致,如果你想更新你的值列表,你需要在MapState 上使用put()

    【讨论】:

    • 非常感谢您的回复。根据您提供的代码和解释,我的理解是它在概念上与上述简单示例中的“密钥到期”相同吗?这是因为整个值集合都与一个 TTL 绑定,无论其中有多少项?作为一个后续问题,我猜值列表中各个项目的过期方式是将值项目提升到键空间中?类似于 mapState = Map("haha_foo" -> 1, "haha_bar" -> 1)?
    • 是的,基本上这个概念就是“密钥过期”。您使用命名空间的解决方案应该可以解决问题,而且它似乎是最简单的解决方案。请问你的用例是什么?
    • 我有一个具有不止一层值的地图状态。例如Scala 中的 MapState(String -> Map(String -> List(String)))。运行一段时间后,mapstate 变得如此之大,以至于它停止了整个 Flink。我想通过向值添加一些 TTL 来清理它。另外,我想利用 Flink 提供的内置 TTL 机制,而不是编写自己的清理逻辑。这就是为什么首先提出原始问题的原因。
    • 对了,我还想确认一件事:内置的TTL机制只能清除第一层的“Value”对吧?即上例中的整个 Map(String -> List(String)) ,它不能进入​​第二层并清理 Map 的值,即 List(String) 对吗?因为 Flink 并不真正知道在一层之外存储了什么数据结构。你提到的源代码让我觉得它可以递归地遍历 mapState 中的任何层,直到它达到“Leaf”值。即上面示例中的 List(String) 。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2021-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-02
    • 2020-05-31
    • 2014-05-13
    • 1970-01-01
    相关资源
    最近更新 更多