Pulsar - 新一代消息中间件引擎

原文链接:https://www.hezebin.com/article/66ac53f04379b36dec11a19b

概述

Pulsar是一个多租户、高性能的服务器到服务器消息传递解决方案。

Pulsar的主要特点如下:

概念

Message 消息

Pulsar是建立在订阅模式(通常缩写为pub-sub)上的。在此模式中,生产者将消息发布到主题;消费者订阅这些主题,处理传入的消息,并在处理完成时将消息创建订阅后,Pulsar会保留所有消息,即使消费者断开连接也是如此。只有当使用者确认所有这些消息都已成功处理时,才会丢弃保留的消息。

publish-subscribe pattern in Pulsar

如果消息的消费失败,并且您希望再次消费该消息,则可以启用消息重新交付机制来请求代理重新发送该消息。

消息是Pulsar的基本“单位”。它们是生产者发布到主题的内容,然后消费者从主题中消费。下表列出了消息的组成部分。

组件描述
Value / data payload报文中携带的数据。所有脉冲星消息都包含原始字节,尽管消息数据也可以符合数据模式
Key消息的键(字符串类型)。它是消息键或分区键的简称。消息可以选择使用键标记,这对于主题压缩等特性很有用。
Properties用户定义属性的可选键/值映射。
Producer name生成消息的生产者的名称。如果不指定生产者名称,则使用默认名称。
Topic name消息要发布到的主题的名称。
Schema version用于生成消息的架构的版本号。
Sequence ID每个脉冲星消息都属于其主题的有序序列。消息的序列ID最初由其生产者分配,指示其在该序列中的顺序,也可以自定义。 序列ID可用于消息重复数据消除。如果brokerDeduplicationEnabled设置为true,则每个消息的序列ID在主题(未分区)或分区的生产者中是唯一的。
Message ID消息的消息ID由博彩公司在消息被持久存储后立即分配。消息ID表示消息在分类账中的特定位置,并且在Pulsar集群中是唯一的。
Publish time发布消息时的时间戳。时间戳由生产者自动应用。
Event time由应用程序附加到消息的可选时间戳。例如,应用程序在处理消息时附加一个时间戳。如果事件时间未设置任何内容,则值为0

消息的默认最大大小为5 MB。您可以使用以下配置选项配置消息的最大大小。

  • broker.conf文件中。

    # The max size of a message (in bytes).
    maxMessageSize=5242880
    
  • broker.conf文件中。

    # The max size of the netty frame (in bytes). Any messages received larger than this value are rejected. The default value is 5 MB.
    nettyMaxFrameSizeBytes=5253120
    

Pulsar中的nettyMaxFrameSizeBytesmaxMessageSize是两个与消息大小相关的配置,但它们作用的层面和目的不同。

nettyMaxFrameSizeBytes是指Netty服务器在处理客户端请求时可以接受的最大帧大小。Pulsar使用Netty作为其网络通信框架,该配置用于限制可以通过网络传输的数据帧的大小。如果客户端尝试发送超过此大小的数据帧,将会被Netty服务器拒绝,并可能返回一个错误给客户端。这个设置是为了防止客户端发送过大的数据帧,以免造成服务器的内存溢出。

maxMessageSize则是指Pulsar内部可以处理的最大消息大小。这个配置限制的是客户端可以发布到Pulsar主题的单个消息的最大大小。如果消息超过了这个大小,将会被Pulsar服务器拒绝,并且客户端会收到一个错误消息。这个限制是为了确保Pulsar集群的稳定性和可维护性。

总的来说,nettyMaxFrameSizeBytes更多地是关注网络层面上的安全和效率,而maxMessageSize则关注的是消息队列层面的数据处理能力。在配置这些参数时,需要考虑到实际的应用场景,保证Pulsar系统能有效稳定地处理大量不同大小的消息。

Ack

在消费者成功消费消息之后,消费者向代理发送消息确认。然后,这条已使用的消息将被永久存储,只有在所有订阅都确认它之后才能删除。确认(ack)是Pulsar知道消息可以从系统中删除的方式。如果要存储已被消费者确认的消息,则需要配置消息保留策略

可以通过以下两种方式之一来确认消息:

  • 被个别承认

    使用单独的确认,消费者确认每个消息并向代理发送确认请求。

  • 累计确认

    累积确认方式。使用这种方式,当你确认消息4时,你实际上是告诉Pulsar所有小于或等于4的消息都已被处理,即1, 2, 3, 4都视为被消费。它假设消费者以顺序方式处理消息,并且一次对多条消息进行确认,这可以减少确认消息所需的网络通信次数,从而提高处理效率。

如果您想单独确认消息,可以使用以下API。

