作者:Anshul Singh,译者:傅腾

注:为了行为顺畅,有部分调整。翻译不易,有任何问题,都可以小窗公众号私信,或者直接联系 Pulsar Bot  :)

这是一篇对 Apache  Pulsar  集群做调优的指南。

Apache  Pulsar 是一个开源的、分布式的消息和事件流平台,旨在实现高性能、可扩展性和可靠性。它是数据流处理方案 Apache Kafka 的一个替代方案,但具有许多内置的重要功能,如支持多租户、水平扩展和地理复制。

在 Flipkart 中,许多微服务使用  Pulsar  集群来处理各种流式和批处理用例。所有用户事件、订单事件(点击产品、添加到购物车、下订单等)、推荐、广告促销、支付对账等都会产生大量数据。我们必须优化处理所有这些用例的 Pulsar 集群,以实现性能优化,并不受非功能性阻塞因素的影响(如亚毫秒级消息处理支持、持久性和可用性)。这也是一篇解释我们如何管理故障容错和高可用性的文章。

在这篇博客文章中,我们将探讨一些关键的考虑因素和高效的方法来调优 Pulsar 集群,再保障性能的同时还能确保高可用性。

我们从 Pulsar 中想要什么?

Pulsar  完美适用于发布-订阅模型事件驱动架构实时数据处理作为微服务通信通道。调整集群配置以更好地支持这些要求并更好地利用资源是很重要的。以下是一些相对于默认配置可以尝试改进的方面:

  • 更好的吞吐量和 Ops
  • 实时处理的延迟更低
  • 可扩展性和可维护性
  • 容错性和弹性

以下是我们在优化 Pulsar 集群后能够实现的一些结果。

  • 3+ Gbps 吞吐量
  • 生产延迟(p999)< 50毫秒
  • 高扇出(fanout)支持(单个主题上的订阅量超过1000个)
  • 支持 50K 个活跃 Topic

这一切都在一个 Pulsar 集群中处理。令人兴奋,对吧?

Pulsar  架构一览

这是关于 Pulsar  基本架构的参考链接:https://Pulsar.apache.org/docs/3.0.x/concepts-architecture-overview/



技术探究 | Flipkart 带来 Apache Pulsar 集群调优指南_缓存

Pulsar  基本架构

我们可以将组件分为以下几个部分:

Pulsar  Cluster

  • Broker :处理层,负责管理和提供主题。它还处理消息、路由和与 Pulsar 客户端的连接。
  • bookkeeper :存储层支持持久化消息存储、数据持久化以及数据在多个存储节点之间的复制。这使得集群具有弹性。
  • Zookeeper:协调层,还负责管理 Pulsar 集群中的元数据和配置的策略。

Pulsar  Client

  • 生产者(Producer):将消息发布到 Pulsar 的主题(流)中
  • 消费者(Consumer):订阅 Pulsar 主题的接收者

让我们看看在 Flipkart 中如何对各个组件做卓有成效的优化。

调优 Pulsar 集群的方法论

我们会对集群进行多种类型的负载测试,如红线测试(redline tests)、浸泡测试(soak tests)等,以验证系统在生产负载下在扩展性、速度和整体稳定性方面的表现是否良好。

我们遵循以下过程进行调优:



技术探究 | Flipkart 带来 Apache Pulsar 集群调优指南_apache_02

调优 Pulsar 集群的方法论

  1. 基准线:使用当前的设置和配置建立一个基准线。这是评估调优变化影响的参考点。
  2. 捕获指标:记录用于参考的指标。工具https://github.com/lawrenceching/metricdump可以提供用于后续比较和记录的指标。需要捕获的一些重要指标(后文附)。
  3. 识别瓶颈:监控 broker/bookie/zookeeper的dashboards,以识别瓶颈(包括CPU/MEM资源利用率、N/W带宽、应用配置、存储I/O、元数据存储性能、身份验证/授权开销等)。除了上述记录的指标外,还可以查看Topic 的statsstats internal。更多详细信息:https://Pulsar.apache.org/docs/next/administration-stats/
  4. 监控假设性变化:针对瓶颈的原因提出一个假设,并在出现任何困惑的情况下查看  Pulsar  代码库。尝试通过配置或部署更改来解决这些问题。
  5. 测试工作负载:再次测试相同的工作负载,以进行公平比较,计算变化的影响。
  6. 比较结果:将结果与之前创建的基准进行比较。如果结果是有利的,则接受它。
  7. 重复 :)

