关于pulsar:聊聊-Pulsar-Pulsar-的核心概念与基础架构

51次阅读

共计 14163 个字符,预计需要花费 36 分钟才能阅读完成。

一、Pulsar 介绍

Apache Pulsar 是 Apache 软件基金会的顶级我的项目,是下一代云原生分布式音讯流平台,集音讯、存储、轻量化函数式计算为一体,采纳计算与存储拆散架构设计,反对多租户、长久化存储、多机房跨区域数据复制,具备强一致性、高吞吐、低延时及高可扩展性等流数据存储个性。

Pulsar 的要害个性如下:

  • 是下一代云原生分布式音讯流平台。
  • Pulsar 的单个实例原生反对多个集群,可跨机房在集群间无缝地实现音讯复制。
  • 极低的公布提早和端到端提早。
  • 可无缝扩大到超过一百万个 topic。
  • 简略的客户端 API,反对 Java、Go、Python 和 C++。
  • 主题的多种订阅模式(独占、共享和故障转移)。
  • 通过 Apache BookKeeper 提供的长久化音讯存储机制保障消息传递。
  • 由轻量级的 serverless 计算框架 Pulsar Functions 实现流原生的数据处理。
  • 基于 Pulsar Functions 的 serverless connector 框架 Pulsar IO 使得数据更易移入、移出 Apache Pulsar。
  • 分层式存储可在数据古老时,将数据从热存储卸载到冷 / 长期存储(如 S3、GCS)中。

二、什么是云原生

既然说 Pulsar 是下一代云原生分布式音讯流平台,那咱们得晓得什么是云原生吧。

云原生的概念是 2013 年 Matt Stine 提出的,到目前为止,云原生的概念产生了屡次变更,目前最新对云原生的定义为:DevOps + 继续交付 + 微服务 + 容器。

而合乎云原生架构的应用程序是:采纳开源堆栈(k8s + docker)进行容器化,基于微服务架构进步灵活性和可维护性,借助麻利办法、DevOps 反对继续迭代和运维自动化,利用云平台设施实现弹性伸缩、动静调度、优化资源利用率。

三、外围概念

3.1 Messages(音讯)

Component Description
Value / data payload 音讯携带的数据,所有 Pulsar 的音讯携带原始 bytes,然而音讯数据也须要遵循数据 schemas。
Key 音讯能够被 Key 打标签。这能够对 topic 压缩之类的事件起作用。
Properties 可选的,用户定义属性的 key/value map。
Producer name 生产音讯的 producer 的名称(producer 被主动赋予默认名称,但你也能够本人指定。)
Sequence ID 在 topic 中,每个 Pulsar 音讯属于一个有序的序列。音讯的 sequence ID 是它在序列中的秩序。
Publish time 音讯公布的工夫戳
Event time 可选的工夫戳,利用能够附在音讯上,代表某个事件产生的工夫,例如,音讯被解决时。如果没有明确的设置,那么 event time 为 0。
TypedMessageBuilder 它用于结构音讯。您能够应用 TypedMessageBuilder 设置音讯属性,比方音讯键、音讯值。设置 TypedMessageBuilder 时,将键设置为字符串。如果您将键设置为其余类型,例如,AVRO 对象,则键将作为字节发送,并且很难从消费者处取回 AVRO 对象。

音讯的默认大小为 5 MB,能够通过以下形式配置音讯的最大大小。

  • broker.conf

    # The max size of a message (in bytes).
    maxMessageSize=5242880
  • bookkeeper.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

3.2 Producers(生产者)

生产者是关联到 topic 的程序,它公布音讯到 Pulsar 的 broker 上。

3.2.1 Send modes(发送模式)

producer 能够以同步或者异步的形式公布音讯到 broker。

Mode Description
异步发送 发送音讯后,producer 期待 broker 的确认。如果没有收到确认,producer 会认为发送失败。
同步发送 producer 将会把音讯放入阻塞队列,而后马上返回。客户端类库将会在背地把音讯发送给 broker。如果队列满了,依据传给 producer 的参数,producer 可能阻塞或者间接返回失败。