consumer.acknowledge(msg);

如果您想累积确认消息,可以使用以下API。

consumer.acknowledgeCumulative(msg);

共享订阅类型中不能使用累积确认,因为共享订阅类型涉及多个可以访问同一订阅的使用者。在共享订阅类型中,消息单独确认。

Nack

与之相反的 Nack 否定确认机制允许您向代理发送通知,指示使用者未处理消息。当使用者无法使用消息并需要重新使用该消息时,使用者会向代理发送否定确认 (nack),从而触发代理将此消息重新传递给使用者。

根据消费订阅类型,单独或累积地对消息进行否定确认:

  • 在独占和故障转移订阅类型中,使用者仅以否定方式确认他们收到的最后一条消息。
  • 在“共享”和“Key_Shared”订阅类型中,使用者可以单独否定地确认消息。

Ack timeout

默认情况下,Ack timeout 处于禁用状态,这意味着除非使用者崩溃,否则不会重新发送传递给使用者的消息。

确认超时机制允许您设置客户端跟踪未确认消息的时间范围。在此确认超时 ( ackTimeout ) 期限之后,客户端向代理发送 redeliver unacknowledged messages 请求,因此代理将未确认的消息重新发送给使用者。

  • 如果启用了批处理,则一个批处理中的所有消息都将重新传递给使用者。
  • 与Ack timeout相比,Nack是首选。首先,设置超时值很困难。其次,当消息处理时间超过确认超时时,代理会重新发送消息,但这些消息可能不需要重新使用。

Retry Topic

该功能允许您存储使用失败的消息,并在以后重试使用它们。使用此方法,您可以自定义重新传递消息的时间间隔。原始主题的使用者也会自动订阅重试信主题。一旦达到最大重试次数,未使用的消息将被移动到一个死信主题中进行 手动 处理。重试信主题的功能由使用者实现。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用重试信主题的意图与使用延迟消息传递的意图不同,即使两者都旨在稍后使用消息。Retry Topic通过消息重新传递来提供故障处理,以确保关键数据不会丢失,而延迟消息传递旨在传递具有指定时间延迟的消息。

默认情况下,自动重试处于禁用状态。您可以在创建消费者时设置为 enableRetry true 在使用者上启用自动重试,设置maxRedeliverCount 值来指定重试次数。

默认的 Retry Topic 使用如下格式:

<topicname>-<subscriptionname>-RETRY

https://pulsar.apache.org/docs/3.2.x/concepts-messaging/#retry-letter-topic

Dead Topic

Dead Topic 和 Retry Topic 类似,只不过是在消息确认失败后不重试,直接将消息放到死消息区。

消息压缩

消息压缩可以通过支付一些 CPU 开销来减小消息大小。Pulsar 客户端支持以下压缩类型:

压缩类型存储在消息元数据中,因此使用者可以根据需要自动采用不同的压缩类型。

Batching

启用批处理后,生产者会在单个请求中累积并发送一批消息。批处理大小由最大消息数和最大发布延迟定义。因此,积压工作 (backlog) 大小表示批处理总数,而不是消息总数。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在 Pulsar 中,批处理被跟踪并存储为单个单元,而不是单个消息。使用者将批处理拆分为单个消息。但是,即使启用了批处理,计划消息(通过 deliverAt 或 参数 deliverAfter 配置)也始终作为单个消息发送。

通常,当使用者确认批处理的所有消息时,就会确认批处理。这意味着,当并非所有批处理消息都得到确认时,意外失败、否定确认或确认超时可能会导致重新传递此批处理中的所有消息:

  • 为了避免将确认的消息批量重新传递给消费者,Pulsar 从 Pulsar 2.6.0 开始引入了批量索引确认。启用批处理索引确认后,使用者会过滤掉已确认的批处理索引,并将批处理索引确认请求发送给代理。代理维护批处理索引确认状态,并跟踪每个批处理索引的确认状态,以避免向使用者发送确认消息。当确认其中消息的所有索引时,将删除该批处理。
  • 默认情况下,批处理索引确认处于禁用状态 ( acknowledgmentAtBatchIndexLevelEnabled=false )。您可以通过在代理端将 acknowledgmentAtBatchIndexLevelEnabled 参数设置为 true 来启用批处理索引确认。启用批处理索引确认会导致更多的内存开销。
  • 还必须通过调用 .enableBatchIndexAcknowledgment(true); 在使用者中启用批处理索引确认

Chunking

消息分块使 Pulsar 能够通过在生产者端将消息拆分为块,并在消费者端聚合块消息来处理大型有效负载消息。