重点指标

  1. JVM指标 [jvm_*]:用于观察资源使用情况、GC暂停情况等。
  2. Broker managedLedgerCache指标 [Pulsar_ml_cache_*] 和 bookkeeper  读/写缓存指标 [bookie_write_cache_*, bookie_read_cache_*] 
  3. Broker Loadbalancer指标 [Pulsar_lb_*] 
  4. 延迟相关指标:
  1. 客户观察到的。
  2. Broker 发布延迟 [Pulsar_broker_publish_latency] 
  3. Broker 观察到的写入延迟 [Pulsar_storage_ledger_write_latency_*Pulsar_storage_write_latency_*] 
  4. bookkeeper  观察到的延迟(journal, ledger read/write 延迟)
  5. PV持久卷指标和实际磁盘延迟
  6. 工作负载(吞吐量进/出,速率进/出,主题/订阅数量,产生的积压等)。有关其他指标的详细信息,请参阅:https://Pulsar.apache.org/docs/next/reference-metrics/

按组件调优

现在让我们来看看每个组件的关键调优点是什么,以及它们如何影响整体的行为。

Broker

调优 Pulsar  brokers 需要调整许多配置。让我们来看一下其中几个重要的配置。



技术探究 | Flipkart 带来 Apache Pulsar 集群调优指南_客户端_03

Pulsar  Cluster architecture

我们在Broker中的主要优化是:

  • Managed Ledger 的策略和缓存
  • 负载均衡和 Bundle  配置
  • 限流
  • JVM GC 调优

Managed Ledger

Managed Ledger 是存储主题消息的底层数据结构。

Managed Ledger 策略(EnsembleSize, WriteQuorum, AckQuorum)

不同的使用场景有不同的数据存储策略,主要可分为:

  • 易失性(Volatile/in-memory):数据主要存储在内存中,不会持久化到磁盘。
  • 软持久性(Soft/async disk write):数据异步写入磁盘。
  • 强持久性(Hard/sync disk write):数据同步写入磁盘。

如何在数据持久性(durability)和延迟(latency)之间做出权衡?

耐久性越强,延迟影响越大。在 Pulsar 中,有许多配置的组合(包括控制持久性的 bookkeeper  配置,journal/ledger 如何接受请求,延迟写入等)。我们在 brokers 中配置的一个这样的配置是(EnsembleSize,WriteQuorum和AckQuorum)的三元组。

这个三元组(EnsembleSize、WriteQuorum和AckQuorum)是什么?

这个三元组控制 Broker 如何使用 bookkeeper  集群。它告诉 bookkeeper  客户端有关数据副本数量以及何时在 bookkeeper  集群中考虑成功的持久写入。

  • EnsembleSize定义了在 Ledger 中存储消息时要考虑的 bookies 数量。我们可以使用 managedLedgerDefaultEnsembleSize 配置来更改此大小,默认为2。
  • WriteQuorum定义了在 Ledger 中存储消息的复制因子。我们可以使用 managedLedgerDefaultWriteQuorum 配置来更改此值,默认值为2。
  • AckQuorum定义了从 bookies   需要的最小确认数量,以将消息确认为“已持久化”。

控制保证副本的数量:我们可以通过 managedLedgerDefaultAckQuorum 配置来控制所需的确认数量,默认情况下为 2。

