本文原文作者是 StreamNative 工程师陈航、刘昱。

关于 Apache Pulsar

Apache Pulsar 是 Apache 软件基金会顶级项目,是下一代云原生分布式消息流平台,集消息、存储、轻量化函数式计算为一体,采用计算与存储分离架构设计,支持多租户、持久化存储、多机房跨区域数据复制,具有强一致性、高吞吐、低延时及高可扩展性等流数据存储特性。 GitHub 地址:http://github.com/apache/pulsar/

近期,Apache Pulsar 社区发布了 Pulsar 2.8.1 版本!新版本涵盖 49 位贡献者提供的改进和错误修复,并提交了 213 次变更。

版本亮点

•在重复打开和关闭消费者时,key-shared 订阅不再停止向消费者发送消息。 •系统 topic 在未配置为压缩时,不再有潜在的数据丢失。 •消费者不得读取未订阅 topic 的数据。

本博客介绍了 2.8.1 版本最值得关注的进展,如需了解所有性能升级和 bug 修复的完整列表,请查阅 Pulsar 2.8.1 发布注记[1] 。

Bug 修复和性能升级

Broker

•PR-11446[2]:精确发布速率限制按预期生效。 

问题:在此 PR 之前,在 topic 上设置精确的发布速率限制无效。 

解决方案:通过 LeakingBucket​ 和 FixedWindow​ 算法实现了新的 RateLimiter。

•PR-10762[3]:具有相同 key 的消息将传递给 Key-shared 订阅上的正确消费者。 

问题:当在 Key-shared 订阅上发生消息重新传递时,具有相同 key 的消息是乱序的。 

解决方案:当向 messagesToRedeliver​ 发送消息时,broker 保存了 key 的哈希值。如果调度程序尝试将更新的消息发送给有与任何一个保存的哈希值对应的 key 的消费者,它们将被添加到 messagesToRedeliver 而不是被发送,防止具有相同 key 的消息出现乱序。 

•PR-11804[4]:不再从 topic map 中删除具有相同名称的活跃生产者。 

问题:在此 PR 之前,即使旧的生产者仍在写入 topic,同名的生产者会触发错误并删除旧生产者。 

解决方案: 基于连接 ID(本地和远程地址以及独有的 ID)和该连接中的生产者 ID 而非生产者名称验证生产者。

•PR-11737[5]:当生产者继续重新连接到 broker 时,可以恢复处于隔离状态的 topic。 

问题:在此 PR 之前,当生产者继续重新连接到 broker 时,topic 的隔离状态始终设置为 true,这导致 topic 无法恢复。 

解决方案:当轮询操作不等于当前操作时,向 ManagedLedgerException 添加一条 entry。

•PR-11547[6]:Topic 正确初始化游标以防止数据丢失。 

问题:在此 PR 之前,当订阅位置最早的 topic 时会丢失数据,因为 ManagedLedger 使用了错误的位置来初始化游标。 

解决方案:订阅最早位置的 topic 时,添加检查游标位置的测试。

•PR-11183[7]:使用 hasMessageAvailableAsync​ 和 readNextAsync 时不再发生死锁。 

问题:在此 PR 之前,将消息添加到传入队列时,在两种情况下可能会发生死锁:首先,在读取消息之前将消息添加到队列中。其次,readNextAsync​ 在调用 future.whenComplete 之前完成。 

解决方案:使用内部线程处理 hasMessageAvailableAsync 的回调。

•PR-10977[8]:调用 getLastMessageId API 时不会发生内存泄漏。 

问题:在此 PR 之前,调用 getLastMessageId API 时 broker 会耗尽内存。 

解决方案:将 entry.release()​ 调用添加到 PersistentTopic.getLastMessageId。

•PR-10941[9]:为系统 topic 触发压缩。     问题:在此 PR 之前,当一个 topic 只有非持久订阅时,不会触发压缩,因为其估测 backlog 大小为 0。 

解决方案:使用总 backlog 大小来触发压缩。在没有持久订阅的情况下更改行为以使用总backlog大小。

•PR-10920[10]: 重复打开和关闭消费者时,Key-shared 订阅不再停止向消费者发送消息。 

问题:使用 Key-Shared 订阅反复打开和关闭消费者偶尔会导致停止向所有消费者发送消息 

解决方案:在调用 removeConsumer() 之前移动了标记删除位置,并从选择器中移除消费者。

•PR-11912[11]:消费者不得读取未订阅 topic 的数据。 

问题:在此 PR 之前,未检查请求 ledger 是否属于消费者连接的 topic,使得消费者读取不属于连接 topic 的数据。 

解决方案:在执行读取操作之前,添加对 ManagedLedger 级别的检查。

Topic Policy

•PR-11021[12]:保留策略实现预期。 

问题:在此 PR 之前,因未在 managedLedgerconfiguration 中设置,保留策略不起作用。 

解决方案:将 managedLedger​ 配置中的保留策略设置为 onUpdate 监听 listner 方法。

•PR-11003[13]:系统 topic 在未配置为压缩时不再有潜在的数据丢失。 

