Apache Pulsar千亿级消息引擎-基本介绍

一、什么是云原生

技术的变革,一定是思想先行,云原生是一种构建和运行应用程序的方法,是一套技术体系和方法论。云原生(CloudNative)是一个组合词,Cloud+Native。Cloud表示应用程序位于云中,而不是传统的数据中心;Native表示应用程序从设计之初即考虑到云的环境,原生为云而设计,在云上以最佳姿势运行,充分利用和发挥云平台的弹性+分布式优势。

Pivotal公司的Matt Stine于2013年首次提出云原生(CloudNative)的概念;2015年,云原生刚推广时,Matt Stine在《迁移到云原生架构》一书中定义了符合云原生架构的几个特征:12因素、微服务、自敏捷架构、基于API协作、扛脆弱性;到了2017年,Matt Stine在接受InfoQ采访时又改了口风,将云原生架构归纳为模块化、可观察、可部署、可测试、可替换、可处理6特质;而Pivotal最新官网对云原生概括为4个要点:DevOps+持续交付+微服务+容器

Apache Pulsar千亿级消息引擎-基本介绍_第1张图片

2015年云原生计算基金会(CNCF)成立,CNCF掺和进来后,最初把云原生定义为包括:容器化封装+自动化管理+面向微服务;到了2018年,CNCF又更新了云原生的定义,把服务网格(Service Mesh)和声明式API给加了进来。

可见,不同的人和组织对云原生有不同的定义,相同的人和组织在不同时间点对云原生也有不同的定义,真是乱的一匹,搞得鄙人非常晕菜,我的应对很简单,选一个我最容易记住和理解的定义:DevOps+持续交付+微服务+容器。

总而言之,符合云原生架构的应用程序应该是:采用开源堆栈(K8S+Docker)进行容器化,基于微服务架构提高灵活性和可维护性,借助敏捷方法、DevOps支持持续迭代和运维自动化,利用云平台设施实现弹性伸缩、动态调度、优化资源利用率。

云原生构建应用简便快捷,部署应用轻松自如、运行应用按需伸缩。优点不一而足,缺点微乎其微;秒杀传统Web框架,吊打祖传IT模式,实在是保命**、评优晋级不可多得的终极绝密武器。

云元素的四要素

微服务:几乎每个云原生的定义都包含微服务,跟微服务相对的是单体应用,微服务有理论基础,那就是康威定律,指导服务怎么切分,很玄乎,凡是能称为理论定律的都简单明白不了,不然就忒没b格,大概意思是组织架构决定产品形态,不知道跟马克思的生产关系影响生产力有无关系。

微服务架构的好处就是按function切了之后,服务解耦,内聚更强,变更更易;另一个划分服务的技巧据说是依据DDD来搞。

容器化:Docker是应用最为广泛的容器引擎,在思科谷歌等公司的基础设施中大量使用,是基于LXC技术搞的,容器化为微服务提供实施保障,起到应用隔离作用,K8S是容器编排系统,用于容器管理,容器间的负载均衡,谷歌搞的,Docker和K8S都采用Go编写,都是好东西。

DevOps:这是个组合词,Dev+Ops,就是开发和运维合体,不像开发和产品,经常刀刃相见,实际上DevOps应该还包括测试,DevOps是一个敏捷思维,是一个沟通文化,也是组织形式,为云原生提供持续交付能力。

持续交付:持续交付是不误时开发,不停机更新,小步快跑,反传统瀑布式开发模型,这要求开发版本和稳定版本并存,其实需要很多流程和工具支撑。

如何云原生?

首先,云原生借了云计算的东风,没有云计算,自然没有云原生,云计算是云原生的基础。

随着虚拟化技术的成熟和分布式框架的普及,在容器技术、可持续交付、编排系统等开源社区的推动下,以及微服务等开发理念的带动下,应用上云已经是不可逆转的趋势

云计算的3层划分,即基础设施即服务(IaaS)、平台即服务(PaaS)、软件即服务(SaaS)为云原生提供了技术基础和方向指引,真正的云化不仅仅是基础设施和平台的变化,应用也需要做出改变,摈弃传统的土方法,在架构设计、开发方式、部署维护等各个阶段和方面都基于云的特点,重新设计,从而建设全新的云化的应用,即云原生应用。