3.2.2 Access mode(拜访模式)

你能够为生产者提供不同类型的主题拜访模式。

Access mode Description
Shared(共享) 多个生产者能够公布一个主题,这是默认设置。
Exclusive(独占) 一个主题只能由一个生产者公布。如果曾经有生产者连贯,其余生产者试图公布该主题立刻失去谬误。如果“老”生产者与 broker 产生网络分区,“老”生产者将被驱赶,“新”生产者将被选为下一个惟一的生产者。
WaitForExclusive(独占期待) 如果曾经有一个生产者连贯,生产者的创立是未决的(而不是超时),直到生产者取得独占拜访。胜利成为排他性的生产者被视为领导者。因而,如果您想为您的应用程序实现 leader 选举计划,您能够应用这种拜访模式。

3.2.3 Compression(压缩)

你能够压缩生产者在传输期间公布的音讯。Pulsar 目前反对以下类型的压缩:

  • LZ4
  • ZLIB
  • ZSTD
  • SNAPPY

3.2.4 Batching(批处理)

如果批处理开启,producer 将会累积一批音讯,而后通过一次申请发送进来。批处理的大小取决于最大的音讯数量及最大的公布提早。

3.2.5 Chunking(分块)

  • 批处理和分块不能同时启用。要启用分块,必须提前禁用批处理。
  • Chunking 只反对长久化的主题。
  • Chunking 仅反对 exclusive 和 failover 订阅模式。
3.2.5.1 解决一个 producer 和一个订阅 consumer 的分块音讯

如下图所示,当生产者向主题发送一批大的分块音讯和一般的非分块音讯时。假如生产者发送的音讯为 M1,M1 有三个分块 M1-C1,M1-C2 和 M1-C3。这个 broker 在其治理的 ledger 外面保留所有的三个块音讯,而后以雷同的程序分发给消费者(独占 / 灾备模式)。消费者将在内存缓存所有的块音讯,直到收到所有的音讯块。将这些音讯合并成为原始的音讯 M1,发送给解决过程。

3.2.5.2 解决多个 producer 和一个订阅 consumer 的分块音讯

当多个生产者公布块音讯到单个主题,这个 Broker 在同一个 Ledger 外面保留来自不同生产者的所有块音讯。如下所示,生产者 1 公布的音讯 M1,M1 由 M1-C1, M1-C2 和 M1-C3 三个块组成。生产者 2 公布的音讯 M2,M2 由 M2-C1, M2-C2 和 M2-C3 三个块组成。这些特定音讯的所有分块是顺序排列的,然而其在 ledger 外面可能不是间断的。这种形式会给消费者带来肯定的内存累赘。因为消费者会为每个大音讯在内存开拓一块缓冲区,以便将所有的块音讯合并为原始的大音讯。

3.3 Consumers(消费者)

消费者通过订阅关联到主题,而后接管音讯的程序。

3.3.1 Receive modes(接管模式)

音讯能够通过同步或者异步的形式从 broker 接管。

Mode Description
同步接管 同步接管将会阻塞,直到音讯可用。
异步接管 异步接管立刻返回 future 值,例如 java 中的 CompletableFuture,一旦新音讯可用,它即刻实现。

3.3.2 Listeners(监听)

客户端类库提供了它们对于 consumer 的监听实现。举一个 Java 客户端的例子,它提供了 MessageListener 接口。在这个接口中,一旦承受到新的音讯,received 办法将被调用。

3.3.3 Acknowledgement(确认)

消费者胜利解决了音讯,须要发送确认给 broker,以让 broker 丢掉这条音讯(否则它将存储着此音讯)。

音讯的确认能够一个接一个,也能够累积一起。累积确认时,消费者只须要确认最初一条它收到的音讯。所有之前(蕴含此条)的音讯,都不会被从新发给那个消费者。

累积音讯确认不能用于 shared 订阅模式,因为 shared 订阅为同一个订阅引入了多个消费者。

3.4 Topics(主题)