问题:在此 PR 之前,如果未持久订阅 topic,可能会丢失数据。 

解决方案:利用 topic 压缩游标来保留数据。

Proxy

•PR-11848[14]:Pulsar proxy 正确关闭出站连接。 

问题:在此 PR 之前,Pulsar proxy 传出 TCP 连接存在内存泄漏的问题。因为 ProxyConnectionPool​ 实例是在 PulsarClientImpl实例之外创建的,并且在客户端关闭时并未关闭。 

解决方案:正确关闭 ConnectionPool。

Function

•PR-11709[15]:Pulsar Functions 支持 Protobuf schema。 

问题:在此 PR 之前,使用 Protobuf schema 时抛出的异常 GeneratedMessageV3 不可分配。 

解决方案:向 Pulsar 实例添加相关依赖。

Client

•PR-11754[16]:分区 topic 消费者在失败后清理资源。 

问题:在此 PR 之前,分区 topic 消费者在创建消费者失败时不清理资源。如果此故障与不可恢复的错误一起发生,则会引发内存泄漏,从而使应用程序不稳定。 

解决方案:关闭和清理计时器任务引用。

•PR-11764[17]:多 topic 消费者不会发生竞争条件。 

问题:在此 PR 之前,当有独立消费者处于“暂停”状态且共享队列已满时,2 个线程之间存在竞争条件。 

解决方案:在将消费者标记为“暂停”后验证共享队列的状态。如果另一个线程在此期间清空队列,则消费者不会被阻塞。

•PR-11691[18]:消费者不会在 batchReceive 上被阻止。 

问题:在此 PR 之前,由于 ConsumerBase.java​ 中的竞争条件,当不同线程同时调用 Consumer.batchReceive() 时,消费者被阻塞。 

解决方案:将 pinnedInternalExecutor​ 置于 ConsumerBase​ 中,以允许批处理计时器、ConsumerImpl​ 和 MultiTopicsConsumerImpl 在单个线程中提交工作。

•PR-11882[19]:Python 客户端正确启用自定义日志记录。 

问题:在此 PR 之前,在 Python 客户端中启用自定义日志记录时可能会发生死锁。 

解决方案:分离工作线程并降低日志级别。

参与其中

新版本使用

欢迎大家下载[20]并使用新版本!如果在使用中遇到问题,可以通过提 issue[21] 或在微信群交流的方式抛出疑问并与社区交流。

加入 Apache Pulsar 社区

Pulsar 项目的成长来源于社区,也扎根于社区。一次次新版本的筹备与发布离不开社区伙伴们的贡献。你是否愿意成为其中的一员呢?参与开源,可以获得公司及社区内外的认可,结交来自各个领域、志同道合的小伙伴;同时也可以提高个人影响力,促进个人发展。参与开源不是码农的专属,社区、文档等各个方面都可以让大家发挥一技之长。 

作为全球性开源项目,截至目前,Apache Pulsar 已拥有 451 名贡献者、9.7 K+ Star 、2.4 K+ Fork 。我们为大家提供了参与指南,欢迎越来越多的小伙伴助力 Apache Pulsar 项目的不断发展与前进。

•Apache Pulsar 官方贡献指南[22]•加入 Apache Pulsar 志愿者大家庭


引用链接

[1]​ Pulsar 2.8.1 发布注记: https://pulsar.apache.org/release-notes/#281-mdash-2021-09-10-a-id281a

[2]​ PR-11446: https://github.com/apache/pulsar/pull/11446

[3]​ PR-10762: https://github.com/apache/pulsar/pull/10762

[4]​ PR-11804: https://github.com/apache/pulsar/pull/11804

[5]​ PR-11737: https://github.com/apache/pulsar/pull/11737

[6]​ PR-11547: https://github.com/apache/pulsar/pull/11547

[7]​ PR-11183: https://github.com/apache/pulsar/pull/11183

[8]​ PR-10977: https://github.com/apache/pulsar/pull/10977

[9]​ PR-10941: https://github.com/apache/pulsar/pull/10941

[10]​ PR-10920: https://github.com/apache/pulsar/pull/10920

[11]​ PR-11912: https://github.com/apache/pulsar/pull/11912

[12]​ PR-11021: https://github.com/apache/pulsar/pull/11021

[13]​ PR-11003: https://github.com/apache/pulsar/pull/11003

[14]​ PR-11848: https://github.com/apache/pulsar/pull/11848

[15]​ PR-11709: https://github.com/apache/pulsar/pull/11709

[16]​ PR-11754: https://github.com/apache/pulsar/pull/11754

[17]​ PR-11764: https://github.com/apache/pulsar/pull/11764

[18]​ PR-11691: https://github.com/apache/pulsar/pull/11691

[19]​ PR-11882: https://github.com/apache/pulsar/pull/11882

[20]​ 下载: https://pulsar.apache.org/en/download/

[21]​ issue: https://github.com/apache/pulsar/issues

[22]​ Apache Pulsar 官方贡献指南: http://pulsar.apache.org/en/contributing/

项目动态|Apache Pulsar 2.8.1 版本发布_python