以下是一些有帮助的场景示例,可以帮助您更好地理解调优要求:

  • 强持久化场景:为了提供持久性和容错性,常见的组合是将 AckQuorum 和 WriteQuorum 设置为相同,并且 EnsembleSize 大于或等于 WriteQuorum。这确保每个写操作都得到了最少数量的 bookies  的确认,并在足够数量的节点上进行了复制。

技术探究 | Flipkart 带来 Apache Pulsar 集群调优指南_客户端_04


强持久化场景

  • 低的延迟场景:为了在一定程度上牺牲持久性以实现较低的延迟,我们可以将“AckQuorum”和“WriteQuorum”设置为较低的值,相对于“Ensemble size”来说。较低的“AckQuorum”可以实现更快的确认,而“EnsembleSize”可以根据容错需求进行调整。

技术探究 | Flipkart 带来 Apache Pulsar 集群调优指南_调优_05

低的延迟场景

  • 定制持久化和性能:根据具体使用情况,我们可以定制化 AckQuorum、WriteQuorum 和 EnsembleSize,以在持久化、性能和资源利用之间取得平衡。这需要仔细考虑诸如消息重要性、预期工作负载、期望的容错能力和可用资源等因素。

技术探究 | Flipkart 带来 Apache Pulsar 集群调优指南_缓存_06

定制持久化和性能

Managed Ledger 缓存

Broker 在 Pulsar 客户端和存储层( bookkeeper  集群)之间管理了一个缓存层。如果要求消费消息的实时性,重要的是调优 Broker 中的缓存属性,以减少对 bookkeeper 磁盘的读取。

缓存负责存储由 Broker 管理的 Ledger 中的主题中的尾部消息,称为 Managed Ledger 缓存。在当前 Broker 的实现中(直到v2.11),这将占用 Broker 分配到的JVM直接内存(direct memory)。

如果工作负载是可预先确定的,在考虑到集群的整体内存消耗后,可以为缓存分配额外的内存,以支持实时场景的使用。

我们可以使用 Pulsar_ml_cache_*指标来观察缓存命中率。如果缓存命中率较低,增加内存可以帮助改善。

下图显示了针对实时消费者错误的缓存调优示例,其中缓存命中率降至0.6,反而增加了对 bookkeeper  的读取请求。



技术探究 | Flipkart 带来 Apache Pulsar 集群调优指南_apache_07

错误的缓存调优示例

以下示例展示了一个良好的缓存调优,其中缓存命中率保持在 > 0.95,适用于实时使用。



技术探究 | Flipkart 带来 Apache Pulsar 集群调优指南_调优_08

良好的缓存调优

以下的Broker 配置可以用来调优 managedLedgerCache 的性能:

  • managedLedgerCacheSizeMB=配置用于缓存 Ledger 元数据和索引条目的缓存大小。增加缓存大小可以通过减少磁盘I/O来提高读取性能。默认情况下,它占用可用直接内存的1/5。
  • managedLedgerCacheCopyEntries=false指定在将条目有效载荷插入缓存时是否制作副本。
  • managedLedgerCacheEvictionWatermark=0.9当触发驱逐时,将缓存级别降低到此阈值。其浮点值为[0-1]。0.9表示驱逐缓存的10%。
  • managedLedgerCacheEvictionIntervalMs=10调整managed Ledger 缓存清理频率。
  • managedLedgerCacheEvictionTimeThresholdMillis=1000指定条目在被驱逐之前可以在缓存中保留的时间长度。
  • managedLedgerMaxEntriesPerLedger=50000指定在创建新的 Ledger 之前,单个 Ledger 中存储的最大条目(消息)数量。该属性会影响每个 Ledger 文件的大小,并且与硬件相关。

负载均衡和 Bundle  配置

在 Pulsar 中,主题在命名空间还有一层逻辑分组。这些主题在物理上被分组并称为 bundles。因此,一个命名空间可以有多个 bundles,一个 bundles 可以有多个主题。brokers 获取 bundles 的所有权而不是每个主题的所有权。这有助于负载均衡。

