下一代分布式消息队列Apache Pulsar

2024-09-06 21:58

本文主要是介绍下一代分布式消息队列Apache Pulsar,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Pulsar简介

Apache Pulsar是一个企业级的分布式消息系统,最初由Yahoo开发并在2016年开源,目前正在Apache基金会下孵化。Plusar已经在Yahoo的生产环境使用了三年多,主要服务于Mail、Finance、Sports、 Flickr、 the Gemini Ads platform、 Sherpa以及Yahoo的KV存储。
Pulsar之所以能够称为下一代消息队列,主要是因为以下特性:

  • 线性扩展。能够丝滑的扩容到成百上千个节点(Kafka扩容需要占用很多系统资源在节点间拷贝数据,而Plusar完全不用)

  • 高吞吐。已经在Yahoo的生产环境中经受了考验,每秒数百万消息

  • 低延迟。在大规模的消息量下依然能够保持低延迟(< 5ms)

  • 持久化机制。Plusar的持久化机制构建在Apache BookKeeper之上,提供了写与读之前的IO隔离

  • 基于地理位置的复制。Plusar将多地域/可用区的复制作为首要特性支持。用户只需配置好可用区,消息就会被源源不断的复制到其他可用区。当某一个可用区挂掉或者发生网络分区,plusar会在之后不断的重试。

  • 部署方式的多样化。既可以运行在裸机,也支持目前例如Docker、K8S的一些容器化方案以及不同的云厂商,同时在本地开发时也只需要一行命令即可启动整个环境。

  • Topic支持多种消费模式:exclusive、shared、failover

架构概述

从最上层来看,一个Plusar单元由若干个集群组成,单元内的集群可以互相之前复制数据, plusar中通常有以下几种组件:

  • Broker:负责处理Producer发来的消息并分发给消费者。通过一个全局的ZK集群来处理多种协作式任务,例如说基于地理位置的复制。并将消息存储到BookKeeper中,同时单个集群内也需要有一套ZK集群,来存储一些元数据。

  • BookKeeper集群: 内部包含多个bookies,用于持久化消息。

  • ZooKeeper集群


    640

Broker

在Kafka和RocketMQ中,Broker负责消息数据的存储以及consumer消费位移的存储等,而Plusar中的broker和他们两个有所不同,plusar中的broker是一个无状态的节点,主要负责三件事情:

  • 暴露REST接口用于执行管理员的命令以及topic所有者的查询等

  • 一个用于节点间通讯的异步的TCP服务器,协议目前采用的是Google之前开源的Protocol Buffer

  • 为了支持地域复制,broker会将自己 集群所在的消息发布到其他可用区。

消息会被先发布到BookKeeper中,然后会在Broker本地内存中缓存一份,因此一般来说消息的读取都会从从内存中读取,因此第一条中所说的查找topic所有者就是说,因为BookKeeper中的一个ledger只允许一个writer,因此我们可以调用rest接口获取到某一个topic当前的所有者。

BookKeeper

BookKeeper是一个可横向扩展的、错误容忍的、低延迟的分布式存储服务,BookKeeper中最基本的单位是记录,实际上就一个字节数组,而记录的数组称之为ledger,BK会将记录复制到多个bookies,存储ledger的节点叫做bookies,从而获得更高的可用性和错误容忍性。从设计阶段BK就考虑到了各种故障,Bookies可以宕机、丢数据、脏数据,但是主要整个集群中有足够的Bookies服务的行为就是正确的。
在Pulsar中,每个分区topic是由若干个ledger组成的,而ledger是一个append-only的数据结构,只允许单个writer,ledger中的每条记录会被复制到多个bookies中,一个ledger被关闭后(例如broker宕机了或者达到了一定的大小)就只支持读取,而当ledger中的数据不再需要的时候(例如所有的消费者都已经消费了这个ledger中的消息)就会被删除。
640?wx_fmt=png

Bookkeeper的主要优势在于它可以保证在出现故障时在ledger的读取一致性。因为ledger只能被同时被一个writer写入,因为没有竞争,BK可以更高效的实现写入。在Broker宕机后重启时,Plusar会启动一个恢复的操作,从ZK中读取最后一个写入的Ledger并读取最后一个已提交的记录,然后所有的消费者也都被保证能看到同样的内容。

640?wx_fmt=png

我们知道Kafka在0.8版本之前是将消费进度存储到ZK中的,但是ZK本质上基于单个日志的中心服务,简单来讲,ZK的性能不会随着你增加更多的节点而线性增加,会只会相反减少,因为更多的节点意味着需要将日志同步到更多的节点,性能也会随之下降,因此QPS也会受单机性能影响,因此0.8版本之后就将消费进度存储到了Kafka的Topic中,而RocketMQ最初的版本也类似,有几种不同的实现例如ZK、数据库等,目前版本采用的是存储到本机文件系统中,而Plusar采用了和Kafka类似的思想,Plusar将消费进度也存储到了BK的ledger中。

640?wx_fmt=png

元数据

Plusar中的元数据主要存储到ZK中,例如不同可用区相关的配置会存在全局的ZK中,集群内部的ZK用于存储例如某个topic的数据写入到了那些Ledger、Broker目前的一些埋点数据等等

Plusar核心概念

Topic

发布订阅系统中最核心的概念是topic,简单来说,topic可以理解为一个管道,producer可以往这个管道丢消息,consumer可以从这个管道的另一端读取消息,但是这里可以有多个consumer同时从这个管道读取消息。
640?wx_fmt=png
每个topic可以划分为多个分区,同一个topic下的不同分区所包含的消息都是不同的。每个消息在被添加到一个分区后都会分配一个唯一的offset,在同一个分区内消息是有序的,因此客户端可以根据比如说用户ID进行一个哈希取模从而使得整个用户的消息都发往整个分区,从而一定程度上避免race condition的问题。
通过分区,将大量的消息分散到不同的节点处理从而获得高吞吐。默认情况下,plusar的topic都是非分区的,但是支持通过cli或者接口创建一定分区数目的topic。