开启消息分块后,当消息大小超过允许的最大负载大小(代理 maxMessageSize 参数)时,消息传递工作流如下:

  1. 生产者将原始消息拆分为分块消息,并将它们与分块元数据一起单独按顺序发布到代理。
  2. 代理以与普通消息相同的方式将分块消息存储在一个托管账本中,并使用该 chunkedMessageRate 参数记录该主题的分块消息速率。
  3. 使用者缓冲分块消息,并在收到消息的所有块时将它们聚合到接收方队列中。
  4. 客户端使用接收方队列中的聚合消息。

分块仅适用于持久性主题。

分块不能与批处理同时启用。在启用分块之前,您需要禁用批处理。

Topic 主题

Pulsar 主题是将消息组织成流的存储单元。与其他 pub-sub 系统一样,Pulsar 中的主题被命名为从生产者向消费者传递消息的通道。主题名称是具有明确定义结构的 URL:

{persistent|non-persistent}://tenant/namespace/topic
Topic name componentDescription
persistent / non-persistent持久性。默认值为 persistent,因此如果未指定类型,则主题为 persistent。对于持久性主题,所有消息都会持久地保留在磁盘上(如果代理不是独立的,则消息会持久地保留在多个磁盘上),而非持久性主题的数据不会持久保存到存储磁盘上。
tenant实例中的主题租户。租户对于 Pulsar 中的多租户至关重要,并且分布在集群中。
namespace主题的管理单位,充当相关主题的分组机制。大多数主题配置都是在命名空间级别执行的。每个租户都有一个或多个命名空间。
topic名称的最后一部分。主题名称在 Pulsar 实例中没有特殊含义。

你不需要在 Pulsar 中显式创建主题。如果客户端尝试向尚不存在的主题写入或接收消息,Pulsar 会自动在主题名称中提供的命名空间下创建该主题。如果客户端创建主题时未指定租户或命名空间,则会在默认租户和命名空间中创建该主题。您还可以在指定的租户和命名空间中创建主题,例如 persistent://my-tenant/my-namespace/my-topic

Namespaces 命名空间

Pulsar 命名空间是主题的逻辑分组,也是租户中的逻辑命名法。租户通过管理 API 创建命名空间。例如,具有不同应用程序的租户可以为每个应用程序创建单独的命名空间。命名空间允许应用程序创建和管理主题的层次结构。该主题 my-tenant/app1 是 的应用程序 app1my-tenant 命名空间。您可以在命名空间下创建任意数量的主题。

Subscriptions type 订阅类型

Pulsar 订阅是一个命名的配置规则,用于确定如何将消息传递给消费者。它是对一组消费者建立的主题的租约。Pulsar 中有四种订阅类型:

Subscription types in Pulsar

当订阅没有使用者时,其订阅类型未定义。订阅的类型是在使用者连接到订阅时定义的,可以通过使用不同的配置重新启动所有使用者来更改类型。

Exclusive 独占

独占类型是一种订阅类型,仅允许单个使用者附加到订阅。如果多个使用者使用同一订阅订阅一个主题,则会发生错误。请注意,如果主题已分区,则允许连接到订阅的单个使用者将使用所有分区。

在下图中,只允许使用者 A 使用消息:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Failover 故障转移

故障转移类型是多个使用者可以附加到同一订阅的订阅类型。为未分区主题或分区主题的每个分区选择主使用者并接收消息。当主使用者断开连接时,所有(未确认的和后续的)消息都将传递给下一个使用者。

在某些情况下,分区可能有一个较旧的活动使用者处理消息,而新切换的活动使用者开始接收新消息。这可能会导致消息重复或乱序。https://pulsar.apache.org/docs/3.2.x/concepts-messaging/#failover–partitioned-topics

Shared 共享

Pulsar 中的共享订阅类型允许多个消费者附加到同一个订阅。消息在消费者之间以循环分布方式传递,并且任何给定的消息都仅传递给一个使用者。当使用者断开连接时,所有已发送给它但未确认的消息都将重新安排以发送给其余使用者。共享订阅不保证消息排序或支持累积确认。

在下图中,消费者 A、消费者 B 和消费者 C 都能够订阅该主题。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Key_Shared

Pulsar 中的Key_Shared订阅类型允许多个消费者附加到同一个订阅。但与共享类型的不同,Key_Shared类型的消息在使用者之间分发,具有相同密钥或相同订购密钥的消息仅传递给一个使用者。无论消息被重新传递多少次,它都会传递给同一个使用者。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

有三种类型的映射算法指示如何为给定的消息键(或排序键)选择使用者:

  • Auto-split Hash Range (自动拆分哈希范围)
  • Auto-split Consistent Hashing (自动拆分一致哈希)
  • Sticky