当一个 Bundle  变得过大或接收到大量的传入消息时,它会被分割成多个较小的 Bundle  或子 Bundle 。Bundle 的分割和负载均衡密切相关,因为 Bundle  分割的过程有助于负载均衡。然后,这些子 Bundle  可以以负载均衡的方式分布在 Broker 之间。所有这些都是基于 Broker 的负载和可用资源动态发生的。

当一个 Bundle 被拆分时,为了做出有根据的负载均衡决策,负载均衡器考虑以下因素:

  • 每个 brokers 的当前负载和 bundles 分布
  • 活跃的生产者和消费者数量
  • 消息吞吐量
  • 资源利用

负载均衡器可以将 bundles 重新分配给负载较低的 brokers ,以确保负载的整体均衡分布。

当我们正确调整 Bundle  拆分和负载均衡时,资源利用率在负载下将达到最佳状态。这还有助于防止集群中出现任何热点,并允许在分布式环境中进行可扩展和高效的消息处理。

这是一个例子,其中一个 Broker 有一个热点和瓶颈。



技术探究 | Flipkart 带来 Apache Pulsar 集群调优指南_客户端_09

Before making any changes to LB and bundle configuration

上图显示了在对负载均衡器和 Bundle  配置进行更改之前的延迟。



技术探究 | Flipkart 带来 Apache Pulsar 集群调优指南_客户端_10

After moving to UniformLoadShedder from ThresholdShedder as it supports our use case better.

在将负载均衡算法从 ThresholdShedder LB 算法更改为 UniformLoadShedder LB 算法后,由于它更适合我们的使用情况。

通过新的配置,每个 Broker 处理的 Bundle  数量大致相同,而之前的情况并非如此,因为一个 Broker 处理的 Bundle  数量是另一个 Broker 的3倍,导致延迟较高,出现瓶颈。

有关 bundle 和负载均衡属性的更多信息,请参阅 Pulsar 文档:https://Pulsar.apache.org/docs/3.0.x/administration-load-balance/

限流

限流允许您调节消息的流量,防止过载情况并保持系统稳定。在生产端和消费端都对客户端进行限流非常重要,因为一个表现不佳的客户端(生产或消费的QPS/吞吐量非常高)可能导致整个集群的性能下降。

相关情景:

  • 系统稳定性:如果生产者或消费者突然产生大量的流量,可能对资源的使用超出预期(CPU、内存、磁盘IOPS、网络带宽、高GC等),导致 Pulsar 集群拥堵和潜在的服务中断。
  • 防止背压:限流作为一种机制,对消息流应用背压。当特定组件(如消费者)无法跟上消息的生产速率时,它可以请求减慢消息的消费速率。这样可以防止消息积压和潜在的数据丢失,确保系统在其容量限制内运行。

可以使用集群配置或资源策略在不同层级上应用限流。

  • broker 级别:在 Broker 配置中,dispatchThrottlingRate*配置可以用于限制发送给消费者的吞吐量,并主动防止任何突然的消息峰值导致系统不稳定。
  • 主题级别:可以使用 Pulsar 管理命令设置命名空间策略,以对该命名空间内的所有主题应用速率限制。参考:https://Pulsar.apache.org/docs/next/admin-api-namespaces/#configure-dispatch-throttling-for-topics
  • 订阅级别:同样,可以使用命名空间策略来限制命名空间下主题的所有订阅。可以使用 Pulsar 管理命令来应用相同的策略。参考:https://Pulsar.apache.org/docs/next/admin-api-namespaces/#configure-dispatch-throttling-for-subscription

示例:

  • 限制客户端之前

技术探究 | Flipkart 带来 Apache Pulsar 集群调优指南_客户端_11

限制客户端之前 Max

技术探究 | Flipkart 带来 Apache Pulsar 集群调优指南_缓存_12


限制客户端之前 999pct


  • 限制客户端之后

技术探究 | Flipkart 带来 Apache Pulsar 集群调优指南_调优_13

限制客户端之后 Max

技术探究 | Flipkart 带来 Apache Pulsar 集群调优指南_apache_14

