news 2026/9/29 5:53:51

Apache Pulsar 租户(Tenant)管理完全指南:pulsar-admin / REST API / Java Admin API 三端实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Apache Pulsar 租户(Tenant)管理完全指南:pulsar-admin / REST API / Java Admin API 三端实战
  • 消息队列
  • 后端
  • 流处理

【免费下载链接】pulsar

Apache Pulsar - distributed pub-sub messaging system

项目地址:https://gitcode.com/gh_mirrors/pulsar28/pulsar
点击查看免费下载

租户(Tenant)是 Apache Pulsar 多租户架构中的第一层资源隔离单元,其下承载命名空间(Namespace)与主题(Topic)。本文基于 Apache Pulsar 2.4.0 官方管理文档,结合当前仓库源码,系统讲解如何使用pulsar-admin命令行、REST API 与 Java Admin API 完成租户的创建、查询、更新与删除,并深入剖析其底层实现原理,帮助你快速上手 Pulsar 的租户级权限与集群配额管理。

本文面向的版本为 Apache Pulsar 2.4.0。文中涉及的源码路径均以当前仓库为准,命令输出以实际运行环境为准。

租户:Pulsar 多租户体系的基石

在 Pulsar 中,资源组织层次为租户(Tenant)→ 命名空间(Namespace)→ 主题(Topic)。租户位于顶层,用于实现多团队、多业务线之间的隔离。与命名空间类似,租户可以通过 admin API 进行管理,当前版本中一个租户有两个可配置维度:

  • Admin roles(管理员角色):拥有该租户管理权限的认证主体(auth principal)集合,通常对应角色或用户标识;
  • Allowed clusters(允许的集群):该租户可以使用的集群列表,用于跨集群场景下的资源约束。

从源码结构看,租户的数据模型定义在 TenantInfo 接口中,核心字段即上述两个集合:

public interface TenantInfo { Set<String> getAdminRoles(); Set<String> getAllowedClusters(); // Builder 模式构建 TenantInfo interface Builder { Builder adminRoles(Set<String> adminRoles); Builder allowedClusters(Set<String> allowedClusters); TenantInfo build(); } }

而租户管理的客户端接口(同步/异步方法)定义在 Tenants.java 中,提供getTenants()、getTenantInfo(tenant)、createTenant(tenant, config)、updateTenant(tenant, config)、deleteTenant(tenant)以及对应的*Async异步版本,这是下文三种管理方式共同依赖的抽象层。

一、租户资源管理操作

以下所有操作均可通过pulsar-admin、REST API 和 Java Admin API 三种方式完成,下文逐一说明。

1. 列出全部租户(List)

pulsar-admin

使用list子命令:

$ pulsar-admin tenants list my-tenant-1 my-tenant-2

命令对应的 CLI 实现位于 CmdTenants.java 的List内部类,底层直接调用getAdmin().tenants().getTenants()。该接口的 Javadoc 给出了典型返回示例["my-tenant", "other-tenant", "third-tenant"]。

REST API
GET /admin/v2/tenants

Broker 侧对应的服务端实现是 v2/Tenants.java 继承的 TenantsBase.java,其中getTenants()在返回前会做一次排序(对列表深拷贝后sort(null)),保证输出顺序稳定。

Java Admin API
admin.tenants().getTenants();

2. 创建租户(Create)

pulsar-admin

使用create子命令:

$ pulsar-admin tenants create my-tenant

创建时可通过-r/--admin-roles指定管理员角色,多个角色用逗号分隔:

$ pulsar-admin tenants create my-tenant \ --admin-roles role1,role2,role3 $ pulsar-admin tenants create my-tenant \ -r role1

除文档中的--admin-roles外,从 CmdTenants.java 的Create命令源码可以看到,创建操作还支持-c/--allowed-clusters参数指定允许的集群列表;若省略该参数,则默认授予租户访问全部现有集群的权限(实现为allowedClusters = getAdmin().clusters().getClusters())。

REST API
PUT /admin/v2/tenants/:tenant

请求体(TenantInfo)示例:

{ "adminRoles": ["admin1", "admin2"], "allowedClusters": ["cl1", "cl2"] }

Broker 侧createTenant的完整校验链路(见 TenantsBase.java)包括:

  • 校验请求者具有 super-user 权限(validateSuperUserAccess());
  • 校验集群列表非空、且每个集群真实存在(validateClusters(tenantInfo)),global集群作为特例被放行;
  • 校验租户名称合法性(NamedEntity.checkName(tenant),非法名称返回 412);
  • 校验租户是否已存在(已存在返回 409 Conflict);
  • 检查集群级maxTenants配额(见下文)。
Java Admin API
admin.tenants().createTenant(tenantName, tenantInfo);

3. 获取租户配置(Get configuration)

可随时获取已有租户的 配置。

pulsar-admin

使用get子命令并指定租户名:

$ pulsar-admin tenants get my-tenant { "adminRoles": [ "admin1", "admin2" ], "allowedClusters": [ "cl1", "cl2" ] }
REST API
GET /admin/v2/tenants/:tenant

Broker 侧若租户不存在,返回 404("Tenant does not exist")。

Java Admin API
admin.tenants().getTenantInfo(tenantName);

4. 删除租户(Delete)

租户可以从 Pulsar 实例中删除。文档中的默认删除逻辑要求租户下没有活跃的命名空间,否则删除失败(返回 409 Conflict)。

pulsar-admin

使用delete子命令并指定租户名:

$ pulsar-admin tenants delete my-tenant

CLI 层还提供了-f/--force参数用于强制删除(deleteTenant(tenant, force))。从 Tenants.java 的 Javadoc 可以看到:默认删除会连带删除该租户下的所有命名空间与主题,但若租户仍有活跃命名空间则抛ConflictException。

REST API
DELETE /admin/v2/tenants/:tenant?force=false

服务端在force=false时的完整删除链路(见internalDeleteTenant)为:确认租户存在 → 校验无活跃命名空间(hasActiveNamespace)→ 依次清理租户的 topic 持久化数据、命名空间资源、分区主题数据、本地策略与 bundle 数据。若强制删除,则先逐个调用namespaces().deleteNamespaceAsync(namespace, true)删除其下所有命名空间,再走正常删除流程。

需要特别注意的是:强制删除受 Broker 配置开关控制。若forceDeleteTenantAllowed=false(Broker 默认值,见 conf/broker.conf 中第 196 行),即使传入force=true,服务端也会返回 405 Method Not Allowed("Broker doesn't allow forced deletion of tenants")。

Java Admin API
admin.tenants().deleteTenant(tenantName); // 普通删除 admin.tenants().deleteTenant(tenantName, true); // 强制删除

5. 更新租户配置(Update)

pulsar-admin

使用update子命令:

$ pulsar-admin tenants update my-tenant

与create类似,update同样支持-r/--admin-roles与-c/--allowed-clusters参数。从 CmdTenants.java 的Update实现可见其增量语义:未指定--admin-roles时保留现有角色,未指定--allowed-clusters时保留现有集群集合。

REST API
POST /admin/v2/tenants/:tenant

服务端updateTenant会先校验租户存在(不存在返回 404),并通过canUpdateCluster检查允许的集群集合变更是否合理,再执行更新。

Java Admin API
admin.tenants().updateTenant(tenantName, tenantInfo);

二、源码视角:租户操作的权限与配额机制

权限要求:Super-user 权限

从 TenantsBase.java 可以看到,list / create / get / update / delete 五个 REST 端点都会先调用validateSuperUserAccess(),即只有 Pulsar super-user 才能执行租户管理操作;普通用户即使持有某些角色也会被拒绝(403)。create与update还会额外调用validatePoliciesReadOnlyAccess(),在 Broker 以只读策略模式运行时(如配置变更保护场景)这些写操作会被拦截。

配额控制:maxTenants

Broker 支持通过配置maxTenants限制单个 Pulsar 集群可创建的租户总数,默认值为0(表示不限制),见 conf/broker.conf 第 117-119 行:

# The maximum number of tenants that each pulsar cluster can create # This configuration is not precise control, in a concurrent scenario, the threshold will be exceeded maxTenants=0

服务端createTenant在写入前会检查当前租户数量,若达到上限则返回 412 Precondition Failed("Exceed the maximum number of tenants")。配置注释明确指出:由于避免分布式锁开销,该阈值在并发场景下并非精确控制。

集群合法性校验

创建与更新租户时,服务端通过validateClusters()强制要求allowedClusters非空且每个集群必须已存在于集群资源中,否则分别返回 412("Clusters can not be empty" / "Clusters do not exist")。global集群名(Constants.GLOBAL_CLUSTER)作为特殊值被放行,这为跨集群数据复制场景提供了支持。

三、三种管理方式对照速查

操作pulsar-admin 命令REST APIJava Admin API
列出租户pulsar-admin tenants listGET /admin/v2/tenantsadmin.tenants().getTenants()
创建租户pulsar-admin tenants create <tenant> [-r roles] [-c clusters]PUT /admin/v2/tenants/:tenantadmin.tenants().createTenant(tenant, info)
获取配置pulsar-admin tenants get <tenant>GET /admin/v2/tenants/:tenantadmin.tenants().getTenantInfo(tenant)
更新配置pulsar-admin tenants update <tenant> [-r roles] [-c clusters]POST /admin/v2/tenants/:tenantadmin.tenants().updateTenant(tenant, info)
删除租户pulsar-admin tenants delete <tenant> [-f]DELETE /admin/v2/tenants/:tenant?force=admin.tenants().deleteTenant(tenant[, force])

四、关键参数与注意事项