1.本地部署的传统应用往往采用c/c++、企业级java编写,而云原生应用则需要用以网络为中心的go、node.js等新兴语言编写。

2.本地部署的传统应用可能需要停机更新,而云原生应用应该始终是最新的,需要支持频繁变更,持续交付,蓝绿部署。

3.本地部署的传统应用无法动态扩展,往往需要冗余资源以抵抗流量高峰,而云原生应用利用云的弹性自动伸缩,通过共享降本增效。

4.本地部署的传统应用对网络资源,比如ip、端口等有依赖,甚至是硬编码,而云原生应用对网络和存储都没有这种限制。

5.本地部署的传统应用通常人肉部署手工运维,而云原生应用这一切都是自动化的。

6.本地部署的传统应用通常依赖系统环境,而云原生应用不会硬连接到任何系统环境,而是依赖抽象的基础架构,从而获得良好移植性。

7.本地部署的传统应用有些是单体(巨石)应用,或者强依赖,而基于微服务架构的云原生应用,纵向划分服务,模块化更合理。

可见,要转向云原生应用需要以新的云原生方法开展工作,云原生包括很多方面:基础架构服务、虚拟化、容器化、容器编排、微服务。幸运的是,开源社区在云原生应用方面做出了大量卓有成效的工作,很多开源的框架和设施可以通过拿来主义直接用,2013年Docker推出并很快成为容器事实标准,随后围绕容器编排的混战中,2017年诞生的k8s很快脱颖而出,而这些技术极大的降低了开发云原生应用的技术门槛。

二、Apache Pulsar基本介绍

Apache Pulsar是一个云原生企业级的发布订阅(pub-sub)消息系统,最初由Yahoo开发并于2016年开源并捐献给Apache,2018成为Apache顶级项目。

Pulsar功能特性:

  1. 多租户模式
  2. 灵活的消息系统
  3. 云原生架构
  4. 分片流(segmented Sreams)
  5. 支持跨地域复制

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

1. 多租户模式

  • 租户和命名空间(namespace)是 Pulsar 支持多租户的两个核心概念。
  • 在租户级别,Pulsar 为特定的租户预留合适的存储空间、应用授权与认证机制。
  • 在命名空间级别,Pulsar 有一系列的配置策略(policy),包括存储配额、流控、消息过期策略和命名空间之间的隔离策略。

Apache Pulsar千亿级消息引擎-基本介绍_第2张图片

2. 灵活的消息系统

  • 比kafka更高的吞吐量和低延迟
  • 无缝支持上百万个topics
  • 支持多种消息订阅模式 (exclusive[独享] & shared[共享] & failover[灾备])
    • Exclusive(独享) - 一个订阅只能有一个消息者消费消息
    • Shared(共享) - 一个订阅中同时可以有多个消费者,多个消费者共享Topic中的消息
    • Fail-Over(灾备) - 一个订阅同时只有一个消费者,可以有多个备份消费者。一旦主消费者故障则备份消费者接管。不会出现同时有两个活跃的消费者。
  • 通过持久化存储BookKeeper保障消息的传递
  • 轻量级Serverless计算框架Pulsar Functions提供了流式数据处理能力。
  • Pulsar 做了队列模型和流模型的统一,在 Topic 级别只需保存一份数据,同一份数据可多次消费。以流式、队列等方式计算不同的订阅模型大大提升了灵活度。
  • 同时pulsar通过事务采用Exactly-Once(精准一次)在进行消息传输过程中, 可以确保数据不丢不重

 队列模式:先进先出,直进直出Apache Pulsar千亿级消息引擎-基本介绍_第3张图片

流模式:数据经过转换之后再次存储进topic中

Apache Pulsar千亿级消息引擎-基本介绍_第4张图片

3.云原生架构

Pulsar 使用计算与存储分离的云原生架构,数据从 Broker 搬离,存在共享存储内部。上层是无状态 Broker,复制消息分发和服务;下层是持久化的存储层 Bookie 集群。Pulsar 存储是分片的,这种构架可以避免扩容时受限制,实现数据的独立扩展和快速恢复。

Apache Pulsar千亿级消息引擎-基本介绍_第5张图片

 4.分片流(Segmented Streams)