和其它的公布订阅零碎一样,Pulsar 中的 topic 是带有名称的通道,用来从 producer 到 consumer 传输音讯。Topic 的名称是合乎良好构造的 URL。

{persistent|non-persistent}://tenant/namespace/topic
Topic name component Description
persistent / non-persistent 定义了 topic 类型,Pulsar 反对两种不同 topic:长久和非长久(默认是长久类型,如果你没有指明类型,topic 将会是长久类型)。长久 topic 的所有音讯都会保留在硬盘上(这意味着多块硬盘,除非是单机模式的 broker),反之,非长久 topic 的数据不会存储到硬盘上。
tenant 实例中 topic 的租户。tenant 是 Pulsar 多租户的基本要素。能够被跨集群的流传。
namespace topic 的治理单元,相干 topic 组的管理机制。大多数的 topic 配置在 namespace 层面失效。每个 tenant 能够有多个 namespace。
topic 主题名称的最初组成部分,topic 的名称很自在,没有什么非凡的含意。

3.4.1 Partitioned topics(分区主题)

一般主题仅由单个 broker 提供服务,这限度了主题的最大吞吐量。分区主题是由多个 broker 解决的一种非凡类型的主题,因而容许更高的吞吐量。

分区的主题实际上实现为 N 个外部主题,其中 N 是分区的数量。当将音讯公布到分区主题时,每个音讯都被路由到几个 broker 中的一个。分区在 broker 间的散布由 Pulsar 主动解决。

如上图,Topic1 主题有 5 个分区(P0 到 P4),划分在 3 个 broker 上。因为分区比 broker 多,前两个 broker 别离解决两个分区,而第三个 broker 只解决一个分区(同样,Pulsar 主动解决分区的散布)。

此主题的音讯将播送给两个消费者。路由模式决定将每个音讯公布到哪个分区,而订阅模式决定将哪些音讯发送到哪个消费者。

在大多数状况下,能够别离决定路由和订阅模式。通常,吞吐量问题应该领导分区 / 路由决策,而订阅决策应该依据应用程序语义进行领导。

就订阅模式的工作形式而言,分区主题和一般主题之间没有区别,因为分区仅决定音讯由生产者公布和由消费者解决和确认之间产生了什么。

分区主题须要通过治理 API 显式创立,分区的数量能够在创立主题时指定。

3.4.1.1 Routing modes(路由模式)

当公布音讯到分区 topic,你必须要指定路由模式。路由模式决定了每条音讯被公布到的分区(其实是外部主题)。

上面是三种默认可用的路由模式:

Mode Description
RoundRobinPartition message 无 key 则轮询,有 key 则 hash(key) 指定分区。(默认模式)
SinglePartition message 无 key,producer 将会随机抉择一个分区,把所有的音讯发往该分区。如果 message 指定了 key,分区的 producer 会把 key 做 hash,而后调配音讯到指定的分区。
CustomPartition 应用自定义音讯路由实现,能够决定特定的音讯进入指定的分区。
3.4.1.2 Ordering guarantee(程序保障)

音讯的程序与路由模式和音讯的 key 无关:

Ordering guarantee Description Routing Mode and Key
Per-key-partition(按 key 分区) 具备雷同 key 的所有音讯将被按程序搁置在同一个分区中。 应用 SinglePartition 或 RoundRobinPartition 模式,Key 由每个音讯提供。
Per-producer(按 producer) 来自同一生产者的所有音讯将是有序的。 应用 SinglePartition 模式,并且没有为每个音讯提供 Key。
3.4.1.3 Hashing scheme(哈希计划)

HashingScheme 是一个 enum,示意在抉择要为特定音讯应用的分区时可用的规范哈希函数集。

有两种类型的规范哈希函数可用:JavaStringHashMurmur3_32Hash。生产者的默认哈希函数是 JavaStringHash。请留神,当生产者能够来自不同的多语言客户端时,JavaStringHash 是没有用的,在这个用例下,倡议应用 Murmur3_32Hash

3.4.2 persistent/Non-persistent topics(长久 / 非长久主题)

