这两年pulsar发展比较快,有好多大公司引入了pulsar,相关的资料和课程也多了,今天一起来了解一下pulsar这款中间件。

下图是几款消息中间件的历史:

2012年pulsar在Yahoo内部开发,2016年开源并捐献给Apache,2018成为Apache顶级项目。

1架构

pulsar的架构图如下:

总结一下,pulsar有下面的几个特性。

1.1 计算存储分离

pulsar采用计算和存储相分离的架构,Broker集群负责把producer发出的消息发送给consumer,同时承担负载均衡的作用。

Pulsar用 Apache BookKeeper作为持久化存储,Broker持有BookKeeper client,把未确认的消息发送到BookKeeper进行保存。

BookKeeper是一个分布式的WAL(Write Ahead Log)系统,pulsar使用BookKeeper有下面几个便利:

  • 可以为Topic创建多个ledgers

Ledger是一个只追加的数据结构,并且只有一个writer,这个writer负责多个BookKeeper存储节点(就是Bookies)的写入。Ledger的条目会被复制到多个bookies。

  • Broker可以创建、关闭和删除Ledger,也可以追加内容到Ledger。

  • Ledger被关闭后,只能以只读状态打开,除非要明确地写数据或者是因为writer挂掉导致的关闭。

  • Ledger只能有writer这一个进程写入,这样写入不会有冲突,所以写入效率很高。如果writer挂了,Ledger会启动恢复进程来确定Ledger最终状态和最后提交的日志,保证之后所有Ledger进程读取到相同的内容。

  • 除了保存消息数据外,还会保存cursors,也就是消费端订阅消费的位置。这样所有cursors消费完一个Ledger的消息后这个Ledger就可以被删除,这样可以实现ledgers的定期翻滚从头写。

1.2 节点对等

从架构图可以看出,broker节点不保存数据,所有broker节点都是对等的。如果一个broker宕机了,不会丢失任何数据,只需要把它服务的topic迁移到一个新的broker上就行。

Broker的topic拥有多个逻辑分区,同时每个分区又有多个segment,writer写数据时,首先会选择Bookies,比如图中的segment1,选择了Bookie1、Bookie2、Bookie4,然后并发地写下去。这样这三个节点并没有主从关系,协调完全依赖于writer,因此它们也是对等的。

1.3 扩展和扩容

在遇到双十一等大流量的场景时,必须增加consumer,这时因为Broker不存储任何数据,可以方便的增加broker。broker集群会有一个或多个broker做消息负载均衡,当新的broker加入后,流量会自动从压力大的broker上迁移过来。

对于BookKeeper,如果对存储要求变高,比如之前存储2个副本,现在需要存储4个副本,这时可以单独扩展bookies而不用考虑broker。因为节点对等,之前节点的segment又堆放整齐,加入新节点并不用搬移数据。writer会感知新的节点并优先选择使用。

1.4 容错机制

对于broker,因为不保存任何数据,如果节点宕机了,就相当于客户端断开,重新连接其他的broker就可以了。

对于BookKeeper,因为保存了多份副本,并且这些副本都是对等的,没有主从关系,所以当一个节点宕机后,不用立即恢复,后台有一个线程会检查宕机节点的数据备份进行恢复。

2 BookKeeper简介

从上一节的讲解看出,Apache Bookkeeper是一个易扩展、高可用、运维简单的分布式存储系统。这节再看一下Bookkeeper的其他三个特性。

2.1 客户端数量

我们知道,在Kafka中,客户端只能从leader节点读取数据。但在BookKeeper中,客户端可以从任何一个bookie副本读取数据,这有三个好处:

  • 增加了读高可用

  • 把客户端流量平均分配到了不同的bookie

  • 可以通过增加客户端数量来提高读取效率

客户端和服务器通信采用Netty实现异步I/O。网络I/O使用单个TCP连接进行多路复用,这就以很少的资源消耗实现了非常高的吞吐量。

2.3 I/O隔离

为什么要做I/O隔离?在大多数消息系统中,如果consumer处理慢,可能会导致消息积压。这迫使存储系统从持久存储介质中读取数据。当存储系统I/O组件共享写入、追尾读、追赶读的单一路径时,就会出现I/O抖动及页面缓存的换入换出。

写入和追尾读对可预测的低延迟有较高要求,而追赶读则对吞吐量的要求比较高,分离这三个路径很重要。

在BookKeeper中,bookie使用三条独立的I/O路径,分别用于写入、追尾读、追赶读。如下图:

参考[1]

3 多租户

Pulsar可以使用多租户来管理大集群。Pulsar的租户可以跨集群分布,每个租户都可以有单独的认证和授权机制。租户也是存储配额、消息TTL和隔离策略的管理单元。

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