Pulsar 将无界的数据看作是分片的流,分片分散存储在分层存储(tiered storage)、BookKeeper 集群和 Broker 节点上,而对外提供一个统一的、无界数据的视图。即底层存储较为复杂,甚至是针对topic级别都有分片存储。其次,不需要用户显式迁移数据,减少存储成本并保持近似无限的存储。用户只需关注如何使用,而不是去研究底层数据如何存储,减少了用户的学习成本。

Apache Pulsar千亿级消息引擎-基本介绍_第6张图片

5.支持跨地域复制

Pulsar 中的跨地域复制是将 Pulsar 中持久化的消息在多个集群间备份。在 Pulsar 2.4.0 中新增了复制订阅模式(Replicated-subscriptions),在某个集群失效情况下,该功能可以在其他集群恢复消费者的消费状态,从而达到热备模式下消息服务的高可用。

进行了不同集群之间的数据的同步性。

Apache Pulsar千亿级消息引擎-基本介绍_第7张图片

三、Apache Pulsar基本架构

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

  • 多个 broker 负责处理和负载均衡 producer 发出的消息,并将这些消息分派给 consumer;Broker 与 Pulsar 配置存储交互来处理相应的任务,并将消息存储在 BookKeeper 实例中(又称 bookies);Broker 依赖 ZooKeeper 集群处理特定的任务,等等。
  • 多个 bookie 的 BookKeeper 集群负责消息的持久化存储。
  • 一个zookeeper集群,用来处理多个Pulsar集群之间的协调任务。

还是这张图:

Apache Pulsar千亿级消息引擎-基本介绍_第8张图片

Broker

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

  • 一个HTTP服务器,它暴露了REST系统管理接口以在生产者和消费者之间进行Topic查找的API
  • 一个调度分发器,它是异步的TCP服务器,通过自定义二进制协议应用于所有相关的数据传输

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

最后,为了支持全局Topic异地复制,Broker会控制Replicators追踪本地发布的条目,并把这些条目用Java 客户端重新发布到其他区域

Zookeeper

Pulsar使用Zookeeper进行元数据存储、集群配置和协调

  • 配置存储:存储租户,命名域和其他需要全局一致的配置项
  • 每个集群由自己独立的Zookeeper保存集群内部配置和协调信息,例如归属信息,broker负载报告。BookKeeper ledger信息等等

BookKeeper

  • Pulsar使用BookKeeper进行持久化存储

关于BookKeeper的介绍可以见此文章5张图带你了解Pulsar的存储引擎BookKeeper_dotNET跨平台的博客-CSDN博客

 Apache Pulsar 为应用程序提供有保证的信息传递, 如果消息成功到达broker, 就认为其预期到达了目的地。

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

​ Pulsar用Apache bookKeeper作为持久化存储。Bookeeper是一个分布式的预写日志(WAL)系统,有如下几个特性,特别适合Pulsar的应用场景:

  • 使Pulsar能够利用独立的日志,称为Ledgers、可以随着时间的推移为Topic创建多个Ledgers
  • 它为处理顺序消息提供了非常有效的存储
  • 保证了多系统挂掉时Ledgers的读取一致性
  • 提供不同的Bookies之间均匀IO分布的特性
  • 它在容量和吞吐量方面都具有水平伸缩性。
  • 能够通过将bookies增加都集群中来提升吞吐量
  • Bookies被设计成可以承载数千的并发读写的ledgers。使用多个磁盘设备(一个用于日志,另一个用于一般存储),这样Bookies可以将读操作的影响和对于写操作的延迟分隔开

Ledger介绍

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

  • Pulsar Broker可以创建、添加内容和关闭Ledger
  • 当一个Ledger被关闭后,除非明确的要写数据或者是因为写入器挂掉导致Ledger关闭,ledger将会以只读打开。
  • 当ledger的条目不再有用的时候,整个ledger可以被删除(Ledger的分布式跨Bookie的)

Pulsar代理(Pulsar Proxy)

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

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

四、Apache Pulsar与Kafka对比

1) 模型概念

  • Kafka: producer – topic – consumer group – consumer
  • Pulsar: producer – topic -subsciption- consumer