默认状况下,Pulsar 会保留所有没确认的音讯到 BookKeeper 中。长久 Topic 的音讯在 Broker 重启或者 Consumer 呈现问题时保留下来。

除了长久 Topic,Pulsar 也反对非长久 Topic。这些 Topic 的音讯只存在于内存中,不会存储到磁盘。

因为 Broker 不会对音讯进行长久化存储,当 Producer 将音讯发送到 Broker 时,Broker 能够立刻将 ack 返回给 Producer,所以非长久 Topic 的消息传递会比长久 Topic 的消息传递更快一些。绝对的,当 Broker 因为一些起因宕机、重启后,非长久 Topic 的音讯都会隐没,订阅者将无奈收到这些音讯。

3.4.3 Dead letter topic(死信主题)

死信主题容许你在用户无奈胜利生产某些音讯时应用新音讯。在这种机制中,无奈应用的音讯存储在独自的主题中,称为死信主题。你能够决定如何解决死信主题中的音讯。

上面的例子展现了如何在 Java 客户端中应用默认的死信主题:

Consumer<byte[]> consumer = pulsarClient.newConsumer(Schema.BYTES)
    .topic(topic)
    .subscriptionName("my-subscription")
    .subscriptionType(SubscriptionType.Shared)
    .deadLetterPolicy(DeadLetterPolicy.builder()
          .maxRedeliverCount(maxRedeliveryCount)
          .build())
    .subscribe();

默认的死信主题格局:

<topicname>-<subscriptionname>-DLQ

如果你想指定死信主题的名称,请应用上面的 Java 客户端示例:

Consumer<byte[]> consumer = pulsarClient.newConsumer(Schema.BYTES)
    .topic(topic)
    .subscriptionName("my-subscription")
    .subscriptionType(SubscriptionType.Shared)
    .deadLetterPolicy(DeadLetterPolicy.builder()
          .maxRedeliverCount(maxRedeliveryCount)
          .deadLetterTopic("your-topic-name")
          .build())
    .subscribe();        

死信主题依赖于音讯的从新投递。因为确认超时或否定确认,音讯将被从新发送。如果要对音讯应用否定确认,请确保在确认超时之前对其进行否定确认。
目前,在共享和 Key_Shared 订阅模式下启用了死信主题。

3.4.4 Retry letter topic(重试主题)

对于许多在线业务零碎,因为业务逻辑解决中出现异常,音讯会被反复生产。若要配置从新生产失败音讯的延迟时间,你能够配置生产者将音讯发送到业务主题和重试主题,并在消费者上启用主动重试。当在消费者上启用主动重试时,如果音讯没有被生产,则音讯将存储在重试主题中,因而消费者在指定的延迟时间后将主动接管来自重试主题的失败音讯。

默认状况下,不启用主动重试性能。你能够将 enableRetry 设置为 true,以启用消费者的主动重试。

上面来看个如何应用从重试主题来生产音讯的示例:

Consumer<byte[]> consumer = pulsarClient.newConsumer(Schema.BYTES)
    .topic(topic)
    .subscriptionName("my-subscription")
    .subscriptionType(SubscriptionType.Shared)
    .enableRetry(true)
    .receiverQueueSize(100)
    .deadLetterPolicy(DeadLetterPolicy.builder()
            .maxRedeliverCount(maxRedeliveryCount)
            .retryLetterTopic("persistent://my-property/my-ns/my-subscription-custom-Retry")
            .build())
    .subscriptionInitialPosition(SubscriptionInitialPosition.Earliest)
    .subscribe();

3.5 Subscriptions(订阅模式)

Pulsar 反对 exclusive(独占)、failover(灾备)、shared(共享)和 key_shared(key 共享)四种音讯订阅模式,这四种模式的示意图如下:

3.5.1 Exclusive(独占模式)

独占模式是 Pulsar 默认的音讯订阅模式,在这种模式下,只能有一个 consumer 生产音讯,如果有多于一个 consumer 生产此 topic 则会出错,生产示意图如下:

3.5.2 Failover(灾备模式)