persistent://tenant/namespace/topic

可以看到,租户是topic的最基本单位。

假如一个公司有三个部门,tenant1、tenant2、tenant3,可以分配三个租户,这三个租户互不干扰,如下图:

如果消息平台不支持租户,那部门之间想要隔离,就要给每个部门部署一套集群,运维成本非常高。

4 消息模型

4.1 消息结构

首先看一下Pulsar的消息结构,如下图:

消息流由多个独立的segment组成,(这里的segment就是上面讲的ledger),segment又包含独立的entry,entry又由独立的message组成。这里的message就是consumer发来的消息。

可以看到,一个message的id组成包括Ledger-id,entry-id,batch-index,partition-index。

需要注意两点:

  • segment和entry都是BookKeeper里面的概念。

  • pulsar作为消息平台时,一个message就是一个entry。当pulsar作为流平台时,为了提高吞吐量,会开启batch,这样多个message组成一个entry。

4.2 创建过程

消息的创建过程如下图:

消息创建后主要经历下面几步:

  1. 选择一个partition

  2. 发送到管理这个partition的broker

  3. broker将消息并发的发送给N个bookie,这个N是可以配置的。broker持有BookKeeper的客户端,也就是writer,writer收到写请求后,会并发的写入N个bookie。上图中N=3。

  4. bookie写完消息后会给broker一个回复,broker收到指定数量的确认消息后就会认为写BookKeeper成功。这个数量是这个配置的,比如M,M越大,写BookKeeper延迟越大,数据一致性越高。因此这个配置要对一致性和延迟到进行。

5 消费模型

5.1 概要

Pulsar的消费模型如下图:

producer将消息发送给topic,topic下有多个partition,partition下面又有多个broker。

broker负责接收消息并把消息分配给给consumer,并把消息写到BookKeeper。

broker还具有限流功能,可以根据限流阈值对producer的消息进行限流。

consumer并不能直接从broker中获取消息,consumer和broker之间有一个Subscription,Consumer通过Subscription获取消息。

5.2 subscription

subscription有四种类型:

  • 独占模式(Exclusive):同一个topic只能有一个消费者,如果多个消费者,就会出错。

  • 灾备模式(Failover):同一个topic可以有多个消费者,但是只能有一个消费者消费,其他消费者作为故障转移备用,如果当前消费者出了故障,就从备用消费者中选择一个进行消费。如下图:

  • 共享模式(Shared):同一个topic可以由多个消费者订阅和消费。消息通过round robin轮询机制分发给不同的消费者,并且每个消息仅会被分发给一个消费者。当消费者断开,发送给它的没有被消费的消息还会被重新分发给其它存活的消费者。如下图:

  • Key_Shared:消息和消费者都会绑定一个key,消息只会发送给绑定同一个key的消费者。如果有新消费者建立连接或者有消费者断开连接,就需要更新一些消息的key。如下图:

跟Shared模式相比,Key_Shared的好处是既可以让消费者并发地消费消息,又能保证同一Key下的消息顺序。

5.3 Cursor

当多个consumer订阅同一个topic时,Subscription为每一个consumer分配一个Cursor,这样多个Consumer之间就不会相互影响了。如下图:

Subscription会维护一个消息的ACK状态,consumer处理完消息后,会给broker返回ACK,表示消息已经处理完成。如果broker一直没有收到ACK,就会把消息发送到其他consumer。

如果客户端想要重新消费Cursor以前的消息,Cursor是支持reset的,reset之后,Cursor就回退回去了,这时consumer可以从新的Cursor位置进行消费。

Cursor的位置是会实时写入BookKeeper的,这必定会有一定的性能损耗。因此,Pulsar提供了一种非持久化的Subscription(Non-durable Exclusive)。Pulsar的Reader接口内嵌了Non—durable Exclusive Cursor,它读取消息不会返回ACK。

6 broker代理

通过前面的讲解可以看到,consumer和producer只需要跟broker进行交互,而不用跟底层的BookKeeper交互,事实上,broker还有一层代理,consumer和producer直接跟代理进行交互。如下图:

7 Zookeeper

Pulsar提供了System topic用来保存策略之类的元数据,尽量减少对Zookeeper的依赖。

Zookeeper也保存一些策略相关的元数据,还保存了broker和BookKeeper集群相关的配置元数据,比如服务发现相关的元数据。

8 总结

Pulsar是一款非常优秀的中间件,实现了计算和存储相分离,支持多租户,扩展和扩容、容错都是非常容易的。

                           ··············  END  ··············

参考资料

[1]

参考: https://zhuanlan.zhihu.com/p/158550358