2) 消息消费模式

  • Kafka: 主要集中在流(Stream) 模式, 对单个partition是独占消费, 没有共享(Queue)的消费模式
  • Pulsar: 提供了统一的消息模型和API. 流(Stream) 模式 – 独占和故障切换订阅方式 ; 队列(Queue)模式 – 共享订阅的方式

3) 消息确认(ack)

Kafka: 使用偏移量 offset

  • Pulsar: 使用专门的cursor管理. 累积确认和kafka效果一样; 提供单条或选择性确认

4) 消息保留:

  • Kafka: 根据设置的保留期来删除消息, 有可能消息没被消费, 过期后被删除, 不支持TTL
  • Pulsar: 消息只有被所有订阅消费后才会删除, 不会丢失数据,. 也运行设置保留期, 保留被消费的数据 . 支持TTL

综合与本质:

Apache Kafka和Apache Pulsar都有类似的消息概念。 客户端通过主题与消息系统进行交互。 每个主题都可以分为多个分区。 然而,Apache Pulsar和Apache Kafka之间的根本区别在于Apache Kafka是以分区为存储中心,而Apache Pulsar是以Segment为存储中心。

Apache Pulsar千亿级消息引擎-基本介绍_第9张图片

对比总结: Apache Pulsar将高性能的流(Apache Kafka所追求的)和灵活的传统队列(RabbitMQ所追求的)结合到一个统一的消息模型和API中。 Pulsar使用统一的API为用户提供一个支持流和队列的系统,且具有同样的高性能。 

性能对比:

Pulsar 表现最出色的就是性能,Pulsar 的速度比 Kafka 快得多,美国德克萨斯州一家名为 GigaOm (https://gigaom.com/) 的技术研究和分析公司对 Kafka 和 Pulsar 的性能做了比较,并证实了这一点。

Apache Pulsar千亿级消息引擎-基本介绍_第10张图片

Apache Pulsar千亿级消息引擎-基本介绍_第11张图片

扩展说明: kafka目前存在的痛点

1)  Kafka 很难进行扩展,因为 Kafka 把消息持久化在 broker 中,迁移主题分区时,需要把分区的数据完全复制到其他 broker 中,这个操作非常耗时。

2) 当需要通过更改分区大小以获得更多的存储空间时,会与消息索引产生冲突,打乱消息顺序。因此,如果用户需要保证消息的顺序,Kafka 就变得非常棘手了。

3) 如果分区副本不处于 ISR(同步)状态,那么 leader 选取可能会紊乱。一般地,当原始主分区出现故障时,应该有一个 ISR 副本被征用,但是这点并不能完全保证。若在设置中并未规定只有 ISR 副本可被选为 leader 时,选出一个处于非同步状态的副本做 leader,这比没有 broker 服务该 partition 的情况更糟糕。

4) 使用 Kafka 时,你需要根据现有的情况并充分考虑未来的增量计划,规划 broker、主题、分区和副本的数量,才能避免 Kafka 扩展导致的问题。这是理想状况,实际情况很难规划,不可避免会出现扩展需求。

5) Kafka 集群的分区再均衡会影响相关生产者和消费者的性能。

6) 发生故障时,Kafka 主题无法保证消息的完整性(需要扩展时极有可能丢失消息)。

7) 使用 Kafka 需要和 offset 打交道,这点让人很头痛,因为 broker 并不维护 consumer 的消费状态。

8) 如果使用率很高,则必须尽快删除旧消息,否则就会出现磁盘空间不够用的问题。

9) 众所周知,Kafka 原生的跨地域复制机制(MirrorMaker)有问题,即使只在两个数据中心也无法正常使用跨地域复制。因此,甚至 Uber 都不得不创建另一套解决方案来解决这个问题,并将其称为 uReplicator (https://eng.uber.com/ureplicator/)。

10) 要想进行实时数据分析,就不得不选用第三方工具,如 Apache Storm、Apache Heron 或 Apache Spark。同时,你需要确保这些第三方工具足以支撑传入的流量。

11) Kafka 没有原生的多租户功能来实现租户的完全隔离,它是通过使用主题授权等安全功能来完成的。 

五、Apache Pulsar主要功能介绍及使用

多租户

多租户是一种架构,目的是为了让多用户环境下使用同一套程序,且保证用户间数据隔离        

简单讲:在一台服务器上运行单个应用实例,它为多个租户(客户)提供服务。