灾备模式下,一个 topic 也是只有单个 consumer 生产一个订阅关系的音讯,与独占模式不同之处在于,灾备模式下,每个消费者会被排序,当后面的消费者无奈连贯上 broker 后,音讯会由下一个消费者生产,生产示意图如下:

3.5.3 Shared(共享模式)

共享模式下,音讯可被多个 consumer 同时生产,无奈保障音讯的程序,并且无奈应用 one by one 和 cumulative 的 ack 模式,音讯通过 roundrobin 的形式投递到每一个消费者,生产示意图如下:

3.5.4 Key_Shared(Key 共享模式)

Key_Shared 模式是 Shared 模式的一种,不同的是它按 key 对音讯做投递,雷同的 key 的音讯会被投递到同一个 consumer 上,生产示意图如下:

3.6 Message retention and expiry(音讯保留和过期)

默认策略:

  • 立刻删除所有曾经被消费者确认过的的音讯;
  • 以 backlog 的模式,长久保留所有未被确认的音讯;

两个个性:

  • 音讯保留让你能够保留 consumer 确认过的音讯;
  • 音讯过期让你能够给未被确认的音讯设置存活时长(TTL);


注:所有音讯保留和过期在 namespace 层面治理。

3.7 Message deduplication(音讯去重)

实现音讯去重的一种形式是确保音讯仅生成一次,即生产者幂等。这种形式的毛病是把音讯去重的工作交由利用去做。

在 Pulsar 中,Broker 反对配置开启音讯去重,用户不须要为了音讯去重去调整 Producer 的代码。启用音讯去重后,即便一条音讯被屡次发送到 Topic 上,这条音讯也只会被长久化到磁盘一次。

如下图,未开启音讯去重时,Producer 发送音讯 1 到 Topic 后,Broker 会把音讯 1 长久化到 BookKeeper,当 Producer 又发送音讯 1 时,Broker 会把音讯 1 再一次长久化到 BookKeeper。开启音讯去重后,当 Producer 再次发送音讯 1 时,Broker 不会把音讯 1 再一次长久化到磁盘。

3.7.1 去重原理

Producer 对每一个发送的音讯,都会采纳递增的形式生成一个惟一的 sequenceID,这个音讯会放在 message 的元数据中传递给 Broker。同时,Broker 也会保护一个 PendingMessage 队列,当 Broker 返回发送胜利 ack 后,Producer 会将 PendingMessage 队列中的对应的 Sequence ID 删除,示意 Producer 工作这个音讯生产胜利。Broker 会记录针对每个 Producer 接管到的最大 Sequence ID 和曾经解决完的最大 Sequence ID。

当 Broker 开启音讯去重后,Broker 会对每个音讯申请进行是否去重的判断。收到的最新的 Sequence ID 是否大于 Broker 端记录的两个维度的最大 Sequence ID,如果大于则不反复,如果小于或等于则音讯反复。音讯反复时,Broker 端会间接返回 ack,不会持续走后续的存储解决流程。

3.8 Delayed message delivery(音讯提早传递)

延时音讯性能容许 Consumer 可能在音讯发送到 Topic 后过一段时间能力生产到这条音讯。在这种机制中,音讯在公布到 Broker 后,会被存储在 BookKeeper 中,当到音讯特定的延迟时间时,音讯就会传递给 Consumer。

下图为音讯提早传递的机制。Broker 在存储提早音讯的时候不会进行非凡的解决。当 Consumer 生产音讯的时候,如果这条音讯设置了延迟时间,则会把这条音讯退出 DelayedDeliveryTracker 中,当到了指定的发送工夫时,DelayedDeliveryTracker 才会把这条音讯推送给消费者。

注:提早消息传递仅在共享订阅模式下无效。在独占和故障转移订阅模式下,将立刻分派提早的音讯。