限制客户端之后 999 pct

在上述运行中,超过 100 个 Open Messaging Benchmark 客户端运行以消除可能存在的客户端瓶颈。这么多的客户端能够通过发出过多的请求轻松地降低集群的性能。

发布延迟上的尖峰表示消费者拉取消息以更快速度清除积压,超过了允许的限制,导致延迟恶化。应用调度速率限制器后,延迟尖峰得到了减少。

Pulsar 提供了两种类型的速率限制器——基于轮询和精确速率限制器。在集群中应用严格的限流规则后,使用精确速率限制器可以将上述延迟限制在不超过200毫秒的范围内。要启用它,请将 preciseTopicPublishRateLimiterEnable 标志设置为 True。

其他优化

JVM GC调优

  • GC算法:Pulsar 中的默认算法是 G1GC,适用于大多数用例。然而,我们建议尝试不同的 GC 算法。例如,对于低延迟的 GC,ZGC 是一个很好的算法,但与G1GC相比,它使用更多的CPU周期。
  • 堆(Heap)大小:堆大小过小会导致 GC 暂停的频率非常高,而堆大小过大会导致巨大的 GC 暂停时间,从而增加延迟峰值。为了计算出最佳的堆大小,可以先猜测初始内存使用量,然后从那里进行调整,观察对堆大小影响最小的情况。
  • 性能分析(Profiling):为了优化垃圾回收(GC),更好地对应用程序进行性能分析,了解内存使用模式,并使用GC日志观察 GC 行为。在负载下进行内存分析可以清楚地了解内存使用模式。

GC 调优是一个独立的话题,这是另一个时间的讨论,但我会分享一个有用的观点,在生产环境中,当为 broker/bookie/zookeeper 进程分配了专用内存时,将 xmxxms 设置为相同的值。

参考:https://developer.jboss.org/thread/149559[1]

Bookkeeper

Bookkeeper 将消息存储为 Ledger 中的条目。这些 Ledger 被映射到称为 managedLedgers 的特定主题。关于提高 bookkeeper 集群性能或支持特定类型的工作负载的一些因素如下:

Journal磁盘

在将消息存储到 Ledger 之前,消息会被追加到 journal 日志中,当 journal 日志文件大小达到或翻转(rollover)周期完成时,消息将被移动到 Ledger 中。Journal 日志和 Ledger 的磁盘在决定集群性能方面起着同样重要的作用。

我们建议将 journal 日志保存在更快的磁盘上,以在集群中获得最佳性能,因为所有的消息都首先到达 journal 日志。存储成功后,它会向 brokers 发送确认。

bookkeeper   配置journalSyncData决定了在数据被同步到 journal 日志磁盘或存储在内存中时是否发送确认。将其设置为“false”意味着存在数据丢失的可能性,因为journal日志条目被写入操作系统页面缓存但未刷新到磁盘。在断电的情况下,受影响的 bookkeeper  可能会丢失未刷新的数据。

将journal日志和ledger数据移动到更好的磁盘(SSD/NVME)上有助于实现更低的延迟和更好的 bookkeeper  集群性能,但成本更高。



技术探究 | Flipkart 带来 Apache Pulsar 集群调优指南_缓存_15

写入流程

决定 bookie 配置,您需要回答几个基本问题:

我需要 journal  吗?

Journal 具有较低的发布延迟,同时不影响持久化。当 journal 中的写操作成功时, bookkeeper  仅向 bookkeeper  客户(即 Broker )发送确认。拥有独立的 journal 和 ledger 还有助于提高 bookkeeper  节点的可扩展性。我们可以在 bookkeeper  配置中使用journalWriteData标志来启用 journal 记录(默认启用)。

Ledger 可以进行延迟写入,而 journal 日志可以存储消息以保持操作的原子性和一致性。我们建议将journal日志磁盘放在比 Ledger 磁盘更高速的磁盘上。当消息存储在 ledger 中时,journal 日志磁盘会释放那些条目,因此可以使用较小的 journal 日志磁盘。

