从Kafka到Pulsar:数据流演进之路 | 青训营笔记

88 阅读6分钟

这是我参与「第四届青训营 」笔记创作活动的的第12天

一、消息队列概述

  1. 分布式与集群

    如果一个业务被拆分为多个子业务部署在不同的服务器上,那就是分布式应用;如果是同一个业务部署在多台服务器上,那就是集群。

  2. 分布式系统间通信的方式:

    远程过程调用(RPC),将单机环境下的过程调用加以扩充后延伸到分布式系统环境,指用户可以像调用本地过程一样调用不同地域的不同计算机上的过程从而使得应用程序设计人员不必设计和开发有关发送和接收信息的实现细节,跨语言。

    消息队列,分布式系统中重要的组件,主要解决应用解耦,异步消息,流量削锋等问题,目前使用较多的消息队列有ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ

二、Kafka介绍

kafka是一个分布式的,分区的消息(官方称之为commit log)服务。它提供一个消息系统应该 具备的功能,但是确有着独特的设计。可以这样来说,Kafka借鉴了JMS规范的思想,但是确 并 没有完全遵循JMS规范。

发送消息

kafka自带了一个producer命令客户端,可以从本地文件中读取内容,或者我们也可以以命令行中直接输入内容,并将这些内容以消息的形式发送到kafka集群中。在默认情况下,每一个行会被当做成一个独立的消息。使用kafka的发送消息的客户端,指定发送到的kafka服务器地址和topic。

消费消息

对于consumer,kafka同样也携带了一个命令行客户端,会将获取到内容在命令中进行输 出, 默认是消费最新的消息 。使用kafka的消费者消息的客户端,从指定kafka服务器的指定 topic中消费消息

所谓的偏移量的意思就是现在消费者消费到哪里了,实际上是个队列,就是假如现在有4条消息,是在这个消费者2上线之前发的,已经被消费者1消费了,这时候偏移量在最后一条消息,这个消费者上线之后可以选择是从头消费还是从最后一条加一的偏移量消费(也就是这个例子的第五条消费)

三、Pulsar详解

1. pulsar是什么?

Apache Pulsar is a cloud-native, distributed messaging and streaming platform。和kafka比较像,由于站在了前人的肩膀上,它做的要比kafka更加出色。

pulsar的关键特性如下:

  1. 云原生架构(计算与存储分离),无缝支持跨集群复制
  2. 比kafka更高的吞吐量和低延迟
  3. 无缝支持上百万个topics
  4. 支持多种消息订阅模式 (exclusive & shared & failover)
  5. 通过持久化存储BookKeeper保障消息的传递
  6. 轻量级Serverless计算框架Pulsar Functions提供了流式数据处理能力。
  7. 提供分层存储能力,释放BookKeeper的空间:将老数据or长期不用的数据放到AWS S3等

Pulsar架构模型类似于Client->Proxy->Server

2. pulsar的架构简介

2.1 pulsar的分层架构

与其他消息系统不同,Pulsar抽象为两层架构:

  • 无状态服务层:处理消息的Broker组成
  • 有状态存储层:BookKeeper存储节点组成,可以持久化的存储消息

Broker无状态层

与kafka不同,Pulsar Broker不存储实际的数据,而是将消息存储在BookKeeper中,仅仅拥有Topic/Partitions的代理权。它屏蔽了msg复杂的读写流程,保证了数据一致性和负载均衡。meta信息是存储在zookeeper中,消息存储到BookKeeper中。

BookKeeper

Pulsar用 Apache BookKeeper作为持久化存储。 BookKeeper是一个分布式的预写日志(WAL)系统,特性主要有:

  • 支持创建多个独立的ledgers(Fragment/Segment)随着时间的推移,底层数据以 Ledger形式存储,Pulsar会为Topic创建多个ledgers。
  • 为按条目复制的顺序数据提供了非常高效的存储。
  • 保证了多系统挂掉时ledgers的读取一致性。
  • 提供不同的Bookies(BookKeeper实例)均匀的IO分布的特性。
  • 容量和吞吐量都能水平扩展。并且容量可以通过在集群内添加更多的Bookies立刻提升。
  • Bookies被设计成可以承载数千的并发读写的ledgers。 使用多个磁盘设备,一个用于日志,另一个用于一般存储,这样Bookies可以将读操作的影响和对于写操作的延迟分隔开。

除了消息数据,cursors也会被持久化入BookKeeper。 Cursors是消费端订阅消费的位置。 BookKeeper让Pulsar可以用一种可扩展的方式存储消费位置

2.2 pulsar的订阅模式

  • 独占订阅:一个消费组只有一个消费者订阅消息。
  • 故障切换(Failover):多个消费者可以加入同一订阅,但是只有一个消费者被选为主消费者,其他消费者为故障转移者。
  • 共享订阅:订阅组可以挂多个消费者,但一个消息只会传递给一个消费者。

2.3 broker故障处理fencing

Pulsar的broker不存储状态,类似于Topic的proxy,拥有对Topic的代理权,当broker故障时,Pulsar需要将这些topic转移给正常的brokers,这个过程称为fencing。大致流程为:

  1. Topic X 的当前拥有者(B1)不可用(通过Zookeeper);
  2. 其他Broker(B2)将Topic X 的当前Ledger状态从OPEN修改为IN_RECOVERY
  3. B2向Ledger的当前Fragment的Bookies发送fence信息并等待(Qw-Qa) + 1个Bookies响应。收到此响应数后Ledger将变成fenced。如果旧的Broker仍然处于活跃状态则无法再进行写入,因为无法获得Qa确认(由于fencing导致异常响应);
  4. B2然后从Fragment的Bookies获得他们最后确认的条目是什么。它需要最新条目的ID,然后从该点开始向前读。它确保从哪一点开始的所有条数(可能以前未向Pulsar Broker承认)都会被复制到Qw Bookies。一旦B2无法读取并复制任何条目,Ledger将完全恢复;
  5. B2将Ledger的状态更改为CLOSED;
  6. B2现在可以创建新的Ledger并接受写入请求。

整个过程类似于raft的选举,选举过程中不处理读写请求。