首页
/
行业洞察
/
正文
INDUSTRY INSIGHT · 深度
Apache Pulsar Standalone 默认项精简:PIP-117 与 RocksDB 嵌入式元数据的实现解析
📅 2026/10/9 10:12:59
✍️ 爱科研究院
👁 阅读 3,247
消息队列流处理后端微服务消息路由【免费下载链接】pulsarApache Pulsar - distributed pub-sub messaging system项目地址https://gitcode.com/gh_mirrors/pu/pulsar点击查看免费下载Apache Pulsar Standalone 是Pulsar in a box形态ZooKeeper或元数据存储、BookKeeper、Broker、Functions Worker 等全部组件运行在同一个 JVM 进程中。PIP-117pip/pip-117.md正是针对这一形态的默认配置进行的精简提案。读完本文你能掌握 Standalone 四项默认变更的具体内容、向后兼容策略以及这些设计在当前源码中PulsarStandalone.java的落地方式与验证方法。背景为什么需要简化 StandaloneStandalone 的典型使用场景是快速上手 Pulsar或任何适合单节点部署的场合开发、测试、边缘部署。但问题在于Standalone 默认启动了大量原本为分布式部署设计的复杂组件。以旧版默认行为为例一个 Standalone 进程会同时拉起本地 ZooKeeper 集群、本地 BookKeeper 集群、Broker 和 Functions Worker其中ZooKeeper 是独立的重型进程级组件增加启动时间与内存/CPU 占用Functions 的 package 后端基于 DistributedLog写入 BookKeeper仅为存放几个 jar 包而维持复杂的分布式日志链路Functions 状态存储依赖 BookKeeper Stream Storage 服务BookKeeper Table Service 也会随 BK 一起启动。PIP-117 提出的目标很明确原文 Goal 小节降低复杂度Reduce complexity缩短启动时间Reduce startup time降低 Standalone 运行时的内存和 CPU 占用Reduce memory and CPU footprint。PIP-117 的四项核心变更提案的核心是替换 Standalone 使用的几类默认实现原文列出的四项变更如下#组件旧默认实现新默认实现1元数据存储Metadata StoreZooKeeperRocksDB嵌入式2Functions package 后端DistributedLog上传到 BookKeeper本地文件系统jar 直接存放在数据目录3Functions 状态存储BookKeeper Stream Storage基于 MetadataStore 的后端RocksDB 实现4Table Service随 BK 启动默认不启动 BK Table Service1. 元数据存储ZooKeeper 替换为 RocksDB这是影响面最大的一项。Pulsar 的集群元数据cluster、tenant、namespace、分区等统一通过 MetadataStore 接口访问。Standalone 中新默认使用rocksdb://协议的嵌入式 RocksDB 元数据存储数据落在本地数据目录。在源码中对应的新参数 metadataStoreUrl 与 metadataStoreConfigPathIts supported by RocksdbMetadataStore and EtcdMetadataStore for now在 conf/standalone.conf 中均有定义。2. Functions package 后端改用本地文件系统旧实现中Functions 的 jar 包通过 DistributedLog 写入 BookKeeper新实现改为直接把 jar 存入数据目录下的本地文件系统。当前仓库中对应实现为 FileSystemPackagesStorageProvider实现PackagesStorageProvider接口。3. Functions 状态存储改为 MetadataStore 后端Functions Worker 的状态存储state storage改为由 MetadataStore 支撑、RocksDB 落地。当前仓库中对应实现为 PulsarMetadataStateStoreProviderImpl实现StateStoreProvider接口。旧路径则是bk://127.0.0.1:stream-storage-port的 Stream Storage 服务。4. Table Service 默认不启动Standalone 不再随 BookKeeper 启动 BK Table Service直接省掉一个默认组件。兼容性设计存量数据如何无冲突升级PIP-117 特别考虑了一个现实问题用户可能已经有一个带存量数据的 Standalone 服务升级时不能因为默认项切换而读不到旧数据。提案给出的原则是原文 Compatibility considerations 小节只要磁盘上已有数据就保持旧默认值keep the old defaults where there is existing data on the disk。具体机制在data/standalone目录下放置一个充当标志位的文件例如new-2.10-defaults。判定逻辑为标志文件存在或数据目录完全不存在全新安装→ 采用新的一套默认配置RocksDB 元数据等标志文件不存在即存在旧数据→ 继续沿用旧默认值ZooKeeper 等保证升级过程不被破坏。源码落地PulsarStandalone 的默认选择逻辑提案的核心决策逻辑实现在 PulsarStandalone.start() 中用一个布尔字段usingNewDefaultsPIP117区分新旧两套默认String forceUseZookeeperEnv System.getenv(PULSAR_STANDALONE_USE_ZOOKEEPER); // Allow forcing to use ZK mode via an env variable. eg: // PULSAR_STANDALONE_USE_ZOOKEEPER1 if (StringUtils.equalsAnyIgnoreCase(forceUseZookeeperEnv, 1, true)) { usingNewDefaultsPIP117 false; log.info(Forcing to chose ZooKeeper metadata through environment variable); } else if (Paths.get(zkDir).toFile().exists()) { log.info(Found existing ZooKeeper metadata. Continuing with ZooKeeper); usingNewDefaultsPIP117 false; } else { // Theres no existing ZK data directory, or were already using RocksDB for metadata usingNewDefaultsPIP117 true; }从源码结构看当前仓库对是否有存量数据的探测采用了检测 ZK 数据目录默认data/standalone/zookeeper是否存在的等价判据并额外提供了环境变量PULSAR_STANDALONE_USE_ZOOKEEPER1|true作为强制回退到 ZooKeeper 模式的开关。这与 PIP-117有数据则用旧默认的原则一致旧版本写出的 ZK 数据目录存在时仍走 ZooKeeper 路径不会破坏升级。新默认路径RocksDB 元数据 轻量 BK 集群选择新默认时usingNewDefaultsPIP117 trueStandalone 调用 startBookieWithMetadataStore()if (StringUtils.isBlank(metadataStoreUrl)){ log.info(Starting BK with RocksDb metadata store); Path metadataDirPath Paths.get(metadataDir); metadataStoreUrl rocksdb:// metadataDirPath.toAbsolutePath(); ... } ... bkCluster BKCluster.builder() .baseServerConfiguration(bkServerConf) .metadataServiceUri(metadataStoreUrl) .numBookies(numOfBk) .bookieIdPrefix(bk) .bkPort(bkPort) .dataDir(bkDir) .clearOldData(wipeData) .build(); config.setMetadataStoreUrl(metadataStoreUrl);要点元数据 URL 默认为rocksdb://metadata-dir 绝对路径--metadata-dir默认值即data/metadata见 PulsarStandalone.java 的命令行选项通过BKClusterpulsar-metadata 模块提供的 BK 集群抽象内嵌启动 bookiebookie 数量由--num-bookies控制默认 1--wipe-data时清理 RocksDB 元数据目录与 BK 旧数据clearOldData(wipeData)。而旧默认路径 startBookieWithZookeeper() 则启动LocalBookkeeperEnsemble内嵌 ZK BK并把元数据 URL 设为zk:127.0.0.1:zkPort默认 2181。Functions Worker 的配套切换在 start() 中两套默认对应不同的 Worker 配置if (usingNewDefaultsPIP117) { workerConfig.setStateStorageProviderImplementation( PulsarMetadataStateStoreProviderImpl.class.getName()); config.setEnablePackagesManagement(true); config.setFunctionsWorkerEnablePackageManagement(true); workerConfig.setFunctionsWorkerEnablePackageManagement(true); config.setPackagesManagementStorageProvider(FileSystemPackagesStorageProvider.class.getName()); } else { // worker talks to local broker if (this.isNoStreamStorage()) { workerConfig.setStateStorageServiceUrl(null); } else if (workerConfig.getStateStorageServiceUrl() null) { workerConfig.setStateStorageServiceUrl(bk://127.0.0.1: this.getStreamStoragePort()); } }新默认下状态存储切换为PulsarMetadataStateStoreProviderImpl对应 PIP-117 第 3 项同时打开 package 管理并指定FileSystemPackagesStorageProvider作为存储提供者对应第 2 项旧默认下状态存储则指向bk://127.0.0.1:4181--stream-storage-port默认 4181的 Stream Storage。内存预算少一个 ZK 实例的变化PIP-117 声称降低内存占用在源码中也有直接体现。calculateCacheSize() 按实例数分摊堆外内存给 BK 的写/读缓存// we need to add one broker and one zk (if needed) to calculate the default cache int instanceCount usingNewDefaultsPIP117 ? (1 numOfBk) : (2 numOfBk); long defaultCacheMB PlatformDependent.maxDirectMemory() / (1024 * 1024) / instanceCount / 4;新默认下分母为1 numOfBkbroker bookie旧默认为2 numOfBk多出 ZooKeeper——少掉一个 ZK 实例后每个实例分到的默认缓存相应增大。相关命令行选项速览Standalone 的命令行选项定义在 PulsarStandalone.java 的 picocli 注解中与 PIP-117 直接相关的主要有选项默认值说明-c, --config—配置文件路径如conf/standalone.conf--metadata-dirdata/metadataRocksDB 元数据存储目录--metadata-url空自动拼rocksdb:// metadata-dir外部指定元数据 URL 时直接生效--wipe-datafalse清理既有 ZK/BK 数据--num-bookies1本地 bookie 数量--bookkeeper-port0内核分配端口bookie 基础端口bookie i 使用 base i旧数据沿用 bookie ID 中记录的端口--bookkeeper-dirdata/standalone/bookkeeperbookie 数据目录--no-broker/--only-broker—只启 ZK/BK、或只启 Broker-nfw, --no-functions-workerfalse不随进程启动 Functions Worker-nss, --no-stream-storagefalse禁用旧默认的 Stream Storage仅旧路径有意义--stream-storage-port4181Stream Storage 端口旧路径状态存储使用--zookeeper-port/--zookeeper-dir2181/data/standalone/zookeeper旧路径的 ZK 端口与数据目录已标记 hidden测试如何验证这些行为集成测试为新旧默认各覆盖了回归场景PulsarStandaloneUpgradeTest通过容器化 Standalone 并以环境变量PULSAR_STANDALONE_USE_ZOOKEEPER控制新旧默认测试中使用该变量的片段验证升级路径下两种默认都能正常启动并读写数据PulsarMetadataStateStoreTest验证 Functions 使用 MetadataStore 状态存储后的行为PulsarStandaloneTestBase作为各 Standalone 集成测试套件的拓扑基类显式设置PULSAR_STANDALONE_USE_ZOOKEEPERtrue走旧默认路径做兼容性回归另有 broker 层单测 PulsarStandaloneTest 覆盖 standalone 进程的启动逻辑。小结与适用前提PIP-117 用四项替换RocksDB 元数据、文件系统 package 存储、MetadataStore 状态存储、默认不启 Table Service把 Standalone 从一个内嵌的分布式集群简化为以本地文件为中心的轻量进程并通过磁盘上有存量数据则保留旧默认的原则保证升级兼容。在当前仓库中这一策略体现在PulsarStandalone的usingNewDefaultsPIP117判定分支、BKClusterrocksdb://的新启动路径以及PulsarMetadataStateStoreProviderImpl/FileSystemPackagesStorageProvider两个配套实现上。适用前提需注意该行为面向全新安装的 Standalone 自动生效新默认已有 ZooKeeper 数据目录的存量实例会继续沿用旧默认需要显式清理数据或--wipe-data全新部署才会切换到 RocksDB 元数据路径。赞分享消息队列流处理后端微服务消息路由【免费下载链接】pulsarApache Pulsar - distributed pub-sub messaging system项目地址https://gitcode.com/gh_mirrors/pu/pulsar点击查看免费下载相关推荐如何把 Atmosphere 开机启动画面换成自定义 1280x720 图片package3 修改完整指南如何把 Atmosphere 开机启动画面换成自定义 1280x720 图片package3 修改完整指南 Atmosphère 是为 Nintendo Sw消息队列流处理后端微服务消息路由Apache Pulsar 的 Oxia 元数据存储插件PIP-335原理、源码实现与配置指南Apache Pulsar 的 Oxia 元数据存储插件PIP 335原理、源码实现与配置指南 导读 本文基于 PIP 335 提案深入讲解 Apac消息队列后端Apache Pulsar PIP-296 解析为 Reader 增加 getLastMessageIds API 的设计与实现Apache Pulsar PIP 296 解析为 Reader 增加 getLastMessageIds API 的设计与实现 导读 本文基于 Apach消息队列后端上一篇Draggable 事件体系全解析DragEvent 家族源码级指南下一篇komorebi close-workspace 命令详解关闭并回收空工作区的正确姿势创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
📌 标签:
工业官网
设计趋势
AI 建站
SEO
获取完整报告 →
RELATED ARTICLES
推荐阅读
2026/10/9 10:12:59
xPSR 寄存器 | 位段表示法
2026/10/9 10:12:59
ZBF文件解析:光场复振幅数据的物理本质与Python读取
2026/10/9 10:07:59
temporal-golang-pro - implementation-playbook
2026/10/9 11:03:15
Flink实时数据分析实战:从架构原理到代码部署与排障
2026/10/9 11:03:15
Loop Engineering循环工程:AI编程从提示词到自动迭代的实战指南
2026/10/9 11:03:15
Loop Engineering:AI编程自动化循环的工程化实践指南
2026/10/9 11:03:15
Claude Code Mod 魔改实战:从零安装到自定义配置完全指南
2026/10/9 11:03:15
Windows 下 Claude Code 安装配置全攻略:从踩坑到高效开发
2026/10/9 10:58:14
移动端弹幕实现:解析轨道分配与性能优化的关键技术
2026/10/9 0:01:35
RISC-V裸机启动全流程:从复位向量到main函数的七步实现
2026/10/9 0:01:35
Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南
2026/10/9 0:01:35
EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错
2026/10/8 5:02:14
Jev+Agent接管浏览器:browser-use实战与jev-ultrafast性能优化
2026/10/9 1:10:43
多智能体集群实战:DeepAgents编排、MCP与A2A协议及Skills体系
2026/10/9 3:31:49
hindsight:面向LLM应用的事后可观测性工程实践
2026/10/8 4:30:43
我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频
2026/10/9 3:32:01
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证
2026/10/8 4:32:33
2026 大模型集体涨价:用 Python 做企业 Token 成本测算与选型避坑(附配置)