算法实现详见:https://pulsar.apache.org/docs/3.2.x/concepts-messaging/#auto-split-hash-range,所有映射算法的步骤如下:

  1. 消息密钥(或排序密钥)被传递给哈希函数(例如,Murmur3 32 位),产生 32 位整数哈希。
  2. 该哈希号被馈送到算法,以便从现有的连接使用者中选择使用者。
                      +--------------+                              +-----------+
Message Key ----->  / Hash Function / ----- hash (32-bit) -------> / Algorithm / ----> Consumer
                   +---------------+                               +----------+

当连接了新的使用者并因此添加到连接的使用者列表中时,算法会重新调整映射,以便当前映射到现有使用者的某些密钥将映射到新添加的使用者。当使用者断开连接,从而从连接的使用者列表中删除时,映射到它的密钥将映射到其他使用者。以下各节将解释如何在给定消息哈希的情况下选择使用者,以及如何在连接新使用者或现有使用者断开每个算法的连接时调整映射。

Subscription modes

订阅模式表示游标属于持久类型或非持久类型。

  • 创建订阅时,将创建一个关联的游标来记录上次使用的位置。
  • 当订阅的使用者重新启动时,它可以从它使用的最后一条消息开始继续使用。
Subscription modeDescriptionNote
Durable光标是持久的,它保留消息并保留当前位置。 如果代理从故障中重新启动,它可以从持久性存储 (BookKeeper) 中恢复游标,以便可以从上次使用的位置继续使用消息。Durable 是默认订阅模式。
NonDurable光标是非持久的。 一旦代理停止,游标就会丢失,并且永远无法恢复,因此消息无法从上次使用的位置继续使用。读者的订阅模式 NonDurable 本质上是,它不会阻止删除主题中的数据。读者的订阅模式无法更改。

订阅可以有一个或多个使用者。当使用者订阅主题时,它必须指定订阅名称。持久订阅和非持久订阅可以具有相同的名称,它们彼此独立。如果使用者指定了以前不存在的订阅,则会自动创建该订阅。

默认情况下,没有任何持久订阅的主题的消息被标记为已删除。如果要防止消息被标记为已删除,可以为此主题创建持久订阅。在这种情况下,只有确认的消息才会标记为已删除。

多主题订阅

当消费者订阅 Pulsar 主题时,默认情况下它会订阅一个特定的主题,例如 persistent://public/default/my-topic .然而,从 Pulsar 版本 1.23.0 孵化开始,Pulsar 消费者可以同时订阅多个主题。您可以通过两种方式定义主题列表:

  • 例如,在正则表达式(正则表达式)的基础上, persistent://public/default/finance-.*
  • 通过显式定义主题列表

通过正则表达式订阅多个主题时,所有主题必须位于同一命名空间中。

Partitioned topics 分区主题

普通主题仅由单个代理提供服务,这限制了主题的最大吞吐量。分区主题是由多个代理处理的特殊类型的主题,因此允许更高的吞吐量。

Partition distribution in Pulsar

就订阅类型的工作方式而言,分区主题和普通主题之间没有区别,因为分区仅确定在生产者发布消息与使用者处理和确认消息之间发生的情况。分区主题需要通过管理 API 显式创建。创建主题时可以指定分区数。

Routing modes 路由模式

发布到分区主题时,必须指定路由模式。路由模式确定每条消息应发布到哪个分区或哪个内部主题。有三个可用的 MessageRoutingMode:

ModeDescription
RoundRobinPartition如果未提供密钥,则生产者将以循环方式在所有分区中发布消息,以实现最大吞吐量。请注意,轮询不是按单个消息完成的,而是设置为相同的批处理延迟边界,以确保批处理有效。如果在消息上指定了密钥,则分区生产者将对密钥进行哈希处理并将消息分配给特定分区。这是默认模式。
SinglePartition如果未提供密钥,生产者将随机选择一个分区并将所有消息发布到该分区中。如果在消息上指定了密钥,则分区生产者将对密钥进行哈希处理并将消息分配给特定分区。
CustomPartition使用将调用的自定义消息路由器实现来确定特定消息的分区。用户可以通过使用 Java 客户端并实现 MessageRouter 接口来创建自定义路由方式。

Ordering guarantee

消息的顺序与 MessageRoutingMode 和 Message Key 相关。通常,用户需要按键分区保证的顺序。

如果消息附加了密钥,则在使用 SinglePartition or RoundRobinPartition 模式时,消息将根据 ProducerBuilder 中 HashingScheme 指定的哈希方案路由到相应的分区。