Apache Pulsar 最初诞生于雅虎,当时就是为了解决雅虎内部各个部门之间数据的协调,所以多租户特性显得至关重用,Pulsar 从诞生之日起就考虑到多租户这一特性,并在后续的实现过程中,将其不断的完善。 多租户这一特性,使得各个部门之间可以共享同一份数据,不用单独部署独立的系统来操作数据,很好的保证了各部门间数据一致性的问题,同时简化维护成本。

Pulsar 的多租户设计符合上述要求:

  • 使用身份验证、授权和 ACL(访问控制列表)确保其安全性
  • 为每个租户强制执行存储配额
  • 支持在运行时更改隔离机制,从而实现操作成本低和管理简单

Pulsar的多租户性质主要体现在topic的URL中, 其结构如下:

persistent://tenant/namespace/topic

从URL中可以看出tenant(租户)是topic最基本的单元(比命名空间和topic名称更为基本)

Apache Pulsar千亿级消息引擎-基本介绍_第12张图片

 

Pulsar多租户的相关特性_安全性(认证和授权)

一个多租户系统需要在租户内提供系统级别的安全性,细分来讲,主要可以归类为一下两点:

  • 租户只能访问它有权限访问的 topics
  • 不允许访问它无法访问的 topics

在 Pulsar 中,多租户的安全性是通过身份验证和授权机制实现的。当 client 连接到 pulsar broker 时,broker 会使用身份验证插件来验证此客户端的身份,然后为其分配一个 string 类型的 role token。role token 主要有如下作用:

  • 判断 client 是否有对 topics 进行生产或消费消息的权限
  • 管理租户属性的配置     

Pulsar 目前支持一下几种身份认证, 同时支持自定义实现自己的身份认证程序

  • TLS 客户端身份认证
  • 雅虎的身份认证系统: Athenz
  • Kerberos
  • JSON Web Token 认证

Apache Pulsar千亿级消息引擎-基本介绍_第13张图片

Pulsar多租户的相关特性_隔离性 

隔离性主要分为如下两种:

  • 软隔离: 通过磁盘配额,流量控制和限制等手段         
存储: 

   Apache Pulsar 使用Bookkeeper来作为其存储层, bookie是Bookkeeper的实例, Bookkeeper本身就是具有I/O分离(读写分离)的特性,可以很多的做好IO隔离, 提升读写的效率

   同时, 不同的租户可以为不同的NameSpace配置不同的存储配额, 当租户内消息的大小达到了存储配额的限制, Pulsar会采取相应的措施, 例如: 阻止消息生成, 抛异常 或丢弃数据等

Broker:

   每个Borker使用的内存资源都是有上限的, 当Broker达到配置的CPU或内存使用的阈值后, Pulsar会迅速的将流量转移到负载较小的Broker处理

   在生产和消费方面, Pulsar都可以进行流量控制,租户可以配置发送和接收的速率,避免出现一个客户端占用当前Broker的所有处理资源
  • 硬隔离: 物理资源隔离
Pulsar 允许将某些租户或名称空间与特定 Broker 进行隔离。这可确保这些租户或命名空间可以充分利用该特定 Broker 上的资源。

Pulsar的名称空间

namespace是Pulsar中最基本的管理单元,在namespace这一层面,可以设置权限,调整副本设置,管理跨集群的消息复制,控制消息策略和执行关键操作。一个主题topic可以继承其所对应的namespace的属性,因此我们只需对namespace的属性进行设置,就可以一次性设置该namespace中所有主题topic的属性。

namespace有两种,分别是本地的namespace和全局的namespace:

  • 本地namespace——仅对定义它的集群可见。
  • 全局namespace——跨集群可见,可以是同一个数据中心的集群,也可以是跨地域中心的集群,这依赖于是否在namespace中设置了跨集群拷贝数据的功能。          

虽然本地namespace和全局namespace的作用域不同,但是只要对他们进行适当的设置,都可以跨团队和跨组织共享。一旦生产者获得了namespace的写入权限,那么它就可以往namespace中的所有topic主题写入数据,如果某个主题不存在,则在生产者第一次写入数据时动态创建。

你可能感兴趣的:(学习笔记,apache,big,data,pulsar,消息队列)