【12图】你管这破玩意叫Pulsar相关推荐

  1. 你管这破玩意叫 RDB

    ‍‍ 作者 | 闪客sun 来源 | 低并发编程(ID:dibingfa) 我是个 redis 服务,我马上就要挂了! 我已经运行了好几年了,我的内存中存储着好多键值对. 如果我挂了,那样我内存中的数 ...

  2. 计算机电路计数器pl什么意思,图解 | 你管这破玩意叫计算机?

    原标题:图解 | 你管这破玩意叫计算机? 我和小宇早恋了,我们家住隔壁. 一.编码与电路--信号的转换 晚上父母会把手机没收,但我们还想继续聊天,又不敢发出声音,于是我们想到了这个办法... 我们把所 ...

  3. 你管这破玩意叫 RDB?

    低并发编程 战略上藐视技术,战术上重视技术 本文末有小惊喜 我是个 redis 服务,我马上就要挂了 我已经运行了好几年了,我的内存中存储着好多键值对. 如果我挂了,那样我内存中的数据就全没了. 我得 ...

  4. 计算机电路图解,图解 | 你管这破玩意叫计算机?

    原标题:图解 | 你管这破玩意叫计算机? 我和小宇早恋了,我们家住隔壁. 一.编码与电路--信号的转换 晚上父母会把手机没收,但我们还想继续聊天,又不敢发出声音,于是我们想到了这个办法... 我们把所 ...

  5. 你管这破玩意叫 CPU ?

    点击关注公众号,Java干货及时送达 每次回家开灯时你有没有想过,用你按的简单开关实际上能打造出复杂的 CPU 来,只不过需要的数量会比较多,也就几十亿个吧. 伟大的发明 过去200年人类最重要的发明 ...

  6. 破玩意 | 多线程 +1 的最快操作

    ‍‍ 作者 | 闪客sun 来源 | 低并发编程(ID:dibingfa) 直奔主题,多个线程,一个共享变量,不断 +1. 如果代码直接这样写,会产生线程安全问题. public class Lon ...

  7. 你管这破玩意叫哨兵?

    作者 | 闪客sun 来源 | 低并发编程(ID:dibingfa) 我是一个苦逼的运维,有一次老板过来找我. 老板:现在有四个 redis 节点摆在你面前,一主三从,你负责盯着点,主节点挂了你赶紧想 ...

  8. 12图、网络、关联矩阵

    第 12 讲 图.网络.关联矩阵 Graphs,networks,incidence matrices 本讲讨论线性代数在物理系统中的应用. 图和网络 Graphs & Networks &q ...

  9. 作业12图的着色问题

    问题图的m着色问题.给定无向连通图G和m种颜色,用这些颜色给图的顶点着色,每个 顶点一种颜色.如果要求G的每条边的两个顶点着不同颜色.给出所有可能的着色方 案:如果不存在,则回答"NO&qu ...

最新文章

  1. SAMBA服务器应用
  2. PMP-【第6章 项目进度管理】-2021-2-11(136页-160页)
  3. python和linux哪个难学-请不要重复犯我在学习Python和Linux系统上的错误
  4. python自定义包_详解python自定义模块、包
  5. java使用validator进行校验
  6. LeetCode - 题 70 跳台阶 - 具体思路与python解法
  7. Drupal basic
  8. 单例模式-双重检查加锁
  9. Veritas面向OpenStack推出全新软件定义存储解决方案
  10. 随想录(虚拟机实现)
  11. amazon云计算平台_腾讯云首次公开边缘计算网络开源平台,拥抱5G与万物互联
  12. java mysql emoj报错_MySQL插入emoji表情报错 SQLException: Incorrect string value 的两种解决方案...
  13. 神经网络结构可视化工具总结实践大全
  14. 使用adb安装apk报错:INSTALL_FAILED_INVALID_URI
  15. 《 阿房宫赋》古文鉴赏
  16. 红外热成像技术的应用与发展
  17. Oracle必读好书推荐
  18. wxid 微信号设置隐私 微信号搜不到 恢复好友总结
  19. access 升迁 mysql_随说秋色园从Access升迁到MSSQL过程
  20. 缓冲区溢出-printf格式化输出漏洞

热门文章

  1. mysql int 11 java_mysql中int(11)列的大小(以字节为单位)是多少?
  2. 高质量的期货研究报告去哪里找?
  3. 写一个简单的 django_post demo
  4. 洛谷P2463 Sandy的卡片【后缀数组】【二分】
  5. js 控制超出字数显示省略号
  6. JavaScript基础学习(七)—BOM
  7. Echart..js插件渲染报错 data.length1?
  8. C/C++预处理宏的总结
  9. mysql在linux下修改存储路径
  10. 国服服务器_《Minecraft我的世界》第三方服务器的基本储备