Ordering guaranteeDescriptionRouting Mode and Key 路由模式和密钥
Per-key-partition 每个键分区所有具有相同键的消息都将按顺序排列并放置在同一个分区中。使用 or SinglePartition RoundRobinPartition 模式,并且每条消息都提供密钥。
Per-producer来自同一生产者的所有消息都将按顺序排列。使用 SinglePartition 模式,并且没有为每条消息提供密钥。

Hashing scheme 哈希方案

哈希方案是一个枚举,表示在选择要用于特定消息的分区时可用的标准哈希函数集。有 2 种类型的标准哈希函数可用:

  • JavaStringHash
  • Murmur3_32Hash

生产者的默认哈希函数是 JavaStringHash 。请注意, JavaStringHash 当生产者可以来自不同的多语言客户端时,这是没有用的,在此用例下,建议使用 Murmur3_32Hash .

Non-persistent topics 非持久性主题

默认情况下,Pulsar 会将所有未确认的消息永久存储在多个 BookKeeper 博彩公司(存储节点)上。因此,持久性主题上的消息数据可以在代理重新启动和订户故障转移后继续存在。

但是,Pulsar 也支持非持久性主题。非持久性主题是 Pulsar 主题,其中消息数据从不持久化存储到磁盘中,仅保存在内存中。使用非持久性传输时,终止 Pulsar 代理或断开订阅者与主题的连接意味着该(非持久性)主题上的所有传输中消息都将丢失,这意味着客户端可能会看到消息丢失。

非持久性主题的名称为以下形式(请注意 non-persistent 名称中的 ):

non-persistent://tenant/namespace/topic

System topic 系统主题

系统主题是 Pulsar 内部使用的预定义主题。它可以是持久性主题,也可以是非持久性主题。

系统主题用于实现某些功能并消除对第三方组件(如事务、检测信号、主题级策略和资源组服务)的依赖性。系统主题使这些功能的实现变得简单、依赖和灵活。以检测心跳为例,您可以利用系统主题进行健康检查,在内部使生产者/读取者能够在检测信号命名空间下生成/使用消息,从而检测当前服务是否仍然处于活动状态。

下表概述了每个特定命名空间的可用系统主题:

NamespaceTopicNameDomainCountUsage
pulsar/systemtransaction_coordinator_assign_${id}PersistentDefault 16事务协调器
pulsar/system__transaction_log_${tc_id}PersistentDefault 16事务日志
pulsar/systemresource-usageNon-persistentDefault 4资源组服务
host/portheartbeatPersistent1心跳检测
User-defined-ns 用户定义的ns__change_eventsPersistentDefault 4Topic events
User-defined-ns__transaction_buffer_snapshotPersistent每个命名空间一个事务缓冲区快照
User-defined-ns${topicName}__transaction_pending_ackPersistent每个主题订阅一个,确认了事务交易确认

不能创建任何系统主题。要列出系统主题,您可以在使用 Pulsar admin API 获取主题列表时添加该选项 --include-system-topic

从 Pulsar 2.11.0 版本开始,系统主题默认开启。在早期版本中,您需要在 conf/broker.conf or conf/standalone.conf 文件中更改以下配置才能启用系统主题。

systemTopicEnabled=true
topicLevelPoliciesEnabled=true

消息保留和过期

默认情况下,Pulsar 消息 brokers 立即删除使用者已确认的所有消息,并将所有未确认的消息永久存储在消息backlog工作中。但是,Pulsar 有两个功能可以覆盖此默认行为:

  • 通过消息保留,可以存储已由使用者确认的消息
  • 通过消息过期,您可以为尚未确认的邮件设置生存时间 (TTL)

所有消息保留和过期都在命名空间级别进行管理。有关操作方法,请参:https://pulsar.apache.org/docs/3.2.x/cookbooks-retention-expiry/

消息重复数据删除

当一条消息被 Pulsar 多次持久化时,就会发生消息重复。消息重复数据删除可确保 Pulsar 主题上生成的每条消息仅保存到磁盘一次,即使该消息生成了多次。消息重复数据删除在服务器端自动处理。

下图说明了禁用与启用重复数据删除时发生的情况:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

https://pulsar.apache.org/docs/3.2.x/concepts-messaging/#message-deduplication

消息传递延迟

通过延迟消息传递,您可以稍后使用消息。在此机制中,消息存储在 BookKeeper 中。在将消息发布到代理后,在内存中 DelayedDeliveryTracker 维护时间索引(time -> messageId)。指定的延迟结束后,此消息将传递给使用者。

下图说明了延迟消息传递的概念:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

代理保存消息时不进行任何检查。当使用者使用消息时,如果消息设置为延迟,则该消息将添加到 DelayedDeliveryTracker .订阅检查并从 DelayedDeliveryTracker 中获取超时消息。

