资讯动态

Pulsar 2.9.1二进制包部署指南:从单机到三节点集群

发布时间:2026/10/16 3:54:41 来源:尧图企业网站定制
简介Apache Pulsar 2.9.1 二进制发行包专为分布式消息队列与流处理场景设计面向需要高吞吐、低延迟、可扩展消息中间件的开发者、架构师及运维团队。压缩包为 gz 格式体积约 321.53MB内含服务端启动程序、客户端 API 库、命令行工具与部署辅助脚本解压即可按官方文档配置集群并启动服务。该版本以 Apache ZooKeeper 为元数据协调核心负责主题分区、集群配置与租约管理配合 BookKeeper 实现高可用持久化并原生支持发布/订阅模型与共享、独占、故障转移等订阅类型可无缝接入 Kubernetes 等云原生环境同时支持消息分层存储以优化成本。借助 Pulsar Functions 可在消息传递同时完成轻量级流处理适合构建实时数据管道或事件驱动应用。已有 151 人下载学习可作为入门 Pulsar 的基础环境用于本地实验、消息流转验证及生产集群选型参考。1. 先动手前搞清楚这份 pulsar-2.9.1-bin 包到底解决了什么问题把 apache pulsar 2.9.1 的 bin.tar.gz 下载到内网机器解压后执行bin/pulsar standalone大约十分钟就能跑出一个可收发消息的实例——这份资源的核心价值就落在这条命令上。Pulsar 是云原生消息中间件里绕不开的名字broker 无状态、存储与计算分离但元数据层需要挂在 ZooKeeper 上直接用官方编译好的二进制包能避开源码编译对 JDK、Maven 仓库和网速的多重依赖。适合两类人刚接触分布式消息中间件的新手想先把整体架构跑通以及要在离线内网环境做部署验证的一线工程师。下文按单机到三节点集群的顺序逐步拆解参数和坑都来自实际部署过程。2. 先把资源本身摸清目录结构、standalone 启动与端到端验证2.1 为什么直接要 bin.tar.gz源码编译的成本与选择逻辑先说一个我自己的经历第一次接触 Pulsar 时我按官方文档从源码编译 2.9.1Maven 依赖在本地仓库反复拉不全中间还因为 JDK 版本不对编不过去折腾了两三小时。后来换用现成的 bin.tar.gz解压之后直接跑十分钟内就走通了生产消费。这个对比基本可以代表大多数人的处境你需要的是一个能跑、能改配置、能看日志的环境而不是再经历一次构建链路的折腾。bin.tar.gz 和源码包的最大区别在于二进制包把所有依赖 jar 都锁在 lib 目录里版本是官方测试过的组合。你不需要关心某次提交之后依赖版本漂移也不需要在编译阶段去匹配 ZooKeeper、BookKeeper 的版本号。对于线上排障来说这种「黑匣子」反而是优点——基础版本固定了出问题时排查范围收窄到配置与网络。我一般会额外做一件事把 bin.tar.gz 的 SHA256 校验一遍再解压避免在内网传输时出现截断导致的启动异常。2.2 解压后先看四个目录bin、conf、lib、examples解压后的主要目录如下。路径作用什么时候动它bin/pulsar、pulsar-admin、pulsar-client、pulsar-daemon 等可执行脚本日常启动、运维入口conf/standalone.conf、broker.conf、zookeeper.conf、bookkeeper.conf部署前必改lib/三大组件的 jar 包与依赖升级组件版本时examples/官方示例源码学习用不需要改注意Windows 上解压后直接双击 bin/pulsar 是跑不起来的脚本是 bash 写的需要 Git Bash 或 WSL。第一次启动会自动生成 data 目录standalone 模式下 ZooKeeper、BookKeeper、Broker 的数据都落在里面。这相当于整个环境的「后悔药」数据乱了停掉进程把 data 目录改名备份再启动就是全新集群。standalone 模式为什么不用去改 zookeeper.conf因为 conf/standalone.conf 已经内置了 ZooKeeper 和 BookKeeper 的相关配置你只需要关注其中的 broker 参数即可。这里常见误用是去改 conf/broker.conf 再跑 standalone结果启动后没有生效——standalone 模式读取的是 standalone.conf不是 broker.conf。2.3 standalone 启动一条命令拉起三个进程执行cd /opt/pulsar bin/pulsar standalone默认情况下这条命令会在同一进程里拉起内嵌 ZooKeeper端口 2181、单节点 BookKeeper 和 Broker。Broker 暴露两个端口6650 是客户端二进制协议端口8080 是管理接口端口。Pulsar 的 topic 在第一次生产消费时自动创建默认单分区。参数理解bin/pulsar standalone --no-functions-worker--no-functions-worker 表示不启动 Pulsar Functions worker单机验证用不到函数计算不加的话会多占一块内存。然后验证生产和消费bin/pulsar-client produce -m hello-standalone -n 5 my-topic bin/pulsar-client consume my-topic -s demo-sub -n 0参数说明-m 指定消息内容-n 5 表示发送 5 条消息-s 指定订阅名称-n 0 表示持续消费直到手动 CtrlC 退出。produce 命令会把消息写入 BookKeeper 的 ledger 中consume 命令创建或复用 demo-sub 订阅并开始读取。看到连续输出 5 条消息就说明端到端链路是通的。提示如果 consume 时提示 topic 不存在或权限错误先检查 standalone.conf 里的 allowAutoTopicCreation 是否被设置为 false这个参数默认是 true但部分二次打包的版本会把它关闭。standalone.conf 里值得先认识的几个参数如下。参数默认值说明brokerServicePort6650客户端二进制协议端口webServicePort8080管理接口与 admin 端口zookeeperServerslocalhost:2181内嵌 ZK 地址单机无需改bookkeeperMetadataServiceUrimetadata_store:zk:localhost:2181ledger 元数据地址allowAutoTopicCreationtrue是否允许 topic 自动创建单机模式下这些参数基本不用动但理解它们的含义对后面切集群很有帮助。尤其是 bookkeeperMetadataServiceUri它决定了 BookKeeper 的 ledger 元数据写到哪个 ZooKeeper 路径集群模式下这行配置会和单机完全不同。2.4 单机验证与真实集群的差异什么时候必须切到集群模式standalone 模式把所有组件塞进一个 JVM好处是环境干净、排障简单坏处是它掩盖了 Pulsar 最重要的分布式特性故障转移与元数据协调。比如你想验证「某个 broker 挂了消费者是否会自动重连」standalone 模式就做不到因为 broker 只有一个且和 ZooKeeper 同进程。我一般把 standalone 当成两件事来用一是验证客户端配置和消息模型二是当本地开发环境。生产验证至少需要三台机器ZooKeeper、BookKeeper、Broker 拆开部署这也正好是下一章的内容。3. 拆成真正的分布式集群ZooKeeper 元数据先落地BookKeeper 与 Broker 再谈Pulsar 在 2.9.1 里的架构可以这样理解Broker 是无状态的接入层只处理生产消费请求和消息路由消息数据写入 BookKeeper 的 ledger而哪个 topic 由哪个 broker 负责、命名空间和租户配置、订阅游标元数据都放在 ZooKeeper 里。换句话说ZooKeeper 是整个集群的「记忆体」Broker 可以被随时替换但 ZooKeeper 的数据丢了集群的元数据就全乱了。这也是为什么云原生环境下 Pulsar 的部署习惯是broker 可以跑在容器里随意扩缩容但 ZooKeeper 一定要用独立的三节点集群来保底。启动顺序有严格约定先 ZooKeeper再 BookKeeper最后 Broker。顺序反了会报连接失败或服务不可用。如果先启动 Brokerbroker 启动时会尝试连接 ZK 读取集群元数据并把自身地址注册进去ZK 没起来就会一直初始化失败或反复重试。BookKeeper 同理bookie 注册写 ZK 也需要 ZK 先行。3.1 ZooKeeper 三节点集群myid、server.list 与端口含义先把三台机器的 hosts 映射配好假设内网 IP 是 10.0.0.1110.0.0.13cat /etc/hosts EOF 10.0.0.11 node1 10.0.0.12 node2 10.0.0.13 node3 EOF然后修改 conf/zookeeper.conf三台机器配置内容一致只有 dataDir 下的 myid 文件不同tickTime2000 initLimit5 syncLimit2 dataDir/data/zookeeper clientPort2181 server.1node1:2888:3888 server.2node2:2888:3888 server.3node3:2888:3888参数说明tickTime 是 ZooKeeper 的最小时间单元单位毫秒initLimit 是 follower 启动后与 leader 完成初始同步的超时阈值5 个 tick 也就是 10 秒syncLimit 是运行期 follower 与 leader 心跳超时2 个 tick 为 4 秒。2888 端口是 leader 向 follower 同步数据的端口3888 是选举端口。这两个端口只在内网开放即可。初始化 myid# node1 上执行 mkdir -p /data/zookeeper echo 1 /data/zookeeper/myidnode2 写 2node3 写 3。myid 必须与 server.N 的 N 对应写错了会出现无法选举或加入失败。启动并验证bin/pulsar-daemon start zookeeper bin/pulsar zookeeper-shell node1:2181 ls /pulsar-daemon start zookeeper 会把进程放到后台并写入 logs 目录。zookeeper-shell 连上后执行 ls /能看到当前根节点列表。如果这里超时优先检查三台机器防火墙是否放行 2181、2888、3888以及 hosts 是否一致。常见做法是先在每台机器上执行telnet node1 2181验证连通性再往下走。注意不要在生产环境的 ZooKeeper dataDir 上放系统和应用日志目录空间不足会导致 ZooKeeper 直接拒绝写事务进而让整个 Pulsar 集群失去元数据读写能力。磁盘监控至少要覆盖这三个数据目录。3.2 BookKeeper 先于 Brokermetaformat 初始化与 ledger 目录规划ZooKeeper 就绪后配置每台机器的 conf/bookkeeper.confzkServersnode1:2181,node2:2181,node3:2181 journalDirectory/data/bookkeeper/journal ledgerDirectories/data/bookkeeper/ledger metadataServiceUrizk://node1:2181,node2:2181,node3:2181/ledgersmetadataServiceUri 指定了 ledger 元数据在 ZooKeeper 中的存储路径journalDirectory 放写入日志ledgerDirectories 放实际数据块。性能敏感场景下我一般会把 journal 放到 SSDledger 放到容量盘两个目录不要共用同一块物理盘。首次部署需要在任意一台机器执行一次元数据初始化bin/bookkeeper shell metaformat -nonInteractive参数说明-nonInteractive 表示自动回答初始化确认不传的话脚本会停下来等输入 yes。重复执行会提示已有 ledgers 元数据没关系不会破坏已有数据。然后每台机器启动 bookiebin/pulsar-daemon start bookie验证 BookKeeper 集群bin/bookkeeper shell listbookies -a看到三台机器都出现在可写 bookie 列表里说明 ledger 层已经就绪。此时如果 listbookies 输出为空多半是 bookie 没有成功注册到 ZooKeeper去看 logs/bookkeeper.log 里有没有报连接 ZK 失败或端口占用。为了进一步确认消息真的写进了 ledger可以发一条消息后执行bin/bookkeeper shell listledgers | head -5。如果输出为空说明消息还没写进 bookie或者元数据没落对。这个检查比只看管理端更直接。3.3 Broker 接入advertisedAddress 是最大的玄学不要留空BookKeeper 起来之后最后启动 Broker。三台机器的 conf/broker.conf 关键配置如下以 node1 为例zookeeperServersnode1:2181,node2:2181,node3:2181 configurationStoreServersnode1:2181,node2:2181,node3:2181 advertisedAddress10.0.0.11 brokerServicePort6650 webServicePort8080 clusterNamepulsar-clusterzookeeperServers 用于 broker 访问集群元数据configurationStoreServers 在 2.9.1 里一般与前者保持一致。advertisedAddress 是 broker 向客户端广播的地址这里必须写本机内网 IP不能留空也不能写 localhost。留空时 broker 会尝试用主机名解析出地址一旦 /etc/hosts 里没配好客户端拿到的就是 127.0.0.1握手必然失败。这个坑我踩过不止一次所以每次部署都会先hostname -i确认解析结果再填。启动 brokerbin/pulsar-daemon start broker验证注册情况bin/pulsar-admin --admin-url http://node1:8080 brokers list pulsar-cluster bin/pulsar-admin --admin-url http://node1:8080 clusters listbrokers list 会输出三个 broker 地址clusters list 至少看到 pulsar-cluster。接着做一个跨节点收发验证在 node2 上执行消费者node1 上执行生产者用同一个 topic 名。# node2 bin/pulsar-client consume my-topic -s sub2 -n 0# node1 bin/pulsar-client produce -m cluster-ok -n 5 my-topic看到消费端连续收到 5 条消息分布式集群的基本链路就算通了。此时可以顺手做一次容错验证在 node3 上执行bin/pulsar-daemon stop zookeeper然后在 node1 上执行bin/pulsar zookeeper-shell node2:2181 ls /。只要集群里超过半数节点存活命令仍能正常返回说明三节点 ZK 的多数派机制生效如果连不上就该检查选举配置与网络。4. 部署常见问题与排查清单五个值得留备忘录的坑这一章结合自己部署 2.9.1 时踩过的坑整理成清单每一条都按「现象、原因、解决」三步展开。这些坑单独看都不复杂但日志里表现的形态各异不熟悉底层数据流的时候确实会绕不少弯路。4.1 启动阶段的坑残留数据与 JDK 版本引起的「玄学」坑一standalone 跑过之后直接切集群ZooKeeper 起不来现象第一次用 standalone 模式在本机跑过数据都落在解压目录的 data 下。后来在同一台机器部署三节点集群启动 zookeeper 后日志报错出现 NoSuchNode、Metadata store error 之类或者进程起来几秒就退出。原因standalone 初始化时已经在 ZooKeeper 里写了 standalone 场景的元数据结构和集群模式下期望的节点路径不一致。残留 data 是最大的干扰源。解决停掉所有相关进程后把整个 data 目录改名备份比如mv data /tmp/data-standalone-backup再重新初始化。如果需要保留原来的消息数据先导出或迁移不要直接删除。从那以后我每次从单机切集群都会先确认 data 目录是干净的。坑二JDK 版本不匹配bookie 起不来现象bin/pulsar-daemon start bookie 后logs 里出现 java.lang.NoSuchMethodError 或 UnsupportedClassVersionError具体类名每次都不一样看上去像随机报错。原因2.9.1 编译时基于 JDK 8u252某些方法在老版本 JDK 8 里还没引入换到 JDK 9 或 10 也有部分 API 不兼容。这是我排查时间最长的一次最后发现是默认 JAVA_HOME 指向了很老的 JRE。解决统一安装 JDK 11并把 JAVA_HOME 指向新版本。Pulsar 2.9.1 官方支持 JDK 11推荐直接用 JDK 11 而不是纠结 JDK 8 的小版本。改完 JAVA_HOME 后先执行java -version确认版本再重启。坑三解压后 bin 脚本没有执行权限现象解压完成后执行 ./bin/pulsar 报 Permission denied用 ls -l 看脚本没有 x 权限位。原因部分内网传输工具或解压程序在解包时丢了执行位特别是从 Windows 侧用某些压缩软件解压 tar.gz 最容易出现。解决进入解压目录执行chmod x bin/*然后重新运行。这个操作也可以在解压后第一件事就做避免启动时报错误判成别的配置问题。4.2 运行期的坑advertisedAddress、订阅与防火墙坑四broker 注册成功但客户端连 6650 握手超时现象三台 Broker 都出现在 brokers list 里pulsar-admin 也能正常访问但客户端连接 6650 端口时一直超时生产者把消息卡在 pending 队列。原因客户端在连接 broker 时拿到的地址不是连接目标而是 broker 广播出去的 advertisedAddress。我第一次部署时没有显式配置 advertisedAddressbroker 把主机名解析成了 127.0.0.1 或错误的内网地址客户端拿着这个地址去握手自然连不通。解决在 broker.conf 中显式写advertisedAddress本机内网IP然后重启 broker。要特别注意的是不要通过改 /etc/hosts 把主机名解析成 127.0.0.1 来绕过这样会引入新问题。正确做法是让每个 broker 都广播自己能连通的内网地址。坑五生产和消费都正常但 topic 的 backlog 只增不减现象生产者和消费者的统计都显示连接正常也没有报错但通过 pulsar-admin 查看 topic stats 时backlog 数量持续上涨消息没有被消费掉。原因Pulsar 的 topic 下可以有多个 subscription每个订阅各自维护消费游标。消费者指定了-s subA而检查时看的却是另一个 subscription或者消费者根本没有指定订阅名导致消息没有真正被读取。解决统一生产和消费的订阅名用pulsar-admin topics subscriptions查看当前 topic 下有哪些订阅确认消费端连的是同一个。检查消费组是不是处于 Activate 状态如果订阅名不一致直接把消费命令的 -s 参数改一致即可。这五条坑基本覆盖了个人在 2.9.1 部署中遇到的大部分阻塞问题。每条看着都不复杂但不熟悉组件之间的依赖关系时确实会花掉一整晚去翻日志。5. 上线前的最后一步健康检查脚本与优雅下线部署完成不等于可以交付。我一般会在验收前跑一份固定的健康检查脚本把 broker 注册、topic 收发、backlog 三个维度都过一遍。脚本内容很简单但能覆盖最常见的两类故障broker 掉线未被自动剔除、消费者游标卡死导致消息积压。#!/usr/bin/env bash set -euo pipefail BIN/opt/pulsar/bin ADMIN_URLhttp://node1:8080 TOPICpersistent://public/default/health-check $BIN/pulsar-admin --admin-url $ADMIN_URL brokers list pulsar-cluster $BIN/pulsar-client produce -m health --count 1 $TOPIC $BIN/pulsar-admin --admin-url $ADMIN_URL topics stats $TOPICbrokers list 检查三个 broker 是否都在produce 一条消息验证写入链路topics stats 输出里重点看 backlog 是否为 0以及最后一条消息的 publish time 是不是刚刚。三项都正常才算通过了基础验收。另一个容易被忽略的操作是优雅下线。很多人习惯 kill -9 直接干掉 broker 进程这在单机环境影响不大但分布式集群里会让 ZooKeeper 等待 session 超时后再重新分配 topic ownership客户端会多等几十秒严重的会出现短时间重复连接。正确的停法是用启动脚本反向操作bin/pulsar-daemon stop broker bin/pulsar-daemon stop bookie bin/pulsar-daemon stop zookeeperstop 指令会让 broker 主动从 ZooKeeper 摘除自己把对应的 topic ownership 交还给其他节点客户端感知不到断连就完成了接管。我从第一次搭建三节点集群之后每次交付前都会强制走一遍健康检查脚本和优雅停机流程尤其是 topics stats 里的 backlog 字段它会暴露绝大多数配置问题。这份 2.9.1 的二进制包在离线环境里也能直接跑解压后按第 2 章到第 4 章的顺序执行基本能一次通过。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