3.8.1 示例

  • Broker

    # Whether to enable the delayed delivery for messages.
    # If disabled, messages are immediately delivered and there is no tracking overhead.
    delayedDeliveryEnabled=true
    
    # Control the ticking time for the retry of delayed message delivery,
    # affecting the accuracy of the delivery time compared to the scheduled time.
    # Default is 1 second.
    delayedDeliveryTickTimeMillis=1000
  • Producer

    // message to be delivered at the configured delay interval
    producer.newMessage().deliverAfter(3L, TimeUnit.Minute).value("Hello Pulsar!").send();

3.8.2 音讯提早传递原理

在 Pulsar 中,能够通过两种形式实现提早投递。别离为 deliverAfter 和 deliverAt。

deliverAfter 能够指定具体的延迟时间戳,deliverAt 能够指定音讯在多长时间后生产。两种形式实质时一样的,deliverAt 形式下,客户端会计算出具体的延迟时间戳发送给 Broker。

DelayedDeliveryTracker 会记录所有须要提早投递的音讯的 index。index 由 Timestamp、Ledger ID、Entry ID 三局部组成,其中 Ledger ID 和 Entry ID 用于定位该音讯,Timestamp 除了记录须要投递的工夫,还用于提早优先级队列排序。DelayedDeliveryTracker 会依据延迟时间对音讯进行排序,延迟时间最短的放在后面。当 Consumer 在生产时,如果有到期的音讯须要生产,则依据 DelayedDeliveryTracker index 的 Ledger ID、Entry ID 找到对应的音讯进行生产。如下图,Producer 顺次投递 m1、m2、m3、m4、m5 这五条音讯,m2 没有设置延迟时间,所以会被 Consumer 间接生产。m1、m3、m4、m5 在 DelayedDeliveryTracker 会依据延迟时间进行排序,并在达到延迟时间时,顺次被 Consumer 进行生产。

3.9 多租户模式

Pulsar 的云原生架构人造反对多租户,每个租户下还反对多 Namespace(命名空间),非常适合做共享大集群,不便保护。此外,Pulsar 人造反对租户之间资源的逻辑隔离,只有用户的经营管控后盾和监控足够弱小,便能够做到动静隔离大流量租户,避免相互烦扰,还能实现大集群资源的充分利用。

  • Tenant(租户)和 Namespace(命名空间)是 Pulsar 反对多租户的两个外围概念。
  • 在租户级别,Pulsar 为特定的租户预留适合的存储空间、利用受权和认证机制。
  • 在命名空间级别,Pulsar 有一系列的配置策略(Policy), 包含存储配额、流控、音讯过期策略和命名空间之间的隔离策略。

Pulsar 的多租户性质次要体现在 Topic 的 URL 中,构造如下:

persistent://tenant/namespace/topic

租户、命名空间、topic 更直观的关系能够看下图:

3.10 对立音讯模型

  • Pulsar 做了队列模型与流模型的对立,在 Topic 级别只需保留一份数据,同一份数据可屡次生产。以流式、队列等形式计算不同的订阅模型,大大的晋升了灵便度。
  • 同时 Pulsar 通过事务采纳 Exactly-Once(刚好一次)的语义,在进行音讯传输过程中,能够确保数据不丢不重。


3.11 Segmented Streams(分片流)

  • Pulsar 将无界的数据看作是分片的流,分片扩散存储在分层存储(tiered storage)、BookKeeper 集群和 Broker 节点上,而对外提供一个对立的、无界数据的视图。
  • 不须要用户显式迁徙数据,对用户无感知,缩小存储老本并放弃近似有限的存储。

3.12 Geo Replication(跨地区复制)

  • Pulsar 中的跨地区复制是将 Pulsar 中长久化的音讯在多个集群间备份。
  • 在 Pulsar 2.4.0 中新增了复制订阅模式(Replicated-subscriptions),在某个集群生效状况下,该性能能够在其余集群复原消费者的生产状态,从而达到热备模式下音讯服务的高可用。


在这个图中,每当 P1、P2 和 P3 生产者别离将音讯公布到 Cluster-A、Cluster-B 和 Cluster-C 上的 T1 主题时,这些音讯就会立刻跨集群复制。一旦音讯被复制,C1 和 C2 消费者就能够从他们各自的集群中生产这些音讯。