系统架构

在最高级别上,Pulsar 实例由一个或多个 Pulsar 集群组成。实例中的集群可以在它们之间复制数据。Pulsar 集群由以下组件组成:

  • 一个或多个代理处理和负载均衡来自生产者的传入消息,将消息分派给消费者,与 Pulsar 配置存储通信以处理各种协调任务,将消息存储在 BookKeeper 实例中,依赖特定于集群的 ZooKeeper 集群来执行某些任务,等等。
  • 一个 BookKeeper 集群由 一个或多个 bookies 处理消息的持久存储。
  • 专属于该集群的 ZooKeeper 集群处理 Pulsar 集群之间的协调任务。

下图展示了一个 Pulsar 集群:

Pulsar architecture diagram

Brokers

Pulsar 消息 Broker 是一个无状态组件,主要负责运行另外两个组件:

  • 一个 HTTP 服务器,它为生产者和使用者的管理任务和主题查找公开 REST API。生产者连接到代理以发布消息,使用者连接到代理以使用消息。
  • 调度程序,它是用于所有数据传输的自定义二进制协议上的异步 TCP 服务器

Clusters

一个 Pulsar 实例由一个或多个 Pulsar 集群组成。反过来,集群由以下部分组成:

  • 一个或多个 Pulsar Broker
  • 一个 ZooKeeper 用于群集级配置和协调的仲裁
  • bookies 集合用于持久化存储消息

Metadata store

Pulsar 元数据存储维护 Pulsar 集群的所有元数据,例如主题元数据、模式、代理加载数据等。Pulsar 使用 Apache ZooKeeper 进行元数据存储、集群配置和协调。Pulsar 元数据存储可以部署在单独的 ZooKeeper 集群上,也可以部署在现有的 ZooKeeper 集群上。您可以将一个 ZooKeeper 集群用于 Pulsar 元数据存储和 BookKeeper 元数据存储。如果要部署连接到现有 BookKeeper 集群的 Pulsar 代理,则需要分别为 Pulsar 元数据存储和 BookKeeper 元数据存储部署单独的 ZooKeeper 集群。

在 Pulsar 实例中:

  • 配置存储仲裁存储租户、命名空间和其他需要全局一致的实体的配置。
  • 每个集群都有自己的本地 ZooKeeper 集成,用于存储特定于集群的配置和协调,例如哪些代理负责哪些主题以及所有权元数据、代理负载报告、BookKeeper 账本元数据等。

Configuration store

配置存储是 ZooKeeper 仲裁,用于特定于配置的任务,它维护 Pulsar 实例的所有配置,例如集群、租户、命名空间、分区主题相关配置等。一个 Pulsar 实例可以有单个本地集群、多个本地集群或多个跨区域集群。因此,配置存储可以在 Pulsar 实例下的多个集群之间共享配置。配置存储可以部署在单独的 ZooKeeper 群集上,也可以部署在现有的 ZooKeeper 群集上。

Persistent storage

Pulsar 为应用程序提供有保障的消息传递。如果消息成功到达 Pulsar 代理,它将被传送到其预期目标。

此保证要求持久存储未确认的消息,直到它们可以传递给消费者并由消费者确认。这种消息传递模式通常称为持久消息传递。在 Pulsar 中,所有消息的 N 个副本都存储在磁盘上并同步,例如,在两台服务器上有 4 个副本,每台服务器上都有镜像的 RAID 卷。

Apache BookKeeper

Pulsar 使用一个名为 Apache BookKeeper 的系统进行持久性消息存储。BookKeeper 是一个分布式预写日志 (WAL) 系统,它为 Pulsar 提供了几个关键优势:

  • 它使 Pulsar 能够利用许多独立的日志,称为账本。随着时间推移,可以为主题创建多个账本。
  • 它为处理条目复制的顺序数据提供了非常有效的存储。
  • 它保证了在存在各种系统故障时账本的读取一致性。
  • 它提供了在 Bookies 之间均匀分布的 I/O。
  • 它在容量和吞吐量方面都是可水平扩展的。通过向集群添加更多 Bookies,可以立即增加容量。
  • Bookies 旨在处理数千个并发读写账。通过使用多个磁盘设备—一个用于日志,另一个用于常规存储),博彩公司可以将读取操作的影响与正在进行的写入操作的延迟隔离开来。

除了消息数据之外,游标还永久存储在 BookKeeper 中。游标是使用者的订阅位置。BookKeeper 使 Pulsar 能够以可扩展的方式存储消费者位置。

您可以在下图中看到Brokers和Bookies如何互动的插图:

Brokers and bookies in a Pulsar cluster

Ledgers

