Apache Pulsar 之 TTL 与 Retention 策略

本文为原创文章,转载请注明出处,原文地址:Apache Pulsar 之 TTL 与 Retention 策略

默认情况下,Pulsar Broker 会对消息做如下处理:

  • 当消息被 consumer 确认之后,会立即执行删除操作。
  • 对于未被确认的消息会存储到 backlog 中。

但是,很多线上的生产环境下,这种默认行为并不能满足我们的生产需求,所以,Pulsar 提供了如下配置策略来覆盖这些行为:

  • Retention 策略:用户可以将 consumer 已经确认的消息保留下来
  • TTL 策略:对于未确认的消息,用户可以通过设置 TTL 来使未确认的消息到达已经确认的状态。

上述两种策略的设置都是在 namespace 的级别进行设置

Retention 策略

Retention 策略的设置提供了两种方式:

  • 消息的大小,默认值:defaultRetentionSizeInMB=0
  • 消息被保存的时间,默认值:defaultRetentionTimeInMinutes=0

我们可以在 broker.conf 中对这两项内容进行配置也可以通过命令行的形式。上文提到过,这两种策略的设置,都是在 namespace 的级别进行设置,所以当我们使用命令行配置时,使用 namespaces 来进行配置,具体如下:

root@e6df71e544ea:/pulsar# ./bin/pulsar-admin namespaces set-retention
The following options are required: --size, -s --time, -t

Set the retention policy for a namespace
Usage: set-retention [options] tenant/namespace
  Options:
  * --size, -s
       Retention size limit (eg: 10M, 16G, 3T). 0 or less than 1MB means no
       retention and -1 means infinite size retention
  * --time, -t
       Retention time in minutes (or minutes, hours, days, weeks eg: 100m, 3h, 2d,
       5w). 0 means no retention and -1 means infinite time retention

如上所示:我们可以通过 -s 或者 -t 来指定我们需要配置的大小或者时间。

当你设置 Retention 策略之后,可以通过如下命令来查看具体的信息:

$ pulsar-admin namespaces get-retention [your tenant]/[your-namespace]
{
  "retentionTimeInMinutes": 10,
  "retentionSizeInMB": 0
}

Backlog

backlog 是未被确认消息的集合,它有一个大前提是,这些消息所在的 topic 是被 broker 所持久化的,在默认情况下,用户创建的 topic 都会被持久化。换句话说,Pulsar Broker 会将所有未确认或者未处理的消息都存放到 backlog 中。

同样的,我们可以在 namespace 级别对 backlog 的大小进行配置。需要注意的是,对 backlog 进行配置时,我们需要明确以下两点:

  • 在当前的 namespace 下,每一个 topic 允许的大小是多少
  • 如果超过设定的 backlog 的阈值,将会执行哪些操作

当超过设定的 backlog 的阈值,Pulsar 提供了以下三种策略供用户选择:

Policy Action
producer_request_hold Broker 会继续提供服务,但是对于之后未确认的消息不做持久化操作
producer_exception Broker 会抛出异常,断开与 produce 的连接
consumer_backlog_eviction Broker 会删除 backlog 中之前积压的消息

你可以通过 set-backlog-quota 在 namespace 级别对 backlog 进行配置,具体如下:

root@e6df71e544ea:/pulsar# ./bin/pulsar-admin namespaces set-backlog-quota
The following options are required: -l, --limit -p, --policy

Set a backlog quota policy for a namespace
Usage: set-backlog-quota [options] tenant/namespace
  Options:
  * -l, --limit
       Size limit (eg: 10M, 16G)
  * -p, --policy
       Retention policy to enforce when the limit is reached. Valid options are:
       [producer_request_hold, producer_exception, consumer_backlog_eviction]

如上所示,set-backlog-quota 提供了两个参数,-l 用来指定你设置 backlog 的大小,-p 用来指定,当超过你设置的 backlog 的阈值之后,Broker 将会执行的策略。

当你设置 backlog 之后,可以通过如下命令,查看相应的信息:

$ pulsar-admin namespaces get-backlog-quotas [your tenant]/[your namespace]
{
  "destination_storage": {
    "limit" : 2147483648,
    "policy" : "producer_request_hold"
  }
}

如果你期望取消 backlog 的配置,可以使用如下命令:

$ pulsar-admin namespaces remove-backlog-quota [your tenant]/[your namespace]

当有消息积压时,你可以通过 clear-backlog 来清除积压的消息。清除 backlog 中积压的消息是相对危险的操作,所以系统会提示你,是否确认要删除 backlog 中的消息, clear-backlog 提供了 -f(--force) 的参数来屏蔽该提示。

$ pulsar-admin namespaces clear-backlog [your tenant]/[your namespace]

Time To Live (TTL)

默认情况下,Pulsar 会持久化所有未被确认的消息。如果未被确认的消息有很多,这种策略会造成大量的消息被积压,导致磁盘空间增大。有些场景下,消息并不需要被持久化,用户更期望的行为是,将这些未被确认的消息直接丢弃。这种情况下,你可以通过设置 TTL 使得未被确认的消息进入到被确认的状态,当超过设定的 TTL 时间之后,配合相应的 Retention 策略将消息丢弃。