没有跨地区复制,C1 和 C2 消费者就不能应用 P3 生产者公布的音讯。

四、云原生架构

4.1 Pulsar 集群架构

单个 Pulsar 集群由以下三局部组成:

  • 一个或者多个 broker 负责解决和负载平衡 producer 收回的音讯,并将这些音讯分派给 consumer;Broker 与 Pulsar 配置存储交互来解决相应的工作,并将音讯存储在 BookKeeper 实例中(又称 bookies);Broker 依赖 ZooKeeper 集群解决特定的工作,等等。
  • 蕴含一个或多个 bookie 的 BookKeeper 集群负责音讯的长久化存储。
  • 一个 ZooKeeper 集群,用来解决多个 Pulsar 集群之间的协调工作。


Pulsar 分理出 Broker 与 Bookie 两层架构,Broker 为无状态服务,用于公布和生产音讯,而 BookKeeper 专一于存储。Pulsar 存储是分片的,这种架构能够防止扩容时受限制,实现数据的独立扩大和疾速复原。

4.2 Brokers

Pulsar 的 broker 是一个无状态组件,次要负责运行另外的两个组件:

  • 一个 HTTP 服务器(Service discovery),它裸露了 REST 系统管理接口以及在生产者和消费者之间进行 Topic 查找的 API。
  • 一个调度散发器(Dispatcher),它是异步的 TCP 服务器,通过自定义二进制协定利用于所有相干的数据传输。

出于性能思考,音讯通常从 Managed Ledger 缓存中分派进来,除非积压超过缓存大小。如果积压的音讯对于缓存来说太大了,则 Broker 将开始从 BookKeeper 那里读取 Entries(Entry 同样是 BookKeeper 中的概念,相当于一条记录)。

最初,为了反对全局 Topic 异地复制,Broker 会管制 Replicators 追踪本地公布的条目,并把这些条目用 Java 客户端从新公布到其余区域。

4.3 ZooKeeper 元数据存储

Pulsar 应用 Apache ZooKeeper 进行元数据存储、集群配置和协调。

  • 配置存储 Quorum 存储了租户、命名空间和其余须要全局统一的配置项。
  • 每个集群有本人独立的本地 ZooKeeper 保留集群外部配置和协调信息,例如 broker 负责哪几个主题及所有权归属元数据、broker 负载报告,BookKeeper ledger 元数据(这个是 BookKeeper 自身所依赖的)等等。

4.4 BookKeeper 长久化存储

Apache Pulsar 为应用程序提供有保障的信息传递,如果音讯胜利达到 broker,就认为其预期达到了目的地。

为了提供这种保障,未确认送达的音讯须要长久化存储直到它们被确认送达。这种消息传递模式通常称为长久消息传递,在 Pulsar 外部,所有音讯都被保留并同步 N 份,例如,2 个服务器保留四份,每个服务器下面都有镜像的 RAID 存储。

Pulsar 用 Apache BookKeeper 作为长久化存储。BookKeeper 是一个分布式的预写日志(WAL)零碎,有如下几个个性特地适宜 Pulsar 的利用场景:

  • 使 Pulsar 可能利用独立的日志,称为 ledgers,能够随着工夫的推移为 topic 创立多个 ledgers。
  • 它为解决程序音讯提供了十分无效的存储。
  • 保障了多零碎挂掉时 ledgers 的读取一致性。
  • 提供不同的 Bookies 之间平均的 IO 散布的个性。
  • 它在容量和吞吐量方面都具备程度伸缩性。可能通过减少 bookies 立刻减少容量到集群中,并晋升吞吐量。
  • Bookies 被设计成能够承载数千的并发读写的 ledgers。应用多个磁盘设施,一个用于日志,另一个用于个别存储,这样 Bookies 能够将读操作的影响和对于写操作的提早分隔开。

4.4.1 brokers 与 bookies 交互

下图展现了 brokers 和 bookies 是如何交互的:

相比 Kafka、RocketMQ 等 MQ,Pulsar 基于 BookKeeper 的存储、计算拆散架构,使得 Pulsar 的音讯存储能够独立于 Broker 而扩大。