Ledgers 账本是一种仅追加的数据结构,具有分配给多个 BookKeeper 存储节点或博彩公司的单个写入器。账本条目被复制到多个博彩公司。账本本身的语义非常简单:

  • Pulsar 代理可以创建账本,将条目附加到账本中,然后关闭账本。
  • 在账本关闭后—无论是显式关闭还是因为写入器进程崩溃—它只能以只读模式打开。
  • 最后,当不再需要账本中的条目时,可以从系统中删除整个账本(跨所有bookies)。

Pulsar proxy

Pulsar 客户端与 Pulsar 集互的一种方式是直接连接到 Pulsar 消息代理。然而,在某些情况下,这种直接连接要么不可行,要么是不可取的,因为客户端无法直接访问代理地址。例如,如果你在云环境、Kubernetes 或类似平台上运行 Pulsar,那么客户端与代理的直接连接可能是不可能的。

Pulsar 代理通过充当集群中所有代理的单个网关来解决这个问题。如果您运行 Pulsar 代理(同样是可选的),则与 Pulsar 集群的所有客户端连接都将通过代理进行传输,而不是与代理通信。

在架构上,Pulsar 代理从 ZooKeeper 获取所需的所有信息。在计算机上启动代理时,只需为特定于集群和实例范围的配置存储集群提供元数据存储连接字符串。下面是一个示例:

cd /path/to/pulsar/directory
bin/pulsar proxy \
    --metadata-store zk:my-zk-1:2181,my-zk-2:2181,my-zk-3:2181 \
    --configuration-metadata-store zk:my-zk-1:2181,my-zk-2:2181,my-zk-3:2181

Service discovery

服务发现是一种机制,它允许连接客户端仅使用单个 URL 与整个 Pulsar 实例进行交互。

如果需要,可以使用自己的服务发现系统。如果您使用自己的系统,则只有一个要求:当客户端向终端节点执行 HTTP 请求时,例如 http://pulsar.us-west.example.com:8080 ,需要将客户端重定向到所需集群中的某个活动代理,无论是通过 DNS、HTTP 或 IP 重定向,还是其他方式。

下图说明了 Pulsar 服务发现:

Service discovery in Pulsar

在此图中,Pulsar 集群可通过单个 DNS 名称进行寻址: pulsar-cluster.acme.com 。例如,Python 客户端可以像这样访问这个 Pulsar 集群:

from pulsar import Client

client = Client('pulsar://pulsar-cluster.acme.com:6650')

安装

