构建下一代万亿级云原生消息架构:Apache Pulsar 在 vivo 的探索与实践( 三 )


构建下一代万亿级云原生消息架构:Apache Pulsar 在 vivo 的探索与实践
文章图片
图7.Ledger翻转示意
Ledger翻转后 , 数据才会写入新的数据目录 。 在Pulsar中 , 在满足Ledger最小翻转时间以及以下条件之一后触发Ledger翻转:已达到Ledger最大翻转时间;已达到Ledger的最大Entry数量;已达到Ledger的最大大小 。
默认值:触发ledger翻转的最小时间:managedLedgerMinLedgerRolloverTimeMinutes=10
触发ledger翻转的最长时间:managedLedgerMaxLedgerRolloverTimeMinutes=240
触发ledger翻转的最大entry数:managedLedgerMaxEntriesPerLedger=50000
触发ledger翻转的最大大小:managedLedgerMaxSizePerLedgerMbytes=2048
注意两个问题:Ledger过大:最小翻转时间是防止Ledger元数据过快增长的手段 , 但实践发现如果Topic分区流量较大 , Ledger的实际值可能远超上述设置的上限阈值 。 Ledger只有在翻转后才会创建新的Ledger , Ledger过大会导致某段时间内写入某个磁盘的数据过多 , 产生磁盘存储不均衡的问题;针对Ledger为对象的一些操作也会受到影响 , 产生无法及时卸载数据到二级存储、数据卸载时间较长、还未卸载成功但Ledger已经过期等问题 。 Ledger间不均衡:LedgerID以集群维度进行递增 。 在分区的维度 , 按照LedgerID对Ledger存储目录数进行取模的方式无法对多磁盘进行均衡写入 。 但保持Ledger间的大小一致 , 在一定程度上会对多磁盘目录的写入均衡有比较大的改善 。
总而言之 , 建议根据业务消息情况适当调整Ledger翻转参数和有针对性地增加大流量Topic分区数量 , 可以防止Ledger过大、大小不均衡的问题 。
数据过期
数据过期主要分为四个阶段:
第一阶段:未被Ack的消息Backlog消息:该段数据不会被删除
第二阶段:已经Ack的消息
第三阶段:消息保留时间检查Retention:对已经Ack的消息的保留策略 , 按保留周期和保留大小设置来保留消息
第四阶段:消息删除Deleted:超过Retenion范围的消息则被删除 。 超过rentention保留周期和保留大小的消息 , 系统会从当前已经ack消息的最新位置往前检查并获取已经过期的ledger , 将其标记删除 。
构建下一代万亿级云原生消息架构:Apache Pulsar 在 vivo 的探索与实践
文章图片
图8.消息保留时间检查与消息删除
从上述的消息阶段演化来看 , Pulsar提供了较大的消息管理空间 , 但也略显复杂 。 建议集群维护者建立简单统一的规则处理数据保留策略 , 如可以设置TTL=Retention保留周期值 。
数据删除
此处介绍数据的物理删除 。 Bookie在处理数据写入过程时 , 会将同一段时间内的数据经过排序flush到同一个EntryLog文件中 , 将索引存放在RocksDB中 。 由于多个Ledger的数据可能会同时写入同一个EntryLog , 因此EntryLog便不能被简单直接的删除 。 对此BookKeeper会启动一个GC(GarbageCollector)线程进行检查和物理删除操作 。
构建下一代万亿级云原生消息架构:Apache Pulsar 在 vivo 的探索与实践
文章图片
图9.数据物理删除流程
EntryLog维护元数据信息(EntryLogMetadata) , 该元数据记录了Ledger列表、大小与剩余有效数据比例 。
GC清理线程在每个gcWaitTime时间间隔:扫描EntryLog的元数据信息 , 对于已经没有有效数据的entrylog直接进行删除 。 判断是否满足compaction条件 , 满足compaction条件后GC线程会读取每一个Entry判断其是否过期 , 一旦过期就会丢弃 , 否则会将数据写入新的EntryLog 。
Compaction分为minorCompaction和majorCompaction , 二者区别在于阈值 。 默认情况下 , minorCompaction清理间隔1小时 , 阈值0.2;majorCompaction清理间隔24小时 , 阈值0.8 。 阈值是EntryLogFile中的剩余有效数据占比 。 minorCompactionInterval=3600minorCompactionThreshold=0.2majorCompactionThreshold=0.8majorCompactionInterval=86400