TTL 的一个典型使用场景是,当 consumer 由于某些原因出现故障,不能正常消费消息,这时 producer 还在不断的往 topic 中生产消息,会造成 topic 中有大量的未确认的消息出现,这时你可以通过设置 TTL 将这些未确认的消息变为已确认的状态。

同样的,你可以在 namesapce 级别下,通过指定 set-message-ttl 对 TTL 进行设置,具体命令如下:

root@e6df71e544ea:/pulsar# ./bin/pulsar-admin namespaces set-message-ttl
The following option is required: --messageTTL, -ttl

Set Message TTL for a namespace
Usage: set-message-ttl [options] tenant/namespace
  Options:
  * --messageTTL, -ttl
       Message TTL in seconds
       Default: 0

如上所示,set-message-ttl 只有一个参数 -ttl,单位为秒,默认值为 0。

当你设置 TTL 策略之后,可以通过 get-message-ttl 查看相应的配置信息,具体如下:

$ pulsar-admin namespaces get-message-ttl [your tenant]/[your namespace]

60

TTL、Backlog 与 Retention 的区别和联系

在上述的描述过程中,可以发现,TTL 只去处理一件事情,将未被确认的消息变为被确认的状态,TTL 本身不会去涉及相应的删除操作,具体如下图所示:

TTL.png
  1. T1 阶段,m1-m5 这 5 条消息被确认,m6-m10 这 5 条消息未被确认
  2. T2 阶段,对 m6、m7、m8 这三条消息设置 TTL 策略
  3. T3 阶段,到达 TTL 设定的阈值,m6、m7、m8 这三条消息被确认

通过上图可以看到,对于 backlog 中未被确认的消息,当你设置 TTL 之后,会将未确认消息的状态变为确认的状态。TTL 在这里所起到的作用就是将消息的 cursor 从 m5 移动到 m8,m6、m7、m8 这三条消息变为已确认状态。

Pulsar 是一个 multiple-subscription 的消息系统,对于 topic 中的一条消息,只有当所有订阅者都对这条消息 ack 或者消费了,它才能被删除。

默认情况下,Pulsar Broker 会将所有未确认的消息持久化到 backlog 中。TTL 的功能是,你可以将这些未被确认的消息变为被确认的状态,而 Retention 所关注的点是,当消息处于被确认的状态时,你可以对已确认的消息进行的保留策略是什么。换句话说,backlog 是针对未确认的消息,Broker 所做的处理是什么。Retention 是针对已确认的消息,Broker 所做的保留策略是什么。

TTL 与死信队列

死信队列的相关介绍在此不做赘述。

在生产环境中,有时可能遇到质量差的数据是由于上游的原因导致的,必须由上游来解决,继续尝试处理其它的消息已经没有意义,这时候用户希望在发生错误时立即停止处理。Pulsar 中提供了一种特殊的 Topic——死信队列。

死信队列与 TTL 都可以将未确认的消息变为已确认的状态。他们之间主要的不同在于,在上图中的 T2 阶段,TTL 只是将未确认的消息变为已确认的状态,死信队列的做法是将消息丢弃到死信队列中,m6、m7、m8 这三条消息变为被确认的状态。m9、m10 这两条有效消息会正常处理,Broker 也会继续运行。之后,你可以从死信队列中检查无效消息,并根据需要忽略或修复并重新处理。用户可以根据自己的需求来确定未确认的消息是通过 TTL 的形式将其变为确认状态还是通过死信队列的方式来实现,依据的主要标准就是看你需不要处理消费不了的消息。

使用问题

场景一:

启动 producer 往 Broker 发送消息,设置了 TTL ,没有启动 consumer,同时设置了 Retention 策略为半小时,到达 retention 的阈值之后,发现设置 TTL 的消息并没有被移除,这是为什么呢?

在上述场景中,有一个问题需要注意,没有启动 consumer,在上面我们说到,TTL 是将消息设置的 cousor 向前移动,如果没有启动 consumer,相当于 cousor 没有被初始化,也就是如果没有 consumer,你就没有必要去设置 TTL。

场景二:

我设置了retention 策略,但是到达了 retention 的阈值,topic 中的数据并没有被删除掉,这是为什么呢?

这个是 pulsar 内部的一个实现机制,在 pulsar 中 topic 是一个逻辑的概念,一个 topic 对应一个 manage ledger,当你写数据的时候,实际上是将数据写到了 ledger 中,还记得在之前很多文章中提到的有关 pulsar 设计的一个核心所在:在 pulsar 中,所有的操作都是异步的,所以当 retention 到达指定阈值之后,是否删除对应 ledger 中的数据,这个操作也是异步的。delete 的操作是不会对当前 active 的 ledger 执行的。只有当数据写满了当前的 ledger ,ledger 发生切换时,才会去真正的执行 retention 策略。

如果想要强制执行,可以使用 pulsar-admin 将当前的 ledger 强制卸载,迫使其发生 ledger 的切换。

如果您有关于此类似的问题,欢迎下方留言进行交流

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,607评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,047评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,496评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,405评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,400评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,479评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,883评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,535评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,743评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,544评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,612评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,309评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,881评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,891评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,136评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,783评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,316评论 2 342

推荐阅读更多精彩内容