每个 bookie 节点需要多少个 Ledger ?

bookkeeper  将消息存储为ledger文件中的一个 entry。在 Pulsar 中,我们可以使用ledgerDirectories  bookkeeper  配置来配置 ledger 目录的数量。这些ledger 目录可以位于不同的磁盘上,以减少在一个设备上发生的随机 IO 引起的延迟峰值。Ledger 磁盘可以采用更便宜的 HDD,因此IOPS非常有限。拥有多个磁盘可以减少瓶颈。

你是否想知道为什么 Ledger 虽然与生产流程没有直接关系,却如此重要?原因很简单。如果已经加载了,它们可以对 journal 日志产生反压力。然而,在已加载的 Ledger 中,增加 Ledger 的 IOPS 限制或迁移到更好的磁盘有助于缓解这个瓶颈。

Journal日志配置

调整 journal 日志很容易。只需要注意以下重要的配置项:

journalBufferedWritesThreshold

确定触发将缓冲写入刷新到磁盘的数量。默认值为64,意味着当累积了64个缓冲写入时,它们将被刷新并写入磁盘上的 journal 日志。刷新写入可以确保在系统故障时消息的持久性和耐久性。

journalMaxGroupWaitMSec

确定缓冲写入在刷新到磁盘之前可以等待的最长时间。它指定写入在写入 journal 日志之前在内存中保留的持续时间。默认值为1毫秒,确保及时持久性写入。该参数平衡性能和耐久性,将写入作为一组刷新可以优化磁盘 I/O 操作。最佳值取决于许多因素,包括系统需要多少耐久性,资源利用率等。

journalWriteBufferSizeKB

确定用于将消息写入 journal 日志的缓冲区的大小。默认情况下,它设置为4 MB。该缓冲区在将消息写入磁盘上的 journal 日志之前,临时将消息保存在内存中。缓冲区的目的是优化磁盘 I/O 操作并提高写入效率。增加缓冲区大小可以增强写入吞吐量,但也会增加内存使用量。适当的值取决于消息负载、期望的性能、内存资源和磁盘能力,我们可以调整它以实现性能和资源利用之间的平衡。

参考:bookkeeper   配置 https://github.com/apache/Pulsar/blob/master/conf/bookkeeper.conf

注意:调整 journalBufferedWritesThresholdjournalMaxGroupWaitMSec 会影响写入延迟和持久性,较低的值会增加持久性但可能影响性能,较高的值会提高吞吐量但可能延迟磁盘持久性。

Zookeeper

将 zookeeper 的仲裁节点数量设置为适应读取操作的规模。限制 zookeeper 的操作是最佳选择,因为增加对 zookeeper 的操作可能会导致集群中的瓶颈。

导致瓶颈的一些情景包括:

  • 增加元数据(大量元数据或大量Topic变动):最好是重复使用主题,而不是频繁创建和删除主题。
  • 增加订阅数量
  • 增加QPS(导致高读写)

我们发现增加 zookeeper 节点在一定程度上有助于缓解瓶颈问题。

批量处理元数据调用

升级到 Zookeeper 3.6.0+ 有助于优化查询,因为批量提交是可用的。https://issues.apache.org/jira/browse/ZOOKEEPER-3359。Pulsar > 2.10带有此功能,因为它与 Zookeeper 3.6.3 绑定在一起。

如果配置中启用了 metadataStoreBatchingEnabled 标志, brokers 可以批量调用 zookeeper。当 brokers 进行多个zk请求时(更新 acks 上的游标信息,更新主题属性,读取在启动具有多个主题或订阅的大型应用程序时的操作等),这非常有用。该属性有助于减少批处理作业启动时的延迟峰值。



技术探究 | Flipkart 带来 Apache Pulsar 集群调优指南_调优_16

禁用元数据操作批处理

技术探究 | Flipkart 带来 Apache Pulsar 集群调优指南_apache_17

启用元数据操作批处理

上图:禁用元数据操作批处理