4.4.2 Ledgers

Ledger 是一个只追加的数据结构,并且只有一个写入器,这个写入器负责多个 BookKeeper 存储节点(就是 Bookies)的写入。Ledger 的条目会被复制到多个 bookies。Ledgers 自身有着非常简单的语义:

  • Pulsar Broker 能够创立 ledger,增加内容到 ledger 和敞开 ledger。
  • 当一个 ledger 被敞开后,除非明确的要写数据或者是因为写入器挂掉导致 ledger 敞开,这个 ledger 只会以只读模式关上。
  • 最初,当 ledger 中的条目不再有用的时候,整个 legder 能够被删除(ledger 散布是跨 Bookies 的)。

4.5 Pulsar 代理

Pulsar 客户端和 Pulsar 集群交互的一种形式就是直连 Pulsar brokers。然而,在某些状况下,这种直连既不可行也不可取,因为客户端并不知道 broker 的地址。例如在云环境或者 Kubernetes 以及其余相似的零碎下面运行 Pulsar,直连 brokers 就基本上不可能了。

Pulsar proxy 为这个问题提供了一个解决方案,为所有的 broker 提供了一个网关,如果抉择运行了 Pulsar Proxy,所有的客户都会通过这个代理而不是间接与 brokers 通信。

4.6 Service discovery(服务发现)

连贯到 Pulsar brokers 的客户端须要可能应用单个 URL 与整个 Pulsar 实例通信。

你能够应用本人的服务发现零碎。如果你应用本人的零碎,只有一个要求:当客户端端点执行 HTTP 申请,比方 http://pulsar.us-west.example.com:8080,客户端须要被重定向到一些沉闷在集群所需的 broker,无论通过 DNS、HTTP 或 IP 重定向或其余伎俩。

五、Pulsar 相干组件

5.1 层级存储

  • Infinite Stream:以流的形式永恒保留原始数据
  • 分区的容量不再受限制
  • 充分利用云存储或现有的便宜存储(例如 HDFS)
  • 数据对立表征:客户端无需关怀数据到底存储在哪里



分层存储的卸载机制就充分利用了这种面向分片式架构(segment oriented architecture)。当须要开始卸载数据时,消息日志中的分片就顺次被同步至分层存储中,直到消息日志中所有的分片(除了以后分片之外)都已被写入分层存储后。

默认状况下写入到 BookKeeper 的数据会复制三个物理机正本。然而,一旦分片被封存在 BookKeeper 中后,该分片就不可更改并且能够复制到归档存储中去。长期存储能够达到节俭存储费用的目标。通过应用 Reed-Solomon error correction 机制,还可缩小物理备份数量。

5.2 Pulsar IO(Connector)连接器

  • Pulsar IO 分为输出(Input)和输入(Output)两个模块,输出代表数据从哪里来,通过 Source 实现数据输出。输入代表数据要往哪里去,通过 Sink 实现数据输入。
  • Pulsar 提出了 IO(也称为 Pulsar Connector),用于解决 Pulsar 与周边零碎的集成问题,帮忙用户高效实现工作。
  • 目前 Pulsar IO 反对十分多的连贯集成操作:例如 HDFS、Spark、Flink、Flume、ES、HBase 等。

5.3 Pulsar Functions(轻量级计算框架)

  • Pulsar Functions 是一个轻量级的计算框架,能够给用户提供一个部署简略、运维简略、API 简略的 FASS(Function as a service)平台。Pulsar Functions 提供基于事件的服务,反对有状态与无状态的多语言计算,是对简单的大数据处理框架的无力补充。
  • Pulsar Functions 的设计灵感来自于 Apache Storm、Apache Heron、Apache Flink 这样的流解决引擎,Pulsar Functions 将会拓展 Pulsar 和整个音讯畛域的将来。应用 Pulsar Functions,用户能够轻松地部署和治理 function,通过 function 从 Pulsar topic 读取数据或者生产新数据到 Pulsar topic。

正文完
 0