640?wx_fmt=png


默认情况下Plusar会自动均衡Producer和Consumer,但有时候客户端想要根据自己的业务规则也进行路由,Plusar默认支持以下几种规则:单分区、轮询、哈希、自定义(即自己实现相关接口来定制路由规则)

消费模式

消费决定了消息具体是如何被分发到消费者的,Plusar支持几种不同的消费模式: exclusive、shared、failover。图示如下:

640?wx_fmt=png

  • Exclusive: 一个topic只能被一个消费者消费。Plusar默认就是这个模式

  • Shared: 共享模式或者叫轮询模式,多个消费者可以连接到同一个topic,消息被依次分发给消费者,当一个消费者宕机或者主动断开连接,那么发到那个消费者的还没有ack的消息会得到重新调度分发给其他消费者。

  • Failover: 多个消费者可以连接同一个topic并按照字典序排序,第一个消费者会开始消费消息,称之为master,当master断开连接,所有未ack和队列中剩下的消息会分发给另一个消费者。
    Plusar目前也支持另一种Reader接口,支持传入一个消息ID,例如说Message.Earliest来从最早的消息开始消费。

总结

Plusar作为下一代分布式消息队列,拥有非常多吸引人的特性,也弥补了一些其他竞品的短板,例如地域复制、多租户、扩展性、读写隔离等等。

640?wx_fmt=gif

640?wx_fmt=jpeg

这篇关于下一代分布式消息队列Apache Pulsar的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1143226

相关文章

SpringBoot集成redisson实现延时队列教程

《SpringBoot集成redisson实现延时队列教程》文章介绍了使用Redisson实现延迟队列的完整步骤,包括依赖导入、Redis配置、工具类封装、业务枚举定义、执行器实现、Bean创建、消费... 目录1、先给项目导入Redisson依赖2、配置redis3、创建 RedissonConfig 配

RabbitMQ 延时队列插件安装与使用示例详解(基于 Delayed Message Plugin)

《RabbitMQ延时队列插件安装与使用示例详解(基于DelayedMessagePlugin)》本文详解RabbitMQ通过安装rabbitmq_delayed_message_exchan... 目录 一、什么是 RabbitMQ 延时队列? 二、安装前准备✅ RabbitMQ 环境要求 三、安装延时队

Redis实现分布式锁全过程

《Redis实现分布式锁全过程》文章介绍Redis实现分布式锁的方法,包括使用SETNX和EXPIRE命令确保互斥性与防死锁,Redisson客户端提供的便捷接口,以及Redlock算法通过多节点共识... 目录Redis实现分布式锁1. 分布式锁的基本原理2. 使用 Redis 实现分布式锁2.1 获取锁

聊聊springboot中如何自定义消息转换器

《聊聊springboot中如何自定义消息转换器》SpringBoot通过HttpMessageConverter处理HTTP数据转换,支持多种媒体类型,接下来通过本文给大家介绍springboot中... 目录核心接口springboot默认提供的转换器如何自定义消息转换器Spring Boot 中的消息

Redis分布式锁中Redission底层实现方式

《Redis分布式锁中Redission底层实现方式》Redission基于Redis原子操作和Lua脚本实现分布式锁,通过SETNX命令、看门狗续期、可重入机制及异常处理,确保锁的可靠性和一致性,是... 目录Redis分布式锁中Redission底层实现一、Redission分布式锁的基本使用二、Red

redis和redission分布式锁原理及区别说明

《redis和redission分布式锁原理及区别说明》文章对比了synchronized、乐观锁、Redis分布式锁及Redission锁的原理与区别,指出在集群环境下synchronized失效,... 目录Redis和redission分布式锁原理及区别1、有的同伴想到了synchronized关键字

分布式锁在Spring Boot应用中的实现过程

《分布式锁在SpringBoot应用中的实现过程》文章介绍在SpringBoot中通过自定义Lock注解、LockAspect切面和RedisLockUtils工具类实现分布式锁,确保多实例并发操作... 目录Lock注解LockASPect切面RedisLockUtils工具类总结在现代微服务架构中,分布

Apache Ignite 与 Spring Boot 集成详细指南

《ApacheIgnite与SpringBoot集成详细指南》ApacheIgnite官方指南详解如何通过SpringBootStarter扩展实现自动配置,支持厚/轻客户端模式,简化Ign... 目录 一、背景:为什么需要这个集成? 二、两种集成方式(对应两种客户端模型) 三、方式一:自动配置 Thick

Apache Ignite缓存基本操作实例详解

《ApacheIgnite缓存基本操作实例详解》文章介绍了ApacheIgnite中IgniteCache的基本操作,涵盖缓存获取、动态创建、销毁、原子及条件更新、异步执行,强调线程池注意事项,避免... 目录一、获取缓存实例(Getting an Instance of a Cache)示例代码:二、动态

RabbitMQ消息总线方式刷新配置服务全过程

《RabbitMQ消息总线方式刷新配置服务全过程》SpringCloudBus通过消息总线与MQ实现微服务配置统一刷新,结合GitWebhooks自动触发更新,避免手动重启,提升效率与可靠性,适用于配... 目录前言介绍环境准备代码示例测试验证总结前言介绍在微服务架构中,为了更方便的向微服务实例广播消息,