下图:启用元数据操作批处理

压缩

如果元数据很大,Zookeeper 很容易成为瓶颈,因为它在配置的间隔内进行快照。巨大的数据大小意味着在快照成功存储到磁盘之前,Zookeeper 将不可用。

我们可以通过减少磁盘IO来缓解这个问题,即通过启用 Zookeeper 中的压缩来增加CPU利用率。Zookeeper 支持 Gzip 和 Snappy 压缩算法。

在我们的一个使用案例中,我们有超过 100,000 个主题生成超过 2GB 的元数据。快照写入导致集群无响应,要么在生产端导致积压,要么集群大部分时间不可用。混沌测试(Chaos tests)可能会出现这个问题,其中一个随机的 zookeeper pod 重新启动,触发快照和同步。

我们选择 Snappy 是因为它对 CPU 利用率的影响较低,并且具有实时性。启用压缩后,元数据大小减小到约 200MB,这有助于更快的同步,因为写入 200MB 要快得多。

注意:压缩功能还需要升级到 Zookeeper 3.6.0+,该版本与 Pulsar 2.10+ Bundle  在一起。

参考:https://issues.apache.org/jira/browse/ZOOKEEPER-3179[2]

Pulsar  客户端

调整 Pulsar 集群后,客户端必须以优化的方式使用集群中的服务。从 Pulsar 客户端的角度考虑,为了提高性能,需要考虑一些关键配置:

  • 消息批处理:通过将多个消息合并成一个发送,可以减少单个消息发送的开销,提高整体吞吐量。要在 Pulsar 客户端中配置消息批处理,可以将batchingEnabled标志设置为true,并设置batchingMaxMessagesbatchingMaxPublishDelay参数来控制批处理大小和发送之间的最大延迟。
  • 压缩:Pulsar 支持消息压缩,可以减少需要传输的数据量,提高网络效率和整体吞吐量。为了启用压缩, Pulsar 提供了 lz4、zlib、zstd 和snappy 的compressionType选项。有时候,批处理和压缩结合在一起会导致更多的延迟,这种想法似乎与直觉相悖,但我们发现情况正好相反。较小的有效载荷大小意味着减少的IO延迟,并且与批处理结合使用可以减少往返时间(RTT),从而相比没有批处理和压缩的情况下获得更好的结果。
  • 确认类型:Pulsar 提供不同的确认模式。为了优化发送到 Pulsar 集群的确认请求的数量,使用累积确认。这可以限制发送到ZooKeeper的操作数量,有助于更好地利用资源,但有一个注意事项。我们不能在共享(shared)订阅类型中使用累积确认(这是 Pulsar 架构的限制)。
  • 接收队列:在消费者端,要处理的消息会预先获取到一个内存队列中,其大小由receiverQueueSize控制。较大的值意味着客户端可以一次拉取更多的消息,从而减少了整体的网络往返次数,但会增加内存的使用量。

结论

优化Apache Pulsar 集群包括:

  • 优化各个组件,如Broker、bookkeeper、ZooKeeper和 Pulsar 客户端
  • 选择合适的硬件
  • 根据磁盘规格实施 journal 日志和 ledger配置
  • 利用 Pulsar 客户端中的消息批处理和压缩

随着 Apache  Pulsar 的新版本添加了配置和功能,可能需要进一步调优内核参数、文件系统调优、IO 优化和网络配置以获得更好的性能。您可能需要考虑管理持久性和延迟设置、负载均衡、限流以保持稳定性,调整 JVM 垃圾回收和优化 ZooKeeper 操作。

通过 Apache  Pulsar 的所有这些努力,可以在实时数据处理应用中持续实现最佳性能和低延迟。


技术探究 | Flipkart 带来 Apache Pulsar 集群调优指南_客户端_18


加入 Apache Pulsar 社区,与全球的开发者一起学习、分享和成长,共同塑造云原生消息流平台的未来。期待在社区见到你的身影,一起为打造更加开放、高效的技术生态做出贡献!