  • --admin-roles(-r):逗号分隔的管理员角色列表,即允许管理该租户的认证主体。创建时省略则角色集合为空;更新时省略则保留原有角色。
  • --allowed-clusters(-c):逗号分隔的允许集群列表。创建时省略默认授予全部现有集群;更新时省略保留原集合。服务端强制要求该字段非空且集群必须存在。
  • --force(-f):删除租户时强制删除其下所有命名空间与主题。注意受 Broker 配置forceDeleteTenantAllowed(默认false)约束,未开启时强制删除会被拒绝。
  • maxTenants:集群级租户数量上限,默认0表示不限制;该阈值非精确控制。
  • 租户命名:租户名称需通过NamedEntity.checkName合法性校验,非法名称创建时返回 412。

结语

租户管理是 Pulsar 多租户隔离的第一道关口。通过pulsar-admin、REST API 与 Java Admin API 三种方式,你可以对租户的 Admin roles 与 Allowed clusters 两个核心维度进行完整的生命周期管理。结合 TenantsBase.java 的源码,可以进一步理解其背后的 super-user 权限校验、集群合法性校验、maxTenants配额以及强制删除开关等关键机制,为生产环境的租户规划与权限治理提供依据。

如需继续深入,建议阅读同目录下的 admin-api-overview、reference-pulsar-admin 与 reference-configuration 文档,并结合本文给出的源码路径进行对照学习。

  • 消息队列
  • 后端
  • 流处理

【免费下载链接】pulsar

Apache Pulsar - distributed pub-sub messaging system

项目地址:https://gitcode.com/gh_mirrors/pulsar28/pulsar
点击查看免费下载
上一篇:你的微信聊天记录真的安全吗?用WeChatMsg实现数据自主的终极方案
下一篇:高效文献管理:Zotero-Style插件标签显示问题完整修复指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/29 5:53:34

JupyterLab 从 Notebook 迁移、安装配置到避坑实战指南

这两年我从 Jupyter Notebook 切到 JupyterLab 之后&#xff0c;最直接的感受就是&#xff1a;我不用再同时开着五六个浏览器标签页来回找了。很多人第一次听说 JupyterLab&#xff0c;都觉得它只是换了层皮的 Notebook&#xff0c;实际上它是 Jupyter 生态里的新一代交互界面&…

作者头像 李华
网站建设 2026/9/29 5:53:00

scrcpy 安卓投屏教程:3 条命令把手游搬上电脑大屏

scrcpy 安卓投屏教程&#xff1a;3 条命令把手游搬上电脑大屏 【免费下载链接】scrcpy Display and control your Android device 项目地址: https://gitcode.com/GitHub_Trending/sc/scrcpy 小屏打团手指发酸&#xff0c;想把手游投屏到电脑、用键鼠或手柄来打&#xf…

作者头像 李华
网站建设 2026/9/29 5:51:05

从信息洪流到结构化认知:AI日报自动化生产系统搭建实战

1. 一份AI日报的诞生&#xff1a;从信息洪流到结构化认知每天早上七点半&#xff0c;我习惯性地打开自己搭建的AI日报工作流&#xff0c;看着过去24小时里散落在全球各个角落的AI动态被自动抓取、清洗、归类、摘要&#xff0c;最终汇聚成一份不到三千字的结构化文档。这个过程从…

作者头像 李华
网站建设 2026/9/29 5:49:13

从零构建语言模型:AI工程的极简实践与避坑指南

如果只看现在的招聘 JD&#xff0c;你可能会觉得「AI 工程」是被大厂的 GPU 集群、算法团队和 MLOps 平台垄断的领域&#xff0c;个人开发者只能站在别人的模型后面调参数。但我决定反着来。两年前我开始了一个项目 ai-engineering-from-scratch&#xff0c;目标是在没有现成 t…

作者头像 李华