从 Apache Pulsar 的官方网站(https://pulsar.apache.org/download/)下载最新版本的 Pulsar 发行版。选择适合您操作系统的二进制发行版并下载。

解压下载的 Pulsar 发行版文件,得到一个包含 Pulsar 文件的文件夹。

tar xvfz apache-pulsar-3.2.2-bin.tar.gz

单节点

单节点也是以集群的方式启动的。进入 Pulsar 解压目录,找到 conf 目录,然后编辑 standalone.conf 文件。配置文件中包含了 Pulsar 的各种参数,例如网络端口、存储路径等。至少需要配置 brokerServicePortwebServicePort

# standalone.conf

# Pulsar broker service port
brokerServicePort=6650

# Pulsar web service port
webServicePort=8080

在命令行中进入 Pulsar 解压目录,运行以下命令启动 Pulsar Standalone:

bin/pulsar standalone

要将服务作为后台进程运行,可以使用命令:

bin/pulsar-daemon start standalone

使用 Pulsar 提供的命令行工具或客户端 API 连接到 Pulsar 实例,确保它正常运行并可访问。

当Pulsar集群启动时,将创建以下目录:

目录描述
数据由BookKeeper和RocksDB创建的所有数据
日志所有服务器端日志

集群

将单节点安装中的 Pulsar 目录复制到所有集群节点。确保所有节点上的 Pulsar 版本一致。

在每个节点上编辑 broker.conf 文件,配置集群的相关信息,包括 advertisedAddress、brokerServicePort、webServicePort 等。确保所有节点的配置相似,但 advertisedAddress 需要设置为每个节点的实际 IP 地址。

# broker.conf

# Advertised address for the broker
advertisedAddress=<Node_IP_Address>

# Pulsar broker service port
brokerServicePort=6650

# Pulsar web service port
webServicePort=8080

在每个节点上运行以下命令启动 Pulsar Broker:

bin/pulsar broker

使用 Pulsar 提供的命令行工具或客户端 API 连接到集群中的任何节点,确保它正常运行并可访问。您可以使用任何节点的 IP 地址和端口(默认为 6650)连接到集群。

配置文件

standalone.conf


broker.conf


其他常见配置


命令

tenant

# 创建租户
pulsar-admin tenants create <tenant-name>
# 租户列表
pulsar-admin tenants list
# 获取租户信息
pulsar-admin tenants get <tenant-name>
# 删除租户
 pulsar-admin tenants delete <tenant-name>

namespace

# 创建命名空间
pulsar-admin namespaces create <tenant>/<namespace>
# 命名空间列表
pulsar-admin namespaces list <tenant>
# 获取命名空间信息
pulsar-admin namespaces get <tenant>/<namespace>
# 删除一个命名空间
 pulsar-admin namespaces delete <tenant>/<namespace>
# 清空命名空间下所有 topic
pulsar-admin namespaces clear-backlog <tenant>/<namespace>

topic

创建一个Topic:

# 创建非分区主题
pulsar-admin topics create <persistent/non-persistent>://<tenant>/<namespace>/<topic>
# 创建分区主题
pulsar-admin topics create-partitioned-topic <persistent/non-persistent>://<tenant>/<namespace>/<topic> --partitions <num-partitions>
# 列出所有命名空间
pulsar-admin topics list <tenant>/<namespace>
# 删除指定 topic
pulsar-admin topics delete <persistent/non-persistent>://<tenant>/<namespace>/<topic>
# 减少分区数
pulsar-admin topics update-partitioned-topic <persistent/non-persistent>://<tenant>/<namespace>/<topic> --partitions <num-partitions>
# 列出所有的订阅
pulsar-admin topics subscriptions <topic>
# 查看topic详情
pulsar-admin topics stats <topic>
pulsar-admin topics create persistent://public/default/my-topic

消息

生产者推送一条消息:

pulsar-client produce my-topic --messages 'Hello Pulsar!'

启动消费者接收消息:

# -p 或 --subscription-position 选项用来指定订阅的初始位置,即从哪里开始消费消息。在你的例子中, -p Earliest 表示从最早的消息开始消费,也就是说,会消费此主题中所有尚未被此订阅消费的消息。对比的还有 Latest,它表示从最新的消息开始消费,忽略所有早先的消息。

#-n 或 --num-messages 选项用来指定要消费的消息数量。在你的命令中,-n 0 表示要消费的消息数量没有限制,客户端将持续消费消息,直到被外部停止。如果这个值被设置成一个具体的数值,如 -n 10,那么客户端将会消费 10 条消息然后退出。
pulsar-client consume my-topic -s 'my-subscription' -p Earliest -n 0

# 你可以使用--subscription-type 或简写 -t 选项来指定。Apache Pulsar 支持几种不同的订阅类型:Exclusive、Shared、Failover、Key_Shared

推送多条消息默认的分隔符是逗号:

pulsar-client produce my-topic --messages "$(seq -s, -f 'Message NO.%g' 1 10)"

认证 (未验证)

  1. 启用认证:修改conf/broker.confconf/standalone.conf(如果你在用单机版)。设置 authenticationEnabledauthorizationEnabledtrue

  2. 选择认证方式:Pulsar 支持多种认证方式,比如 Token, OAuth2, TLS等等。这里我们假设使用了最常见的Token认证方式。配置认证提供者,继续在conf/broker.confconf/standalone.conf中配置认证提供者。对于Token认证,配置项如下:

authenticationProviders=org.apache.pulsar.broker.authentication.AuthenticationProviderToken
authenticationTokenSecretKey=file:///path/to/secret.key

其中/path/to/secret.key是你的秘钥文件的路径。

  1. 生成秘钥和Token:使用Pulsar自带的token命令行工具生成密钥和token。密钥用于服务端验证,token发给客户端用于认证。
   bin/pulsar tokens create-secret-key --output secret.key --base64
  1. 然后创建token:
bin/pulsar tokens create --secret-key file:///path/to/secret.key --subject test-user
  1. 配置客户端:客户端在配置的时候需要指定token。在客户端的配置文件中或者是通过代码指定。使用Go客户端为例,配置代码如下:
import (
    "github.com/apache/pulsar/pulsar-client-go/pulsar"
    "log"
)

func main() {
    client, err := pulsar.NewClient(pulsar.ClientOptions{
        URL:            "pulsar://localhost:6650",
        Authentication: pulsar.NewAuthenticationToken("eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0LXVzZXIifQ.abcdefghijk"),
    })

    if err != nil {
        log.Fatal(err)
    }
    defer client.Close()

    // 使用 client 执行你需要的操作
}

eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0LXVzZXIifQ.abcdefghijk就是你生成的token。

  1. 验证Token:一旦认证配置完成,客户端在连接时会发送Token,服务端会使用之前设置的秘钥对Token进行验证。如果验证不通过,连接会被拒绝。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值