You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pulsar.apache.org by te...@apache.org on 2023/01/11 12:38:12 UTC
[pulsar-site] branch doc_release_2.11.0 created (now da6d289b27e)
This is an automated email from the ASF dual-hosted git repository.
technoboy pushed a change to branch doc_release_2.11.0
in repository https://gitbox.apache.org/repos/asf/pulsar-site.git
at da6d289b27e Update the site for release 2.11.0
This branch includes the following new commits:
new da6d289b27e Update the site for release 2.11.0
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
[pulsar-site] 01/01: Update the site for release 2.11.0
Posted by te...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
technoboy pushed a commit to branch doc_release_2.11.0
in repository https://gitbox.apache.org/repos/asf/pulsar-site.git
commit da6d289b27e4e94810b0f5902c7e7a72910c1af2
Author: Jiwe Guo <te...@apache.org>
AuthorDate: Wed Jan 11 20:37:56 2023 +0800
Update the site for release 2.11.0
---
releases.json | 1 +
versioned_docs/version-2.11.0/about.md | 58 +
versioned_docs/version-2.11.0/adaptors-kafka.md | 265 ++
versioned_docs/version-2.11.0/adaptors-spark.md | 82 +
versioned_docs/version-2.11.0/adaptors-storm.md | 89 +
versioned_docs/version-2.11.0/admin-api-brokers.md | 283 ++
.../version-2.11.0/admin-api-clusters.md | 305 ++
.../version-2.11.0/admin-api-functions.md | 760 +++++
.../version-2.11.0/admin-api-namespaces.md | 1253 ++++++++
.../admin-api-non-partitioned-topics.md | 7 +
.../admin-api-non-persistent-topics.md | 7 +
.../version-2.11.0/admin-api-overview.md | 48 +
.../version-2.11.0/admin-api-packages.md | 362 +++
.../version-2.11.0/admin-api-partitioned-topics.md | 7 +
.../version-2.11.0/admin-api-permissions.md | 176 ++
.../version-2.11.0/admin-api-persistent-topics.md | 7 +
versioned_docs/version-2.11.0/admin-api-schemas.md | 659 +++++
versioned_docs/version-2.11.0/admin-api-tenants.md | 233 ++
versioned_docs/version-2.11.0/admin-api-topics.md | 2058 +++++++++++++
.../version-2.11.0/admin-api-transactions.md | 725 +++++
versioned_docs/version-2.11.0/admin-get-started.md | 82 +
.../version-2.11.0/administration-geo.md | 275 ++
.../administration-isolation-bookie.md | 269 ++
.../administration-isolation-broker.md | 60 +
.../version-2.11.0/administration-isolation.md | 73 +
.../version-2.11.0/administration-load-balance.md | 279 ++
.../administration-metadata-store.md | 110 +
.../version-2.11.0/administration-proxy.md | 123 +
.../administration-pulsar-manager.md | 183 ++
.../version-2.11.0/administration-pulsar-shell.md | 174 ++
.../version-2.11.0/administration-stats.md | 179 ++
.../version-2.11.0/administration-upgrade.md | 203 ++
.../version-2.11.0/administration-zk-bk.md | 354 +++
.../version-2.11.0/client-api-overview.md | 18 +
.../version-2.11.0/client-libraries-cpp.md | 448 +++
.../version-2.11.0/client-libraries-dotnet.md | 435 +++
.../version-2.11.0/client-libraries-go.md | 940 ++++++
.../version-2.11.0/client-libraries-java.md | 1308 +++++++++
.../version-2.11.0/client-libraries-node.md | 444 +++
.../version-2.11.0/client-libraries-python.md | 328 +++
.../version-2.11.0/client-libraries-rest.md | 125 +
.../version-2.11.0/client-libraries-websocket.md | 617 ++++
versioned_docs/version-2.11.0/client-libraries.md | 81 +
.../concepts-architecture-overview.md | 169 ++
.../version-2.11.0/concepts-authentication.md | 8 +
versioned_docs/version-2.11.0/concepts-clients.md | 87 +
.../concepts-cluster-level-failover.md | 163 ++
.../version-2.11.0/concepts-messaging.md | 1161 ++++++++
.../version-2.11.0/concepts-multi-tenancy.md | 58 +
.../concepts-multiple-advertised-listeners.md | 38 +
versioned_docs/version-2.11.0/concepts-overview.md | 32 +
.../version-2.11.0/concepts-proxy-sni-routing.md | 164 ++
.../version-2.11.0/concepts-replication.md | 62 +
.../version-2.11.0/concepts-schema-registry.md | 5 +
.../version-2.11.0/concepts-tiered-storage.md | 17 +
.../version-2.11.0/concepts-topic-compaction.md | 36 +
.../version-2.11.0/concepts-transactions.md | 29 +
.../version-2.11.0/cookbooks-bookkeepermetadata.md | 20 +
.../version-2.11.0/cookbooks-compaction.md | 120 +
.../version-2.11.0/cookbooks-deduplication.md | 145 +
.../version-2.11.0/cookbooks-encryption.md | 12 +
.../version-2.11.0/cookbooks-message-queue.md | 139 +
.../version-2.11.0/cookbooks-non-persistent.md | 56 +
.../version-2.11.0/cookbooks-partitioned.md | 6 +
.../version-2.11.0/cookbooks-retention-expiry.md | 475 +++
.../version-2.11.0/cookbooks-tiered-storage.md | 310 ++
versioned_docs/version-2.11.0/deploy-aws.md | 228 ++
.../deploy-bare-metal-multi-cluster.md | 404 +++
versioned_docs/version-2.11.0/deploy-bare-metal.md | 490 ++++
versioned_docs/version-2.11.0/deploy-dcos.md | 185 ++
versioned_docs/version-2.11.0/deploy-docker.md | 180 ++
versioned_docs/version-2.11.0/deploy-kubernetes.md | 27 +
versioned_docs/version-2.11.0/deploy-monitoring.md | 119 +
.../version-2.11.0/develop-load-manager.md | 209 ++
versioned_docs/version-2.11.0/develop-plugin.md | 126 +
versioned_docs/version-2.11.0/develop-schema.md | 62 +
versioned_docs/version-2.11.0/develop-tools.md | 105 +
.../version-2.11.0/developers-landing.md | 12 +
.../version-2.11.0/developing-binary-protocol.md | 632 ++++
versioned_docs/version-2.11.0/functions-api.md | 5 +
versioned_docs/version-2.11.0/functions-cli.md | 191 ++
.../version-2.11.0/functions-concepts.md | 193 ++
.../version-2.11.0/functions-debug-cli.md | 187 ++
.../version-2.11.0/functions-debug-localrun.md | 69 +
.../version-2.11.0/functions-debug-log-topic.md | 46 +
.../version-2.11.0/functions-debug-stderr.md | 7 +
.../version-2.11.0/functions-debug-unit-test.md | 63 +
versioned_docs/version-2.11.0/functions-debug.md | 12 +
.../version-2.11.0/functions-debugging.md | 5 +
.../version-2.11.0/functions-deploy-arguments.md | 32 +
.../functions-deploy-cluster-builtin.md | 16 +
.../functions-deploy-cluster-encryption.md | 26 +
.../functions-deploy-cluster-package.md | 24 +
.../functions-deploy-cluster-parallelism.md | 45 +
.../functions-deploy-cluster-resource.md | 32 +
.../version-2.11.0/functions-deploy-cluster.md | 35 +
.../version-2.11.0/functions-deploy-localrun.md | 33 +
.../version-2.11.0/functions-deploy-trigger.md | 66 +
versioned_docs/version-2.11.0/functions-deploy.md | 21 +
.../version-2.11.0/functions-deploying.md | 5 +
.../version-2.11.0/functions-develop-admin-api.md | 49 +
.../version-2.11.0/functions-develop-api.md | 230 ++
.../version-2.11.0/functions-develop-log.md | 174 ++
.../version-2.11.0/functions-develop-metrics.md | 89 +
.../functions-develop-schema-registry.md | 9 +
.../version-2.11.0/functions-develop-security.md | 92 +
.../version-2.11.0/functions-develop-serde.md | 146 +
.../version-2.11.0/functions-develop-state.md | 313 ++
.../version-2.11.0/functions-develop-tutorial.md | 111 +
.../functions-develop-user-defined-configs.md | 146 +
versioned_docs/version-2.11.0/functions-develop.md | 24 +
.../version-2.11.0/functions-guarantees.md | 5 +
versioned_docs/version-2.11.0/functions-metrics.md | 6 +
.../version-2.11.0/functions-overview.md | 86 +
.../version-2.11.0/functions-package-go.md | 47 +
.../version-2.11.0/functions-package-java.md | 207 ++
.../version-2.11.0/functions-package-python.md | 181 ++
versioned_docs/version-2.11.0/functions-package.md | 19 +
.../version-2.11.0/functions-quickstart.md | 626 ++++
.../functions-runtime-java-options.md | 20 +
.../version-2.11.0/functions-runtime-kubernetes.md | 144 +
.../version-2.11.0/functions-runtime-process.md | 24 +
.../version-2.11.0/functions-runtime-thread.md | 34 +
versioned_docs/version-2.11.0/functions-runtime.md | 21 +
versioned_docs/version-2.11.0/functions-state.md | 5 +
.../version-2.11.0/functions-worker-corun.md | 61 +
.../functions-worker-for-geo-replication.md | 19 +
.../functions-worker-run-separately.md | 229 ++
.../version-2.11.0/functions-worker-stateful.md | 68 +
.../functions-worker-temp-file-path.md | 14 +
.../functions-worker-troubleshooting.md | 41 +
versioned_docs/version-2.11.0/functions-worker.md | 19 +
.../getting-started-concepts-and-architecture.md | 15 +
.../version-2.11.0/getting-started-docker.md | 210 ++
.../version-2.11.0/getting-started-helm.md | 375 +++
.../version-2.11.0/getting-started-home.md | 12 +
.../version-2.11.0/getting-started-pulsar.md | 67 +
.../version-2.11.0/getting-started-standalone.md | 137 +
versioned_docs/version-2.11.0/helm-deploy.md | 378 +++
versioned_docs/version-2.11.0/helm-install.md | 12 +
versioned_docs/version-2.11.0/helm-overview.md | 12 +
versioned_docs/version-2.11.0/helm-prepare.md | 27 +
versioned_docs/version-2.11.0/helm-tools.md | 12 +
versioned_docs/version-2.11.0/helm-upgrade.md | 36 +
versioned_docs/version-2.11.0/how-to-landing.md | 13 +
.../install-deploy-upgrade-landing.md | 23 +
versioned_docs/version-2.11.0/io-aerospike-sink.md | 31 +
versioned_docs/version-2.11.0/io-aerospike.md | 5 +
versioned_docs/version-2.11.0/io-alluxio.md | 68 +
versioned_docs/version-2.11.0/io-canal-source.md | 208 ++
versioned_docs/version-2.11.0/io-cassandra-sink.md | 60 +
versioned_docs/version-2.11.0/io-cassandra.md | 5 +
versioned_docs/version-2.11.0/io-cdc-canal.md | 5 +
versioned_docs/version-2.11.0/io-cdc-debezium.md | 487 ++++
versioned_docs/version-2.11.0/io-cdc.md | 25 +
versioned_docs/version-2.11.0/io-cli.md | 586 ++++
versioned_docs/version-2.11.0/io-connectors.md | 274 ++
.../version-2.11.0/io-debezium-source.md | 719 +++++
versioned_docs/version-2.11.0/io-debug.md | 391 +++
versioned_docs/version-2.11.0/io-develop.md | 394 +++
.../version-2.11.0/io-dynamodb-source.md | 83 +
versioned_docs/version-2.11.0/io-dynamodb.md | 5 +
.../version-2.11.0/io-elasticsearch-sink.md | 238 ++
versioned_docs/version-2.11.0/io-elasticsearch.md | 5 +
versioned_docs/version-2.11.0/io-file-source.md | 154 +
versioned_docs/version-2.11.0/io-file.md | 5 +
versioned_docs/version-2.11.0/io-flume-sink.md | 59 +
versioned_docs/version-2.11.0/io-flume-source.md | 59 +
versioned_docs/version-2.11.0/io-hbase-sink.md | 69 +
versioned_docs/version-2.11.0/io-hbase.md | 5 +
versioned_docs/version-2.11.0/io-hdfs.md | 5 +
versioned_docs/version-2.11.0/io-hdfs2-sink.md | 66 +
versioned_docs/version-2.11.0/io-hdfs3-sink.md | 61 +
versioned_docs/version-2.11.0/io-http-sink.md | 62 +
versioned_docs/version-2.11.0/io-influxdb-sink.md | 118 +
versioned_docs/version-2.11.0/io-influxdb.md | 5 +
versioned_docs/version-2.11.0/io-jdbc-sink.md | 187 ++
versioned_docs/version-2.11.0/io-jdbc.md | 5 +
versioned_docs/version-2.11.0/io-kafka-sink.md | 82 +
versioned_docs/version-2.11.0/io-kafka-source.md | 222 ++
versioned_docs/version-2.11.0/io-kafka.md | 5 +
versioned_docs/version-2.11.0/io-kinesis-sink.md | 83 +
versioned_docs/version-2.11.0/io-kinesis-source.md | 87 +
versioned_docs/version-2.11.0/io-kinesis.md | 5 +
versioned_docs/version-2.11.0/io-mongo-sink.md | 58 +
versioned_docs/version-2.11.0/io-mongo-source.md | 61 +
versioned_docs/version-2.11.0/io-mongo.md | 5 +
versioned_docs/version-2.11.0/io-netty-source.md | 204 ++
versioned_docs/version-2.11.0/io-netty.md | 5 +
versioned_docs/version-2.11.0/io-nsq-source.md | 26 +
versioned_docs/version-2.11.0/io-nsq.md | 5 +
versioned_docs/version-2.11.0/io-overview.md | 155 +
versioned_docs/version-2.11.0/io-quickstart.md | 845 ++++++
versioned_docs/version-2.11.0/io-rabbitmq-sink.md | 87 +
.../version-2.11.0/io-rabbitmq-source.md | 87 +
versioned_docs/version-2.11.0/io-rabbitmq.md | 5 +
versioned_docs/version-2.11.0/io-redis-sink.md | 142 +
versioned_docs/version-2.11.0/io-redis.md | 5 +
versioned_docs/version-2.11.0/io-solr-sink.md | 64 +
versioned_docs/version-2.11.0/io-solr.md | 5 +
versioned_docs/version-2.11.0/io-tcp.md | 5 +
versioned_docs/version-2.11.0/io-twitter-source.md | 33 +
versioned_docs/version-2.11.0/io-twitter.md | 6 +
versioned_docs/version-2.11.0/io-use.md | 1664 +++++++++++
versioned_docs/version-2.11.0/kubernetes-helm.md | 369 +++
.../version-2.11.0/performance-pulsar-perf.md | 246 ++
.../version-2.11.0/pulsar-api-overview.md | 33 +
.../version-2.11.0/reference-cli-tools.md | 29 +
.../version-2.11.0/reference-configuration.md | 7 +
.../version-2.11.0/reference-connector-admin.md | 12 +
versioned_docs/version-2.11.0/reference-landing.md | 15 +
versioned_docs/version-2.11.0/reference-metrics.md | 720 +++++
.../version-2.11.0/reference-pulsar-admin.md | 3018 ++++++++++++++++++++
.../version-2.11.0/reference-rest-api-overview.md | 20 +
.../version-2.11.0/reference-terminology.md | 176 ++
.../schema-evolution-compatibility.md | 12 +
.../version-2.11.0/schema-get-started.md | 956 +++++++
versioned_docs/version-2.11.0/schema-manage.md | 12 +
versioned_docs/version-2.11.0/schema-overview.md | 150 +
versioned_docs/version-2.11.0/schema-understand.md | 376 +++
versioned_docs/version-2.11.0/security-athenz.md | 188 ++
.../version-2.11.0/security-authorization.md | 118 +
.../version-2.11.0/security-basic-auth.md | 152 +
.../version-2.11.0/security-bouncy-castle.md | 142 +
.../version-2.11.0/security-encryption.md | 380 +++
.../version-2.11.0/security-extending.md | 90 +
versioned_docs/version-2.11.0/security-jwt.md | 237 ++
versioned_docs/version-2.11.0/security-kerberos.md | 314 ++
versioned_docs/version-2.11.0/security-oauth2.md | 267 ++
versioned_docs/version-2.11.0/security-overview.md | 74 +
.../version-2.11.0/security-tls-authentication.md | 254 ++
.../version-2.11.0/security-tls-transport.md | 584 ++++
.../version-2.11.0/security-token-admin.md | 162 ++
.../sql-deployment-configurations.md | 255 ++
.../version-2.11.0/sql-getting-started.md | 118 +
versioned_docs/version-2.11.0/sql-overview.md | 21 +
versioned_docs/version-2.11.0/sql-rest-api.md | 206 ++
versioned_docs/version-2.11.0/standalone-docker.md | 199 ++
versioned_docs/version-2.11.0/standalone.md | 12 +
.../version-2.11.0/tiered-storage-aliyun.md | 204 ++
.../version-2.11.0/tiered-storage-aws.md | 248 ++
.../version-2.11.0/tiered-storage-azure.md | 191 ++
.../version-2.11.0/tiered-storage-filesystem.md | 575 ++++
.../version-2.11.0/tiered-storage-gcs.md | 242 ++
.../version-2.11.0/tiered-storage-overview.md | 73 +
versioned_docs/version-2.11.0/tiered-storage-s3.md | 202 ++
versioned_docs/version-2.11.0/transaction-api.md | 149 +
.../version-2.11.0/transaction-guarantee.md | 16 +
.../version-2.11.0/tutorials-namespace.md | 37 +
.../version-2.11.0/tutorials-produce-consume.md | 75 +
versioned_docs/version-2.11.0/tutorials-tenant.md | 54 +
versioned_docs/version-2.11.0/tutorials-topic.md | 39 +
versioned_docs/version-2.11.0/txn-how.md | 150 +
versioned_docs/version-2.11.0/txn-monitor.md | 9 +
versioned_docs/version-2.11.0/txn-use.md | 94 +
versioned_docs/version-2.11.0/txn-what.md | 59 +
versioned_docs/version-2.11.0/txn-why.md | 44 +
.../version-2.11.0/window-functions-context.md | 529 ++++
versioned_sidebars/version-2.11.0-sidebars.json | 413 +++
versions.json | 1 +
260 files changed, 48013 insertions(+)
diff --git a/releases.json b/releases.json
index 2476ab3697a..cf2b3685503 100644
--- a/releases.json
+++ b/releases.json
@@ -1,4 +1,5 @@
[
+ "2.11.0",
"2.10.3",
"2.10.2",
"2.10.1",
diff --git a/versioned_docs/version-2.11.0/about.md b/versioned_docs/version-2.11.0/about.md
new file mode 100644
index 00000000000..b102dda3167
--- /dev/null
+++ b/versioned_docs/version-2.11.0/about.md
@@ -0,0 +1,58 @@
+---
+slug: /
+id: about
+title: Welcome to the Apache Pulsar documentation portal
+sidebar_label: "About"
+---
+
+import BlockLinks from "@site/src/components/BlockLinks";
+import BlockLink from "@site/src/components/BlockLink";
+import { docUrl } from "@site/src/utils/index";
+
+
+# Welcome to the Apache Pulsar documentation portal
+***
+
+This portal holds a variety of topics, tutorials, guides, and reference material to help you work with Pulsar.
+
+## Choose your path....
+Select one of the content blocks below to begin your Pulsar journey. If you ...
+* Are new to Pulsar, start with **About Pulsar** to learn about features and concepts.
+* Want to jump to the quickstart, select **Get Started**.
+* Are an operator responsible for architecting and supporting Apache Pulsar, start with **Install, Deploy, Upgrade**.
+* Are a developer who wants to master Apache Pulsar, select **Pulsar for Developers**.
+* Want to try out Pulsar, select **How To** for access to the "hello world" tutorial.
+* An experienced Pulsar coder looking for API, metrics, or configuration documentation, go to **Reference**.
+
+<BlockLinks>
+ <BlockLink title="About Pulsar" url="/docs/next/concepts-overview/" />
+ <BlockLink title="Get Started" url="/docs/next/getting-started-home/" />
+ <BlockLink title="Install, Deploy, Upgrade" url="/docs/next/install-deploy-upgrade-landing/" />
+ <BlockLink title="Pulsar for Developers" url="/docs/next/developers-landing/" />
+ <BlockLink title="How To" url="/docs/next/how-to-landing/" />
+ <BlockLink title="Reference" url="/docs/next/reference-landing/" />
+</BlockLinks>
+
+## Continuous Improvement
+***
+
+As you probably know, we are working on a new user experience for our documentation portal that will make learning about and building on top of Apache Pulsar a much better experience. Whether you need overview concepts, how-to procedures, curated guides or quick references, we’re building content to support it. This welcome page is just the first step. We will be providing updates every month.
+
+## Help Improve These Documents
+***
+
+You’ll notice an Edit button at the bottom and top of each page. Click it to open a landing page with instructions for requesting changes to posted documents. These are your resources. Participation is not only welcomed – it’s essential!
+
+:::tip
+
+For how to make contributions to documentation, see [Pulsar Documentation Contribution Guide](pathname:///contribute/document-intro).
+
+:::
+
+## Join the Community!
+***
+
+The Pulsar community on GitHub is active, passionate, and knowledgeable. Join discussions, voice opinions, suggest features, and dive into the code itself. Find your Pulsar family here at [apache/pulsar](https://github.com/apache/pulsar).
+
+An equally passionate community can be found in the [Pulsar Slack channel](https://apache-pulsar.slack.com/). You’ll need an invitation to join, but many Github Pulsar community members are Slack members too. Join, hang out, learn, and make some new friends.
+
diff --git a/versioned_docs/version-2.11.0/adaptors-kafka.md b/versioned_docs/version-2.11.0/adaptors-kafka.md
new file mode 100644
index 00000000000..49761504779
--- /dev/null
+++ b/versioned_docs/version-2.11.0/adaptors-kafka.md
@@ -0,0 +1,265 @@
+---
+id: adaptors-kafka
+title: Pulsar adaptor for Apache Kafka
+sidebar_label: "Kafka client wrapper"
+---
+
+
+Pulsar provides an easy option for applications that are currently written using the [Apache Kafka](http://kafka.apache.org) Java client API.
+
+## Use the Pulsar Kafka compatibility wrapper
+
+In an existing application, change the regular Kafka client dependency and replace it with the Pulsar Kafka wrapper. Remove the following dependency in `pom.xml`:
+
+```xml
+<dependency>
+ <groupId>org.apache.kafka</groupId>
+ <artifactId>kafka-clients</artifactId>
+ <version>0.10.2.1</version>
+</dependency>
+```
+
+Then include this dependency for the Pulsar Kafka wrapper:
+
+```xml
+<dependency>
+ <groupId>org.apache.pulsar</groupId>
+ <artifactId>pulsar-client-kafka</artifactId>
+ <version>@pulsar:version@</version>
+</dependency>
+```
+
+With the new dependency, the existing code works without any changes. You need to adjust the configuration, and make sure it points the
+producers and consumers to Pulsar service rather than Kafka, and uses a particular
+Pulsar topic.
+
+## Use the Pulsar Kafka compatibility wrapper together with existing Kafka client
+
+When migrating from Kafka to Pulsar, the application might use the original Kafka client
+and the Pulsar Kafka wrapper together during migration. You should consider using the
+unshaded Pulsar Kafka client wrapper.
+
+```xml
+<dependency>
+ <groupId>org.apache.pulsar</groupId>
+ <artifactId>pulsar-client-kafka-original</artifactId>
+ <version>@pulsar:version@</version>
+</dependency>
+```
+
+When using this dependency, construct producers using `org.apache.kafka.clients.producer.PulsarKafkaProducer`
+instead of `org.apache.kafka.clients.producer.KafkaProducer` and `org.apache.kafka.clients.producer.PulsarKafkaConsumer` for consumers.
+
+## Producer example
+
+```java
+// Topic needs to be a regular Pulsar topic
+String topic = "persistent://public/default/my-topic";
+
+Properties props = new Properties();
+// Point to a Pulsar service
+props.put("bootstrap.servers", "pulsar://localhost:6650");
+
+props.put("key.serializer", IntegerSerializer.class.getName());
+props.put("value.serializer", StringSerializer.class.getName());
+
+Producer<Integer, String> producer = new KafkaProducer(props);
+
+for (int i = 0; i < 10; i++) {
+ producer.send(new ProducerRecord<Integer, String>(topic, i, "hello-" + i));
+ log.info("Message {} sent successfully", i);
+}
+
+producer.close();
+```
+
+## Consumer example
+
+```java
+String topic = "persistent://public/default/my-topic";
+
+Properties props = new Properties();
+// Point to a Pulsar service
+props.put("bootstrap.servers", "pulsar://localhost:6650");
+props.put("group.id", "my-subscription-name");
+props.put("enable.auto.commit", "false");
+props.put("key.deserializer", IntegerDeserializer.class.getName());
+props.put("value.deserializer", StringDeserializer.class.getName());
+
+Consumer<Integer, String> consumer = new KafkaConsumer(props);
+consumer.subscribe(Arrays.asList(topic));
+
+while (true) {
+ ConsumerRecords<Integer, String> records = consumer.poll(100);
+ records.forEach(record -> {
+ log.info("Received record: {}", record);
+ });
+
+ // Commit last offset
+ consumer.commitSync();
+}
+```
+
+## Complete Examples
+
+You can find the complete producer and consumer examples [here](https://github.com/apache/pulsar-adapters/tree/master/pulsar-client-kafka-compat/pulsar-client-kafka-tests/src/test/java/org/apache/pulsar/client/kafka/compat/examples).
+
+## Compatibility matrix
+
+Currently, the Pulsar Kafka wrapper supports most of the operations offered by the Kafka API.
+
+### Producer
+
+APIs:
+
+| Producer Method | Supported | Notes |
+|:------------------------------------------------------------------------------|:----------|:-------------------------------------------------------------------------|
+| `Future<RecordMetadata> send(ProducerRecord<K, V> record)` | Yes | |
+| `Future<RecordMetadata> send(ProducerRecord<K, V> record, Callback callback)` | Yes | |
+| `void flush()` | Yes | |
+| `List<PartitionInfo> partitionsFor(String topic)` | No | |
+| `Map<MetricName, ? extends Metric> metrics()` | No | |
+| `void close()` | Yes | |
+| `void close(long timeout, TimeUnit unit)` | Yes | |
+
+Properties:
+
+| Config property | Supported | Notes |
+|:----------------------------------------|:----------|:------------------------------------------------------------------------------|
+| `acks` | Ignored | Durability and quorum writes are configured at the namespace level |
+| `auto.offset.reset` | Yes | It uses a default value of `earliest` if you do not give a specific setting. |
+| `batch.size` | Ignored | |
+| `bootstrap.servers` | Yes | |
+| `buffer.memory` | Ignored | |
+| `client.id` | Ignored | |
+| `compression.type` | Yes | Allows `gzip` and `lz4`. No `snappy`. |
+| `connections.max.idle.ms` | Yes | Only support up to 2,147,483,647,000(Integer.MAX_VALUE * 1000) ms of idle time|
+| `interceptor.classes` | Yes | |
+| `key.serializer` | Yes | |
+| `linger.ms` | Yes | Controls the group commit time when batching messages |
+| `max.block.ms` | Ignored | |
+| `max.in.flight.requests.per.connection` | Ignored | In Pulsar ordering is maintained even with multiple requests in flight |
+| `max.request.size` | Ignored | |
+| `metric.reporters` | Ignored | |
+| `metrics.num.samples` | Ignored | |
+| `metrics.sample.window.ms` | Ignored | |
+| `partitioner.class` | Yes | |
+| `receive.buffer.bytes` | Ignored | |
+| `reconnect.backoff.ms` | Ignored | |
+| `request.timeout.ms` | Ignored | |
+| `retries` | Ignored | Pulsar client retries with exponential backoff until the send timeout expires. |
+| `send.buffer.bytes` | Ignored | |
+| `timeout.ms` | Yes | |
+| `value.serializer` | Yes | |
+
+
+### Consumer
+
+The following table lists consumer APIs.
+
+| Consumer Method | Supported | Notes |
+|:--------------------------------------------------------------------------------------------------------|:----------|:------|
+| `Set<TopicPartition> assignment()` | No | |
+| `Set<String> subscription()` | Yes | |
+| `void subscribe(Collection<String> topics)` | Yes | |
+| `void subscribe(Collection<String> topics, ConsumerRebalanceListener callback)` | No | |
+| `void assign(Collection<TopicPartition> partitions)` | No | |
+| `void subscribe(Pattern pattern, ConsumerRebalanceListener callback)` | No | |
+| `void unsubscribe()` | Yes | |
+| `ConsumerRecords<K, V> poll(long timeoutMillis)` | Yes | |
+| `void commitSync()` | Yes | |
+| `void commitSync(Map<TopicPartition, OffsetAndMetadata> offsets)` | Yes | |
+| `void commitAsync()` | Yes | |
+| `void commitAsync(OffsetCommitCallback callback)` | Yes | |
+| `void commitAsync(Map<TopicPartition, OffsetAndMetadata> offsets, OffsetCommitCallback callback)` | Yes | |
+| `void seek(TopicPartition partition, long offset)` | Yes | |
+| `void seekToBeginning(Collection<TopicPartition> partitions)` | Yes | |
+| `void seekToEnd(Collection<TopicPartition> partitions)` | Yes | |
+| `long position(TopicPartition partition)` | Yes | |
+| `OffsetAndMetadata committed(TopicPartition partition)` | Yes | |
+| `Map<MetricName, ? extends Metric> metrics()` | No | |
+| `List<PartitionInfo> partitionsFor(String topic)` | No | |
+| `Map<String, List<PartitionInfo>> listTopics()` | No | |
+| `Set<TopicPartition> paused()` | No | |
+| `void pause(Collection<TopicPartition> partitions)` | No | |
+| `void resume(Collection<TopicPartition> partitions)` | No | |
+| `Map<TopicPartition, OffsetAndTimestamp> offsetsForTimes(Map<TopicPartition, Long> timestampsToSearch)` | No | |
+| `Map<TopicPartition, Long> beginningOffsets(Collection<TopicPartition> partitions)` | No | |
+| `Map<TopicPartition, Long> endOffsets(Collection<TopicPartition> partitions)` | No | |
+| `void close()` | Yes | |
+| `void close(long timeout, TimeUnit unit)` | Yes | |
+| `void wakeup()` | No | |
+
+Properties:
+
+| Config property | Supported | Notes |
+|:--------------------------------|:----------|:------------------------------------------------------|
+| `group.id` | Yes | Maps to a Pulsar subscription name |
+| `max.poll.records` | Yes | |
+| `max.poll.interval.ms` | Ignored | Messages are "pushed" from broker |
+| `session.timeout.ms` | Ignored | |
+| `heartbeat.interval.ms` | Ignored | |
+| `bootstrap.servers` | Yes | Needs to point to a single Pulsar service URL |
+| `enable.auto.commit` | Yes | |
+| `auto.commit.interval.ms` | Ignored | With auto-commit, acks are sent immediately to broker |
+| `partition.assignment.strategy` | Ignored | |
+| `auto.offset.reset` | Yes | Only support earliest and latest. |
+| `fetch.min.bytes` | Ignored | |
+| `fetch.max.bytes` | Ignored | |
+| `fetch.max.wait.ms` | Ignored | |
+| `interceptor.classes` | Yes | |
+| `metadata.max.age.ms` | Ignored | |
+| `max.partition.fetch.bytes` | Ignored | |
+| `send.buffer.bytes` | Ignored | |
+| `receive.buffer.bytes` | Ignored | |
+| `client.id` | Ignored | |
+
+
+## Customize Pulsar configurations
+
+You can configure Pulsar authentication provider directly from the Kafka properties.
+
+### Pulsar client properties
+
+| Config property | Default | Notes |
+|:---------------------------------------|:--------|:---------------------------------------------------------------------------------------|
+| [`pulsar.authentication.class`](/api/client/org/apache/pulsar/client/api/ClientConfiguration.html#setAuthentication-org.apache.pulsar.client.api.Authentication-) | | Configure to auth provider. For example, `org.apache.pulsar.client.impl.auth.AuthenticationTls`.|
+| [`pulsar.authentication.params.map`](/api/client/org/apache/pulsar/client/api/ClientConfiguration.html#setAuthentication-java.lang.String-java.util.Map-) | | Map which represents parameters for the Authentication-Plugin. |
+| [`pulsar.authentication.params.string`](/api/client/org/apache/pulsar/client/api/ClientConfiguration.html#setAuthentication-java.lang.String-java.lang.String-) | | String which represents parameters for the Authentication-Plugin, for example, `key1:val1,key2:val2`. |
+| [`pulsar.use.tls`](/api/client/org/apache/pulsar/client/api/ClientConfiguration.html#setUseTls-boolean-) | `false` | Enable TLS transport encryption. |
+| [`pulsar.tls.trust.certs.file.path`](/api/client/org/apache/pulsar/client/api/ClientConfiguration.html#setTlsTrustCertsFilePath-java.lang.String-) | | Path for the TLS trust certificate store. |
+| [`pulsar.tls.allow.insecure.connection`](/api/client/org/apache/pulsar/client/api/ClientConfiguration.html#setTlsAllowInsecureConnection-boolean-) | `false` | Accept self-signed certificates from brokers. |
+| [`pulsar.operation.timeout.ms`](/api/client/org/apache/pulsar/client/api/ClientConfiguration.html#setOperationTimeout-int-java.util.concurrent.TimeUnit-) | `30000` | General operations timeout. |
+| [`pulsar.stats.interval.seconds`](/api/client/org/apache/pulsar/client/api/ClientConfiguration.html#setStatsInterval-long-java.util.concurrent.TimeUnit-) | `60` | Pulsar client lib stats printing interval. |
+| [`pulsar.num.io.threads`](/api/client/org/apache/pulsar/client/api/ClientConfiguration.html#setIoThreads-int-) | `1` | The number of Netty IO threads to use. |
+| [`pulsar.connections.per.broker`](/api/client/org/apache/pulsar/client/api/ClientConfiguration.html#setConnectionsPerBroker-int-) | `1` | The maximum number of connection to each broker. |
+| [`pulsar.use.tcp.nodelay`](/api/client/org/apache/pulsar/client/api/ClientConfiguration.html#setUseTcpNoDelay-boolean-) | `true` | TCP no-delay. |
+| [`pulsar.concurrent.lookup.requests`](/api/client/org/apache/pulsar/client/api/ClientConfiguration.html#setConcurrentLookupRequest-int-) | `50000` | The maximum number of concurrent topic lookups. |
+| [`pulsar.max.number.rejected.request.per.connection`](/api/client/org/apache/pulsar/client/api/ClientConfiguration.html#setMaxNumberOfRejectedRequestPerConnection-int-) | `50` | The threshold of errors to forcefully close a connection. |
+| [`pulsar.keepalive.interval.ms`](/api/client/org/apache/pulsar/client/api/ClientBuilder.html#keepAliveInterval-int-java.util.concurrent.TimeUnit-)| `30000` | Keep alive interval for each client-broker-connection. |
+
+
+### Pulsar producer properties
+
+| Config property | Default | Notes |
+|:---------------------------------------|:--------|:---------------------------------------------------------------------------------------|
+| [`pulsar.producer.name`](/api/client/org/apache/pulsar/client/api/ProducerConfiguration.html#setProducerName-java.lang.String-) | | Specify the producer name. |
+| [`pulsar.producer.initial.sequence.id`](/api/client/org/apache/pulsar/client/api/ProducerConfiguration.html#setInitialSequenceId-long-) | | Specify baseline for sequence ID of this producer. |
+| [`pulsar.producer.max.pending.messages`](/api/client/org/apache/pulsar/client/api/ProducerConfiguration.html#setMaxPendingMessages-int-) | `1000` | Set the maximum size of the message queue pending to receive an acknowledgment from the broker. |
+| [`pulsar.producer.max.pending.messages.across.partitions`](/api/client/org/apache/pulsar/client/api/ProducerConfiguration.html#setMaxPendingMessagesAcrossPartitions-int-) | `50000` | Set the maximum number of pending messages across all the partitions. |
+| [`pulsar.producer.batching.enabled`](/api/client/org/apache/pulsar/client/api/ProducerConfiguration.html#setBatchingEnabled-boolean-) | `true` | Control whether automatic batching of messages is enabled for the producer. |
+| [`pulsar.producer.batching.max.messages`](/api/client/org/apache/pulsar/client/api/ProducerConfiguration.html#setBatchingMaxMessages-int-) | `1000` | The maximum number of messages in a batch. |
+| [`pulsar.block.if.producer.queue.full`](/api/client/org/apache/pulsar/client/api/ProducerConfiguration.html#setBlockIfQueueFull-boolean-) | | Specify the block producer if queue is full. |
+| [`pulsar.crypto.reader.factory.class.name`](/api/client/org/apache/pulsar/client/api/ProducerConfiguration.html#setCryptoKeyReader-org.apache.pulsar.client.api.CryptoKeyReader-) | | Specify the CryptoReader-Factory(`CryptoKeyReaderFactory`) classname which allows producer to create CryptoKeyReader. |
+
+
+### Pulsar consumer Properties
+
+| Config property | Default | Notes |
+|:---------------------------------------|:--------|:---------------------------------------------------------------------------------------|
+| [`pulsar.consumer.name`](/api/client/org/apache/pulsar/client/api/ConsumerConfiguration.html#setConsumerName-java.lang.String-) | | Specify the consumer name. |
+| [`pulsar.consumer.receiver.queue.size`](/api/client/org/apache/pulsar/client/api/ConsumerConfiguration.html#setReceiverQueueSize-int-) | 1000 | Set the size of the consumer receiver queue. |
+| [`pulsar.consumer.acknowledgments.group.time.millis`](/api/client/org/apache/pulsar/client/api/ConsumerBuilder.html#acknowledgmentGroupTime-long-java.util.concurrent.TimeUnit-) | 100 | Set the maximum amount of group time for consumers to send the acknowledgments to the broker. |
+| [`pulsar.consumer.total.receiver.queue.size.across.partitions`](/api/client/org/apache/pulsar/client/api/ConsumerConfiguration.html#setMaxTotalReceiverQueueSizeAcrossPartitions-int-) | 50000 | Set the maximum size of the total receiver queue across partitions. |
+| [`pulsar.consumer.subscription.topics.mode`](/api/client/org/apache/pulsar/client/api/ConsumerBuilder.html#subscriptionTopicsMode-Mode-) | PersistentOnly | Set the subscription topic mode for consumers. |
+| [`pulsar.crypto.reader.factory.class.name`](/api/client/org/apache/pulsar/client/api/ProducerConfiguration.html#setCryptoKeyReader-org.apache.pulsar.client.api.CryptoKeyReader-) | | Specify the CryptoReader-Factory(`CryptoKeyReaderFactory`) classname which allows consumer to create CryptoKeyReader. |
diff --git a/versioned_docs/version-2.11.0/adaptors-spark.md b/versioned_docs/version-2.11.0/adaptors-spark.md
new file mode 100644
index 00000000000..d97d2349669
--- /dev/null
+++ b/versioned_docs/version-2.11.0/adaptors-spark.md
@@ -0,0 +1,82 @@
+---
+id: adaptors-spark
+title: Pulsar adaptor for Apache Spark
+sidebar_label: "Apache Spark"
+---
+
+## Spark Streaming receiver
+The Spark Streaming receiver for Pulsar is a custom receiver that enables Apache [Spark Streaming](https://spark.apache.org/streaming/) to receive raw data from Pulsar.
+
+An application can receive data in [Resilient Distributed Dataset](https://spark.apache.org/docs/latest/programming-guide.html#resilient-distributed-datasets-rdds) (RDD) format via the Spark Streaming receiver and can process it in a variety of ways.
+
+### Prerequisites
+
+To use the receiver, include a dependency for the `pulsar-spark` library in your Java configuration.
+
+#### Maven
+
+If you're using Maven, add this to your `pom.xml`:
+
+```xml
+<!-- in your <properties> block -->
+<pulsar.version>@pulsar:version@</pulsar.version>
+
+<!-- in your <dependencies> block -->
+<dependency>
+ <groupId>org.apache.pulsar</groupId>
+ <artifactId>pulsar-spark</artifactId>
+ <version>${pulsar.version}</version>
+</dependency>
+```
+
+#### Gradle
+
+If you're using Gradle, add this to your `build.gradle` file:
+
+```groovy
+def pulsarVersion = "@pulsar:version@"
+
+dependencies {
+ compile group: 'org.apache.pulsar', name: 'pulsar-spark', version: pulsarVersion
+}
+```
+
+### Usage
+
+Pass an instance of `SparkStreamingPulsarReceiver` to the `receiverStream` method in `JavaStreamingContext`:
+
+```java
+ String serviceUrl = "pulsar://localhost:6650/";
+ String topic = "persistent://public/default/test_src";
+ String subs = "test_sub";
+
+ SparkConf sparkConf = new SparkConf().setMaster("local[*]").setAppName("Pulsar Spark Example");
+
+ JavaStreamingContext jsc = new JavaStreamingContext(sparkConf, Durations.seconds(60));
+
+ ConsumerConfigurationData<byte[]> pulsarConf = new ConsumerConfigurationData();
+
+ Set<String> set = new HashSet();
+ set.add(topic);
+ pulsarConf.setTopicNames(set);
+ pulsarConf.setSubscriptionName(subs);
+
+ SparkStreamingPulsarReceiver pulsarReceiver = new SparkStreamingPulsarReceiver(
+ serviceUrl,
+ pulsarConf,
+ new AuthenticationDisabled());
+
+ JavaReceiverInputDStream<byte[]> lineDStream = jsc.receiverStream(pulsarReceiver);
+```
+
+For a complete example, click [here](https://github.com/apache/pulsar-adapters/blob/master/examples/spark/src/main/java/org/apache/spark/streaming/receiver/example/SparkStreamingPulsarReceiverExample.java). In this example, the number of messages that contain the string "Pulsar" in received messages is counted.
+
+Note that if needed, other Pulsar authentication classes can be used. For example, to use a token during authentication the following parameters for the `SparkStreamingPulsarReceiver` constructor can be set:
+
+```java
+SparkStreamingPulsarReceiver pulsarReceiver = new SparkStreamingPulsarReceiver(
+ serviceUrl,
+ pulsarConf,
+ new AuthenticationToken("token:<secret-JWT-token>"));
+```
+
diff --git a/versioned_docs/version-2.11.0/adaptors-storm.md b/versioned_docs/version-2.11.0/adaptors-storm.md
new file mode 100644
index 00000000000..7f05e79dde1
--- /dev/null
+++ b/versioned_docs/version-2.11.0/adaptors-storm.md
@@ -0,0 +1,89 @@
+---
+id: adaptors-storm
+title: Pulsar adaptor for Apache Storm
+sidebar_label: "Apache Storm"
+---
+
+Pulsar Storm is an adaptor for integrating with [Apache Storm](http://storm.apache.org/) topologies. It provides core Storm implementations for sending and receiving data.
+
+An application can inject data into a Storm topology via a generic Pulsar spout, as well as consume data from a Storm topology via a generic Pulsar bolt.
+
+## Using the Pulsar Storm Adaptor
+
+Include dependency for Pulsar Storm Adaptor:
+
+```xml
+<dependency>
+ <groupId>org.apache.pulsar</groupId>
+ <artifactId>pulsar-storm</artifactId>
+ <version>${pulsar.version}</version>
+</dependency>
+```
+
+## Pulsar Spout
+
+The Pulsar Spout allows for the data published on a topic to be consumed by a Storm topology. It emits a Storm tuple based on the message received and the `MessageToValuesMapper` provided by the client.
+
+The tuples that fail to be processed by the downstream bolts will be re-injected by the spout with an exponential backoff, within a configurable timeout (the default is 60 seconds) or a configurable number of retries, whichever comes first, after which it is acknowledged by the consumer. Here's an example construction of a spout:
+
+```java
+MessageToValuesMapper messageToValuesMapper = new MessageToValuesMapper() {
+
+ @Override
+ public Values toValues(Message msg) {
+ return new Values(new String(msg.getData()));
+ }
+
+ @Override
+ public void declareOutputFields(OutputFieldsDeclarer declarer) {
+ // declare the output fields
+ declarer.declare(new Fields("string"));
+ }
+};
+
+// Configure a Pulsar Spout
+PulsarSpoutConfiguration spoutConf = new PulsarSpoutConfiguration();
+spoutConf.setServiceUrl("pulsar://broker.messaging.usw.example.com:6650");
+spoutConf.setTopic("persistent://my-property/usw/my-ns/my-topic1");
+spoutConf.setSubscriptionName("my-subscriber-name1");
+spoutConf.setMessageToValuesMapper(messageToValuesMapper);
+
+// Create a Pulsar Spout
+PulsarSpout spout = new PulsarSpout(spoutConf);
+```
+
+For a complete example, click [here](https://github.com/apache/pulsar-adapters/blob/master/pulsar-storm/src/test/java/org/apache/pulsar/storm/PulsarSpoutTest.java).
+
+## Pulsar Bolt
+
+The Pulsar bolt allows data in a Storm topology to be published on a topic. It publishes messages based on the Storm tuple received and the `TupleToMessageMapper` provided by the client.
+
+A partitioned topic can also be used to publish messages on different topics. In the implementation of the `TupleToMessageMapper`, a "key" will need to be provided in the message which will send the messages with the same key to the same topic. Here's an example bolt:
+
+```java
+TupleToMessageMapper tupleToMessageMapper = new TupleToMessageMapper() {
+
+ @Override
+ public TypedMessageBuilder<byte[]> toMessage(TypedMessageBuilder<byte[]> msgBuilder, Tuple tuple) {
+ String receivedMessage = tuple.getString(0);
+ // message processing
+ String processedMsg = receivedMessage + "-processed";
+ return msgBuilder.value(processedMsg.getBytes());
+ }
+
+ @Override
+ public void declareOutputFields(OutputFieldsDeclarer declarer) {
+ // declare the output fields
+ }
+};
+
+// Configure a Pulsar Bolt
+PulsarBoltConfiguration boltConf = new PulsarBoltConfiguration();
+boltConf.setServiceUrl("pulsar://broker.messaging.usw.example.com:6650");
+boltConf.setTopic("persistent://my-property/usw/my-ns/my-topic2");
+boltConf.setTupleToMessageMapper(tupleToMessageMapper);
+
+// Create a Pulsar Bolt
+PulsarBolt bolt = new PulsarBolt(boltConf);
+```
+
diff --git a/versioned_docs/version-2.11.0/admin-api-brokers.md b/versioned_docs/version-2.11.0/admin-api-brokers.md
new file mode 100644
index 00000000000..11253175f11
--- /dev/null
+++ b/versioned_docs/version-2.11.0/admin-api-brokers.md
@@ -0,0 +1,283 @@
+---
+id: admin-api-brokers
+title: Managing Brokers
+sidebar_label: "Brokers"
+---
+
+````mdx-code-block
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+````
+
+
+:::tip
+
+ This page only shows **some frequently used operations**.
+
+ - For the latest and complete information about `Pulsar admin`, including commands, flags, descriptions, and more information, see [Pulsar admin doc](/tools/pulsar-admin/).
+
+ - For the latest and complete information about `REST API`, including parameters, responses, samples, and more, see {@inject: rest:REST:/} API doc.
+
+ - For the latest and complete information about `Java admin API`, including classes, methods, descriptions, and more, see [Java admin API doc](/api/admin/).
+
+:::
+
+Pulsar brokers consist of two components:
+
+1. An HTTP server exposing a {@inject: rest:REST:/} interface administration and [topic](reference-terminology.md#topic) lookup.
+2. A dispatcher that handles all Pulsar [message](reference-terminology.md#message) transfers.
+
+[Brokers](reference-terminology.md#broker) can be managed via:
+
+* The `brokers` command of the [`pulsar-admin`](/tools/pulsar-admin/) tool
+* The `/admin/v2/brokers` endpoint of the admin {@inject: rest:REST:/} API
+* The `brokers` method of the `PulsarAdmin` object in the [Java API](client-libraries-java.md)
+
+In addition to being configurable when you start them up, brokers can also be [dynamically configured](#dynamic-broker-configuration).
+
+For a full listing of broker-specific configuration parameters, see the [Configuration](reference-configuration.md#broker) page.
+
+## Brokers resources
+
+### List active brokers
+
+Fetch all available active brokers that are serving traffic with cluster name.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin brokers list use
+```
+
+Example output:
+
+```
+localhost:8080
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/brokers/:cluster|operation/getActiveBrokers?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.brokers().getActiveBrokers(clusterName)
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Get the information of the leader broker
+
+Fetch the information of the leader broker, for example, the service url.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin brokers leader-broker
+```
+
+Example output:
+
+```json
+{
+ "serviceUrl" : "http://localhost:8080"
+}
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/brokers/leaderBroker|operation/getLeaderBroker?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.brokers().getLeaderBroker()
+```
+
+For the detail of the code above, see [here](https://github.com/apache/pulsar/blob/master/pulsar-client-admin/src/main/java/org/apache/pulsar/client/admin/internal/BrokersImpl.java#L80)
+
+</TabItem>
+
+</Tabs>
+````
+
+#### list of namespaces owned by a given broker
+
+It finds all namespaces which are owned and served by a given broker.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin brokers namespaces use \
+ --url localhost:8080
+```
+
+Example output:
+
+```
+public/default/0x00000000_0x40000000 [broker_assignment=shared is_controlled=false is_active=true]
+public/default/0xc0000000_0xffffffff [broker_assignment=shared is_controlled=false is_active=true]
+public/functions/0x40000000_0x80000000 [broker_assignment=shared is_controlled=false is_active=true]
+public/functions/0x00000000_0x40000000 [broker_assignment=shared is_controlled=false is_active=true]
+pulsar/standalone/localhost:8080/0x00000000_0xffffffff [broker_assignment=shared is_controlled=false is_active=true]
+pulsar/localhost:8080/0x00000000_0xffffffff [broker_assignment=shared is_controlled=false is_active=true]
+public/functions/0x80000000_0xc0000000 [broker_assignment=shared is_controlled=false is_active=true]
+public/default/0x80000000_0xc0000000 [broker_assignment=shared is_controlled=false is_active=true]
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/brokers/:cluster/:broker/ownedNamespaces|operation/getOwnedNamespaes?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.brokers().getOwnedNamespaces(cluster,brokerUrl);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Dynamic broker configuration
+
+One way to configure a Pulsar [broker](reference-terminology.md#broker) is to supply a [configuration](reference-configuration.md#broker) when the broker is [started up](reference-cli-tools.md).
+
+But since all broker configuration in Pulsar is stored in ZooKeeper, configuration values can also be dynamically updated *while the broker is running*. When you update broker configuration dynamically, ZooKeeper will notify the broker of the change and the broker will then override any existing configuration values.
+
+* The `brokers` command for the [`pulsar-admin`](/tools/pulsar-admin/) tool has a variety of subcommands that enable you to manipulate a broker's configuration dynamically, enabling you to [update config values](#update-dynamic-configuration) and more.
+* In the Pulsar admin {@inject: rest:REST:/} API, dynamic configuration is managed through the `/admin/v2/brokers/configuration` endpoint.
+
+### Update dynamic configuration
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+The [`update-dynamic-config`](/tools/pulsar-admin/) subcommand will update existing configuration. It takes two arguments: the name of the parameter and the new value using the `config` and `value` flag respectively. Here's an example of the [`brokerShutdownTimeoutMs`](reference-configuration.md#broker-brokerShutdownTimeoutMs) parameter:
+
+```shell
+pulsar-admin brokers update-dynamic-config --config brokerShutdownTimeoutMs --value 100
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v2/brokers/configuration/:configName/:configValue|operation/updateDynamicConfiguration?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.brokers().updateDynamicConfiguration(configName, configValue);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### List updated values
+
+Fetch a list of all potentially updatable configuration parameters.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin brokers list-dynamic-config
+```
+
+Example output:
+
+```
+forceDeleteNamespaceAllowed
+loadBalancerMemoryResourceWeight
+allowAutoTopicCreation
+brokerDeleteInactivePartitionedTopicMetadataEnabled
+managedLedgerInactiveLedgerRolloverTimeSeconds
+loadBalancerNamespaceBundleMaxMsgRate
+resourceUsageTransportPublishIntervalInSecs
+# omit...
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/brokers/configuration|operation/getDynamicConfigurationName?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.brokers().getDynamicConfigurationNames();
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### List all
+
+Fetch a list of all parameters that have been dynamically updated.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin brokers get-all-dynamic-config
+```
+Example output:
+
+```
+brokerShutdownTimeoutMs 100
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/brokers/configuration/values|operation/getAllDynamicConfigurations?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.brokers().getAllDynamicConfigurations();
+```
+
+</TabItem>
+
+</Tabs>
+````
diff --git a/versioned_docs/version-2.11.0/admin-api-clusters.md b/versioned_docs/version-2.11.0/admin-api-clusters.md
new file mode 100644
index 00000000000..ee1887baa2c
--- /dev/null
+++ b/versioned_docs/version-2.11.0/admin-api-clusters.md
@@ -0,0 +1,305 @@
+---
+id: admin-api-clusters
+title: Managing Clusters
+sidebar_label: "Clusters"
+---
+
+````mdx-code-block
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+````
+
+
+:::tip
+
+ This page only shows **some frequently used operations**.
+
+ - For the latest and complete information about `Pulsar admin`, including commands, flags, descriptions, and more, see [Pulsar admin doc](/tools/pulsar-admin/)
+
+ - For the latest and complete information about `REST API`, including parameters, responses, samples, and more, see {@inject: rest:REST:/} API doc.
+
+ - For the latest and complete information about `Java admin API`, including classes, methods, descriptions, and more, see [Java admin API doc](/api/admin/).
+
+:::
+
+Pulsar clusters consist of one or more Pulsar [brokers](reference-terminology.md#broker), one or more [BookKeeper](reference-terminology.md#bookkeeper)
+servers (aka [bookies](reference-terminology.md#bookie)), and a [ZooKeeper](https://zookeeper.apache.org) cluster that provides configuration and coordination management.
+
+Clusters can be managed via:
+
+* The `clusters` command of the [`pulsar-admin`](/tools/pulsar-admin/) tool
+* The `/admin/v2/clusters` endpoint of the admin {@inject: rest:REST:/} API
+* The `clusters` method of the `PulsarAdmin` object in the [Java API](client-libraries-java.md)
+
+## Clusters resources
+
+### Provision
+
+New clusters can be provisioned using the admin interface.
+
+:::note
+
+This operation requires superuser privileges.
+
+:::
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+You can provision a new cluster using the [`create`](/tools/pulsar-admin/) subcommand. Here's an example:
+
+```shell
+pulsar-admin clusters create cluster-1 \
+ --url http://my-cluster.org.com:8080 \
+ --broker-url pulsar://my-cluster.org.com:6650
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|PUT|/admin/v2/clusters/:cluster|operation/createCluster?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+ClusterData clusterData = new ClusterData(
+ serviceUrl,
+ serviceUrlTls,
+ brokerServiceUrl,
+ brokerServiceUrlTls
+);
+admin.clusters().createCluster(clusterName, clusterData);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Initialize cluster metadata
+
+When provisioning a new cluster, you need to initialize that cluster's [metadata](concepts-architecture-overview.md#metadata-store). When initializing cluster metadata, you need to specify all of the following:
+
+* The name of the cluster
+* The local metadata store connection string for the cluster
+* The configuration store connection string for the entire instance
+* The web service URL for the cluster
+* A broker service URL enabling interaction with the [brokers](reference-terminology.md#broker) in the cluster
+
+You must initialize cluster metadata *before* starting up any [brokers](admin-api-brokers.md) that will belong to the cluster.
+
+> **No cluster metadata initialization through the REST API or the Java admin API**
+>
+> Unlike most other admin functions in Pulsar, cluster metadata initialization cannot be performed via the admin REST API
+> or the admin Java client, as metadata initialization involves communicating with ZooKeeper directly.
+> Instead, you can use the [`pulsar`](reference-cli-tools.md) CLI tool, in particular
+> the [`initialize-cluster-metadata`](reference-cli-tools.md) command.
+
+Here's an example cluster metadata initialization command:
+
+```shell
+bin/pulsar initialize-cluster-metadata \
+ --cluster us-west \
+ --metadata-store zk:zk1.us-west.example.com:2181,zk2.us-west.example.com:2181/my-chroot-path \
+ --configuration-metadata-store zk:zk1.us-west.example.com:2181,zk2.us-west.example.com:2181/my-chroot-path \
+ --web-service-url http://pulsar.us-west.example.com:8080/ \
+ --web-service-url-tls https://pulsar.us-west.example.com:8443/ \
+ --broker-service-url pulsar://pulsar.us-west.example.com:6650/ \
+ --broker-service-url-tls pulsar+ssl://pulsar.us-west.example.com:6651/
+```
+
+You'll need to use `--*-tls` flags only if you're using [TLS authentication](security-tls-authentication.md) in your instance.
+
+### Get configuration
+
+You can fetch the [configuration](reference-configuration.md) for an existing cluster at any time.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+Use the [`get`](/tools/pulsar-admin/) subcommand and specify the name of the cluster. Here's an example:
+
+```shell
+pulsar-admin clusters get cluster-1
+```
+Output:
+
+```json
+{
+ "serviceUrl": "http://my-cluster.org.com:8080/",
+ "serviceUrlTls": null,
+ "brokerServiceUrl": "pulsar://my-cluster.org.com:6650/",
+ "brokerServiceUrlTls": null
+ "peerClusterNames": null
+}
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/clusters/:cluster|operation/getCluster?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.clusters().getCluster(clusterName);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Update
+
+You can update the configuration for an existing cluster at any time.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+Use the [`update`](/tools/pulsar-admin/) subcommand and specify new configuration values using flags.
+
+```shell
+pulsar-admin clusters update cluster-1 \
+ --url http://my-cluster.org.com:4081 \
+ --broker-url pulsar://my-cluster.org.com:3350
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v2/clusters/:cluster|operation/updateCluster?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+ClusterData clusterData = new ClusterData(
+ serviceUrl,
+ serviceUrlTls,
+ brokerServiceUrl,
+ brokerServiceUrlTls
+);
+admin.clusters().updateCluster(clusterName, clusterData);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Delete
+
+Clusters can be deleted from a Pulsar [instance](reference-terminology.md#instance).
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+Use the [`delete`](/tools/pulsar-admin/) subcommand and specify the name of the cluster.
+
+```
+pulsar-admin clusters delete cluster-1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|DELETE|/admin/v2/clusters/:cluster|operation/deleteCluster?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.clusters().deleteCluster(clusterName);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### List
+
+You can fetch a list of all clusters in a Pulsar [instance](reference-terminology.md#instance).
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+Use the [`list`](/tools/pulsar-admin/) subcommand.
+
+```shell
+pulsar-admin clusters list
+```
+
+Output:
+
+```
+cluster-1
+cluster-2
+```
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/clusters|operation/getClusters?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.clusters().getClusters();
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Update peer-cluster data
+
+Peer clusters can be configured for a given cluster in a Pulsar [instance](reference-terminology.md#instance).
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+Use the [`update-peer-clusters`](/tools/pulsar-admin/) subcommand and specify the list of peer-cluster names.
+
+```shell
+pulsar-admin update-peer-clusters cluster-1 --peer-clusters cluster-2
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v2/clusters/:cluster/peers|operation/setPeerClusterNames?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.clusters().updatePeerClusterNames(clusterName, peerClusterList);
+```
+
+</TabItem>
+
+</Tabs>
+````
\ No newline at end of file
diff --git a/versioned_docs/version-2.11.0/admin-api-functions.md b/versioned_docs/version-2.11.0/admin-api-functions.md
new file mode 100644
index 00000000000..703265cfade
--- /dev/null
+++ b/versioned_docs/version-2.11.0/admin-api-functions.md
@@ -0,0 +1,760 @@
+---
+id: admin-api-functions
+title: Manage Functions
+sidebar_label: "Functions"
+---
+
+````mdx-code-block
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+````
+
+
+:::tip
+
+ This page only shows **some frequently used operations**.
+
+ - For the latest and complete information about `Pulsar admin`, including commands, flags, descriptions, and more, see [Pulsar admin doc](/tools/pulsar-admin/)
+
+ - For the latest and complete information about `REST API`, including parameters, responses, samples, and more, see {@inject: rest:REST:/} API doc.
+
+ - For the latest and complete information about `Java admin API`, including classes, methods, descriptions, and more, see [Java admin API doc](/api/admin/).
+
+:::
+
+**Pulsar Functions** are lightweight compute processes that
+
+* consume messages from one or more Pulsar topics
+* apply a user-supplied processing logic to each message
+* publish the results of the computation to another topic
+
+Functions can be managed via the following methods.
+
+Method | Description
+---|---
+**Admin CLI** | The `functions` command of the [`pulsar-admin`](/tools/pulsar-admin/) tool.
+**REST API** |The `/admin/v3/functions` endpoint of the admin {@inject: rest:REST:/} API.
+**Java Admin API**| The `functions` method of the `PulsarAdmin` object in the [Java API](client-libraries-java.md).
+
+## Function resources
+
+You can perform the following operations on functions.
+
+### Create a function
+
+You can create a Pulsar function in cluster mode (deploy it on a Pulsar cluster) using Admin CLI, REST API or Java Admin API.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="Admin CLI"
+ values={[{"label":"Admin CLI","value":"Admin CLI"},{"label":"REST API","value":"REST API"},{"label":"Java Admin API","value":"Java Admin API"}]}>
+<TabItem value="Admin CLI">
+
+Use the [`create`](/tools/pulsar-admin/) subcommand.
+
+**Example**
+
+```shell
+pulsar-admin functions create \
+ --tenant public \
+ --namespace default \
+ --name (the name of Pulsar Functions) \
+ --inputs test-input-topic \
+ --output persistent://public/default/test-output-topic \
+ --classname org.apache.pulsar.functions.api.examples.ExclamationFunction \
+ --jar /examples/api-examples.jar
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v3/functions/:tenant/:namespace/:functionName|operation/registerFunction?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+```java
+FunctionConfig functionConfig = new FunctionConfig();
+functionConfig.setTenant(tenant);
+functionConfig.setNamespace(namespace);
+functionConfig.setName(functionName);
+functionConfig.setRuntime(FunctionConfig.Runtime.JAVA);
+functionConfig.setParallelism(1);
+functionConfig.setClassName("org.apache.pulsar.functions.api.examples.ExclamationFunction");
+functionConfig.setProcessingGuarantees(FunctionConfig.ProcessingGuarantees.ATLEAST_ONCE);
+functionConfig.setTopicsPattern(sourceTopicPattern);
+functionConfig.setSubName(subscriptionName);
+functionConfig.setAutoAck(true);
+functionConfig.setOutput(sinkTopic);
+admin.functions().createFunction(functionConfig, fileName);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Update a function
+
+You can update a Pulsar function that has been deployed to a Pulsar cluster using Admin CLI, REST API or Java Admin API.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="Admin CLI"
+ values={[{"label":"Admin CLI","value":"Admin CLI"},{"label":"REST API","value":"REST API"},{"label":"Java Admin API","value":"Java Admin API"}]}>
+<TabItem value="Admin CLI">
+
+Use the [`update`](/tools/pulsar-admin/) subcommand.
+
+**Example**
+
+```shell
+pulsar-admin functions update \
+ --tenant public \
+ --namespace default \
+ --name (the name of Pulsar Functions) \
+ --output persistent://public/default/update-output-topic \
+ # other options
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|PUT|/admin/v3/functions/:tenant/:namespace/:functionName|operation/updateFunction?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+```java
+FunctionConfig functionConfig = new FunctionConfig();
+functionConfig.setTenant(tenant);
+functionConfig.setNamespace(namespace);
+functionConfig.setName(functionName);
+functionConfig.setRuntime(FunctionConfig.Runtime.JAVA);
+functionConfig.setParallelism(1);
+functionConfig.setClassName("org.apache.pulsar.functions.api.examples.ExclamationFunction");
+UpdateOptions updateOptions = new UpdateOptions();
+updateOptions.setUpdateAuthData(updateAuthData);
+admin.functions().updateFunction(functionConfig, userCodeFile, updateOptions);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Start an instance of a function
+
+You can start a stopped function instance with `instance-id` using Admin CLI, REST API or Java Admin API.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="Admin CLI"
+ values={[{"label":"Admin CLI","value":"Admin CLI"},{"label":"REST API","value":"REST API"},{"label":"Java Admin API","value":"Java Admin API"}]}>
+<TabItem value="Admin CLI">
+
+Use the [`start`](/tools/pulsar-admin/) subcommand.
+
+```shell
+pulsar-admin functions start \
+ --tenant public \
+ --namespace default \
+ --name (the name of Pulsar Functions) \
+ --instance-id 1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v3/functions/:tenant/:namespace/:functionName/:instanceId/start|operation/startFunction?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+```java
+admin.functions().startFunction(tenant, namespace, functionName, Integer.parseInt(instanceId));
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Start all instances of a function
+
+You can start all stopped function instances using Admin CLI, REST API or Java Admin API.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="Admin CLI"
+ values={[{"label":"Admin CLI","value":"Admin CLI"},{"label":"REST API","value":"REST API"},{"label":"Java Admin API","value":"Java Admin API"}]}>
+<TabItem value="Admin CLI">
+
+Use the [`start`](/tools/pulsar-admin/) subcommand.
+
+**Example**
+
+```shell
+pulsar-admin functions start \
+ --tenant public \
+ --namespace default \
+ --name (the name of Pulsar Functions) \
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v3/functions/:tenant/:namespace/:functionName/start|operation/startFunction?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+```java
+admin.functions().startFunction(tenant, namespace, functionName);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Stop an instance of a function
+
+You can stop a function instance with `instance-id` using Admin CLI, REST API or Java Admin API.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="Admin CLI"
+ values={[{"label":"Admin CLI","value":"Admin CLI"},{"label":"REST API","value":"REST API"},{"label":"Java Admin API","value":"Java Admin API"}]}>
+<TabItem value="Admin CLI">
+
+Use the [`stop`](/tools/pulsar-admin/) subcommand.
+
+**Example**
+
+```shell
+pulsar-admin functions stop \
+ --tenant public \
+ --namespace default \
+ --name (the name of Pulsar Functions) \
+ --instance-id 1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v3/functions/:tenant/:namespace/:functionName/:instanceId/stop|operation/stopFunction?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+```java
+admin.functions().stopFunction(tenant, namespace, functionName, Integer.parseInt(instanceId));
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Stop all instances of a function
+
+You can stop all function instances using Admin CLI, REST API or Java Admin API.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="Admin CLI"
+ values={[{"label":"Admin CLI","value":"Admin CLI"},{"label":"REST API","value":"REST API"},{"label":"Java Admin API","value":"Java Admin API"}]}>
+<TabItem value="Admin CLI">
+
+Use the [`stop`](/tools/pulsar-admin/) subcommand.
+
+**Example**
+
+```shell
+pulsar-admin functions stop \
+ --tenant public \
+ --namespace default \
+ --name (the name of Pulsar Functions)
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v3/functions/:tenant/:namespace/:functionName/stop|operation/stopFunction?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+```java
+admin.functions().stopFunction(tenant, namespace, functionName);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Restart an instance of a function
+
+Restart a function instance with `instance-id` using Admin CLI, REST API or Java Admin API.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="Admin CLI"
+ values={[{"label":"Admin CLI","value":"Admin CLI"},{"label":"REST API","value":"REST API"},{"label":"Java Admin API","value":"Java Admin API"}]}>
+<TabItem value="Admin CLI">
+
+Use the [`restart`](/tools/pulsar-admin/) subcommand.
+
+**Example**
+
+```shell
+pulsar-admin functions restart \
+ --tenant public \
+ --namespace default \
+ --name (the name of Pulsar Functions) \
+ --instance-id 1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v3/functions/:tenant/:namespace/:functionName/:instanceId/restart|operation/restartFunction?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+```java
+admin.functions().restartFunction(tenant, namespace, functionName, Integer.parseInt(instanceId));
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Restart all instances of a function
+
+You can restart all function instances using Admin CLI, REST API or Java admin API.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="Admin CLI"
+ values={[{"label":"Admin CLI","value":"Admin CLI"},{"label":"REST API","value":"REST API"},{"label":"Java Admin API","value":"Java Admin API"}]}>
+<TabItem value="Admin CLI">
+
+Use the [`restart`](/tools/pulsar-admin/) subcommand.
+
+**Example**
+
+```shell
+pulsar-admin functions restart \
+ --tenant public \
+ --namespace default \
+ --name (the name of Pulsar Functions)
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v3/functions/:tenant/:namespace/:functionName/restart|operation/restartFunction?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+```java
+admin.functions().restartFunction(tenant, namespace, functionName);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### List all functions
+
+You can list all Pulsar functions running under a specific tenant and namespace using Admin CLI, REST API or Java Admin API.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="Admin CLI"
+ values={[{"label":"Admin CLI","value":"Admin CLI"},{"label":"REST API","value":"REST API"},{"label":"Java Admin API","value":"Java Admin API"}]}>
+<TabItem value="Admin CLI">
+
+Use the [`list`](/tools/pulsar-admin/) subcommand.
+
+**Example**
+
+```shell
+pulsar-admin functions list \
+ --tenant public \
+ --namespace default
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v3/functions/:tenant/:namespace|operation/listFunctions?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+```java
+admin.functions().getFunctions(tenant, namespace);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Delete a function
+
+You can delete a Pulsar function that is running on a Pulsar cluster using Admin CLI, REST API or Java Admin API.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="Admin CLI"
+ values={[{"label":"Admin CLI","value":"Admin CLI"},{"label":"REST API","value":"REST API"},{"label":"Java Admin API","value":"Java Admin API"}]}>
+<TabItem value="Admin CLI">
+
+Use the [`delete`](/tools/pulsar-admin/) subcommand.
+
+**Example**
+
+```shell
+pulsar-admin functions delete \
+ --tenant public \
+ --namespace default \
+ --name (the name of Pulsar Functions)
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|DELETE|/admin/v3/functions/:tenant/:namespace/:functionName|operation/deregisterFunction?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+```java
+admin.functions().deleteFunction(tenant, namespace, functionName);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Get info about a function
+
+You can get information about a Pulsar function currently running in cluster mode using Admin CLI, REST API or Java Admin API.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="Admin CLI"
+ values={[{"label":"Admin CLI","value":"Admin CLI"},{"label":"REST API","value":"REST API"},{"label":"Java Admin API","value":"Java Admin API"}]}>
+<TabItem value="Admin CLI">
+
+Use the [`get`](/tools/pulsar-admin/) subcommand.
+
+**Example**
+
+```shell
+pulsar-admin functions get \
+ --tenant public \
+ --namespace default \
+ --name (the name of Pulsar Functions)
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v3/functions/:tenant/:namespace/:functionName|operation/getFunctionInfo?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+```java
+admin.functions().getFunction(tenant, namespace, functionName);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Get status of an instance of a function
+
+You can get the current status of a Pulsar function instance with `instance-id` using Admin CLI, REST API or Java Admin API.
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="Admin CLI"
+ values={[{"label":"Admin CLI","value":"Admin CLI"},{"label":"REST API","value":"REST API"},{"label":"Java Admin API","value":"Java Admin API"}]}>
+<TabItem value="Admin CLI">
+
+Use the [`status`](/tools/pulsar-admin/) subcommand.
+
+**Example**
+
+```shell
+pulsar-admin functions status \
+ --tenant public \
+ --namespace default \
+ --name (the name of Pulsar Functions) \
+ --instance-id 1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v3/functions/:tenant/:namespace/:functionName/:instanceId/status|operation/getFunctionInstanceStatus?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+```java
+admin.functions().getFunctionStatus(tenant, namespace, functionName, Integer.parseInt(instanceId));
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Get status of all instances of a function
+
+You can get the current status of a Pulsar function instance using Admin CLI, REST API or Java Admin API.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="Admin CLI"
+ values={[{"label":"Admin CLI","value":"Admin CLI"},{"label":"REST API","value":"REST API"},{"label":"Java Admin API","value":"Java Admin API"}]}>
+<TabItem value="Admin CLI">
+
+Use the [`status`](/tools/pulsar-admin/) subcommand.
+
+**Example**
+
+```shell
+pulsar-admin functions status \
+ --tenant public \
+ --namespace default \
+ --name (the name of Pulsar Functions)
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v3/functions/:tenant/:namespace/:functionName/status|operation/getFunctionStatus?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+```java
+admin.functions().getFunctionStatus(tenant, namespace, functionName);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Get stats of an instance of a function
+
+You can get the current stats of a Pulsar Function instance with `instance-id` using Admin CLI, REST API or Java admin API.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="Admin CLI"
+ values={[{"label":"Admin CLI","value":"Admin CLI"},{"label":"REST API","value":"REST API"},{"label":"Java Admin API","value":"Java Admin API"}]}>
+<TabItem value="Admin CLI">
+
+Use the [`stats`](/tools/pulsar-admin/) subcommand.
+
+**Example**
+
+```shell
+pulsar-admin functions stats \
+ --tenant public \
+ --namespace default \
+ --name (the name of Pulsar Functions) \
+ --instance-id 1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v3/functions/:tenant/:namespace/:functionName/:instanceId/stats|operation/getFunctionInstanceStats?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+```java
+admin.functions().getFunctionStats(tenant, namespace, functionName, Integer.parseInt(instanceId));
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Get stats of all instances of a function
+
+You can get the current stats of a Pulsar function using Admin CLI, REST API or Java admin API.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="Admin CLI"
+ values={[{"label":"Admin CLI","value":"Admin CLI"},{"label":"REST API","value":"REST API"},{"label":"Java Admin API","value":"Java Admin API"}]}>
+<TabItem value="Admin CLI">
+
+Use the [`stats`](/tools/pulsar-admin/) subcommand.
+
+**Example**
+
+```shell
+pulsar-admin functions stats \
+ --tenant public \
+ --namespace default \
+ --name (the name of Pulsar Functions)
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v3/functions/:tenant/:namespace/:functionName/stats|operation/getFunctionStats?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+```java
+admin.functions().getFunctionStats(tenant, namespace, functionName);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Trigger a function
+
+You can trigger a specified Pulsar function with a supplied value using Admin CLI, REST API or Java admin API.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="Admin CLI"
+ values={[{"label":"Admin CLI","value":"Admin CLI"},{"label":"REST API","value":"REST API"},{"label":"Java Admin API","value":"Java Admin API"}]}>
+<TabItem value="Admin CLI">
+
+Use the [`trigger`](/tools/pulsar-admin/) subcommand.
+
+**Example**
+
+```shell
+pulsar-admin functions trigger \
+ --tenant public \
+ --namespace default \
+ --name (the name of Pulsar Functions) \
+ --topic (the name of input topic) \
+ --trigger-value \"hello pulsar\"
+ # or --trigger-file (the path of trigger file)
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v3/functions/:tenant/:namespace/:functionName/trigger|operation/triggerFunction?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+```java
+admin.functions().triggerFunction(tenant, namespace, functionName, topic, triggerValue, triggerFile);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Put state associated with a function
+
+You can put the state associated with a Pulsar function using Admin CLI, REST API or Java admin API.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="Admin CLI"
+ values={[{"label":"Admin CLI","value":"Admin CLI"},{"label":"REST API","value":"REST API"},{"label":"Java Admin API","value":"Java Admin API"}]}>
+<TabItem value="Admin CLI">
+
+Use the [`putstate`](/tools/pulsar-admin/) subcommand.
+
+**Example**
+
+```shell
+pulsar-admin functions putstate \
+ --tenant public \
+ --namespace default \
+ --name (the name of Pulsar Functions) \
+ --state "{\"key\":\"pulsar\", \"stringValue\":\"hello pulsar\"}"
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v3/functions/:tenant/:namespace/:functionName/state/:key|operation/putFunctionState?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+```java
+TypeReference<FunctionState> typeRef = new TypeReference<FunctionState>() {};
+FunctionState stateRepr = ObjectMapperFactory.getThreadLocal().readValue(state, typeRef);
+admin.functions().putFunctionState(tenant, namespace, functionName, stateRepr);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Fetch state associated with a function
+
+You can fetch the current state associated with a Pulsar function using Admin CLI, REST API or Java admin API.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="Admin CLI"
+ values={[{"label":"Admin CLI","value":"Admin CLI"},{"label":"REST API","value":"REST API"},{"label":"Java Admin API","value":"Java Admin API"}]}>
+<TabItem value="Admin CLI">
+
+Use the [`querystate`](/tools/pulsar-admin/) subcommand.
+
+**Example**
+
+```shell
+pulsar-admin functions querystate \
+ --tenant public \
+ --namespace default \
+ --name (the name of Pulsar Functions) \
+ --key (the key of state)
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v3/functions/:tenant/:namespace/:functionName/state/:key|operation/getFunctionState?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+```java
+admin.functions().getFunctionState(tenant, namespace, functionName, key);
+```
+
+</TabItem>
+
+</Tabs>
+````
\ No newline at end of file
diff --git a/versioned_docs/version-2.11.0/admin-api-namespaces.md b/versioned_docs/version-2.11.0/admin-api-namespaces.md
new file mode 100644
index 00000000000..dc7b3f0c5a8
--- /dev/null
+++ b/versioned_docs/version-2.11.0/admin-api-namespaces.md
@@ -0,0 +1,1253 @@
+---
+id: admin-api-namespaces
+title: Managing Namespaces
+sidebar_label: "Namespaces"
+---
+
+````mdx-code-block
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+````
+
+
+:::tip
+
+ This page only shows **some frequently used operations**.
+
+ - For the latest and complete information about `Pulsar admin`, including commands, flags, descriptions, and more information, see [Pulsar admin doc](/tools/pulsar-admin/).
+
+ - For the latest and complete information about `REST API`, including parameters, responses, samples, and more, see {@inject: rest:REST:/} API doc.
+
+ - For the latest and complete information about `Java admin API`, including classes, methods, descriptions, and more, see [Java admin API doc](/api/admin/).
+
+:::
+
+Pulsar [namespaces](reference-terminology.md#namespace) are logical groupings of [topics](reference-terminology.md#topic).
+
+Namespaces can be managed via:
+
+* The `namespaces` command of the [`pulsar-admin`](/tools/pulsar-admin/) tool
+* The `/admin/v2/namespaces` endpoint of the admin {@inject: rest:REST:/} API
+* The `namespaces` method of the `PulsarAdmin` object in the [Java API](client-libraries-java.md)
+
+## Namespaces resources
+
+### Create namespaces
+
+You can create new namespaces under a given [tenant](reference-terminology.md#tenant).
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+Use the [`create`](/tools/pulsar-admin/) subcommand and specify the namespace by name:
+
+```shell
+pulsar-admin namespaces create test-tenant/test-namespace
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|PUT|/admin/v2/namespaces/:tenant/:namespace|operation/createNamespace?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.namespaces().createNamespace(namespace);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Get policies
+
+You can fetch the current policies associated with a namespace at any time.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+Use the [`policies`](/tools/pulsar-admin/) subcommand and specify the namespace:
+
+```shell
+pulsar-admin namespaces policies test-tenant/test-namespace
+```
+
+Example output:
+
+```json
+{
+ "auth_policies": {
+ "namespace_auth": {},
+ "destination_auth": {}
+ },
+ "replication_clusters": [],
+ "bundles_activated": true,
+ "bundles": {
+ "boundaries": [
+ "0x00000000",
+ "0xffffffff"
+ ],
+ "numBundles": 1
+ },
+ "backlog_quota_map": {},
+ "persistence": null,
+ "latency_stats_sample_rate": {},
+ "message_ttl_in_seconds": 0,
+ "retention_policies": null,
+ "deleted": false
+}
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/namespaces/:tenant/:namespace|operation/getPolicies?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.namespaces().getPolicies(namespace);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### List namespaces
+
+You can list all namespaces within a given Pulsar [tenant](reference-terminology.md#tenant).
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+Use the [`list`](/tools/pulsar-admin/) subcommand and specify the tenant:
+
+```shell
+pulsar-admin namespaces list test-tenant
+```
+
+Example output:
+
+```
+test-tenant/namespace1
+test-tenant/namespace2
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/namespaces/:tenant|operation/getTenantNamespaces?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.namespaces().getNamespaces(tenant);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Delete namespaces
+
+You can delete existing namespaces from a tenant.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+Use the [`delete`](/tools/pulsar-admin/) subcommand and specify the namespace:
+
+```shell
+pulsar-admin namespaces delete test-tenant/namespace1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|DELETE|/admin/v2/namespaces/:tenant/:namespace|operation/deleteNamespace?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.namespaces().deleteNamespace(namespace);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Configure replication clusters
+
+#### Set replication cluster
+
+You can set replication clusters for a namespace to enable Pulsar to internally replicate the published messages from one colocation facility to another.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin namespaces set-clusters test-tenant/namespace1 --clusters cl1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v2/namespaces/:tenant/:namespace/replication|operation/setNamespaceReplicationClusters?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.namespaces().setNamespaceReplicationClusters(namespace, clusters);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+#### Get replication cluster
+
+You can get the list of replication clusters for a given namespace.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin namespaces get-clusters test-tenant/cluster1/namespace1
+```
+
+Example output:
+
+```
+cluster2
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/namespaces/:tenant/:namespace/replication|operation/getNamespaceReplicationClusters?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.namespaces().getNamespaceReplicationClusters(namespace)
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Configure backlog quota policies
+
+#### Set backlog quota policies
+
+Backlog quota helps the broker to restrict bandwidth/storage of a namespace once it reaches a certain threshold limit. Admin can set the limit and take the corresponding action after the limit is reached.
+
+ 1. producer_request_hold: the producer holds the message and retries until client configuration `sendTimeoutMs` is exceeded
+
+ 2. producer_exception: the producer throws an exception when trying to send a message
+
+ 3. consumer_backlog_eviction: broker starts discarding backlog messages
+
+Backlog quota restriction can be taken care of by defining the restriction of backlog-quota-type: destination_storage.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin namespaces set-backlog-quota --limit 10G \
+ --limitTime 36000 \
+ --policy producer_request_hold \
+ test-tenant/namespace1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v2/namespaces/:tenant/:namespace/backlogQuota|operation/setBacklogQuota?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.namespaces().setBacklogQuota(namespace, new BacklogQuota(limit, limitTime, policy))
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+#### Get backlog quota policies
+
+You can get a configured backlog quota for a given namespace.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin namespaces get-backlog-quotas test-tenant/namespace1
+```
+
+Example output:
+
+```
+destination_storage BacklogQuotaImpl(limit=10737418240, limitSize=10737418240, limitTime=36000, policy=producer_request_hold)
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/namespaces/:tenant/:namespace/backlogQuotaMap|operation/getBacklogQuotaMap?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.namespaces().getBacklogQuotaMap(namespace);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+#### Remove backlog quota policies
+
+You can remove backlog quota policies for a given namespace.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin namespaces remove-backlog-quota test-tenant/namespace1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|DELETE|/admin/v2/namespaces/:tenant/:namespace/backlogQuota|operation/removeBacklogQuota?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.namespaces().removeBacklogQuota(namespace, backlogQuotaType)
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Configure persistence policies
+
+#### Set persistence policies
+
+Persistence policies allow users to configure persistency-level for all topic messages under a given namespace.
+
+ - Bookkeeper-ack-quorum: Number of acks (guaranteed copies) to wait for each entry, default: 0
+
+ - Bookkeeper-ensemble: Number of bookies to use for a topic, default: 0
+
+ - Bookkeeper-write-quorum: How many writes to make of each entry, default: 0
+
+ - Ml-mark-delete-max-rate: Throttling rate of mark-delete operation (0 means no throttle), default: 0.0
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin namespaces set-persistence \
+ --bookkeeper-ack-quorum 2 --bookkeeper-ensemble 3 \
+ --bookkeeper-write-quorum 2 --ml-mark-delete-max-rate 0 \
+ test-tenant/namespace1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v2/namespaces/:tenant/:namespace/persistence|operation/setPersistence?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.namespaces().setPersistence(namespace,new PersistencePolicies(bookkeeperEnsemble, bookkeeperWriteQuorum,bookkeeperAckQuorum,managedLedgerMaxMarkDeleteRate))
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+#### Get persistence policies
+
+You can get the configured persistence policies of a given namespace.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin namespaces get-persistence test-tenant/namespace1
+```
+
+Example output:
+
+```json
+{
+ "bookkeeperEnsemble": 3,
+ "bookkeeperWriteQuorum": 2,
+ "bookkeeperAckQuorum": 2,
+ "managedLedgerMaxMarkDeleteRate": 0
+}
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/namespaces/:tenant/:namespace/persistence|operation/getPersistence?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.namespaces().getPersistence(namespace)
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Configure namespace bundles
+
+#### Unload namespace bundles
+
+A namespace bundle is a virtual group of topics that belong to the same namespace. If the broker gets overloaded with the number of bundles, this command can help unload a bundle from that broker, so it can be served by some other less-loaded brokers. The namespace bundle ID ranges from 0x00000000 to 0xffffffff.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin namespaces unload --bundle 0x00000000_0xffffffff test-tenant/namespace1
+pulsar-admin namespaces unload --bundle 0x00000000_0xffffffff test-tenant/namespace1
+pulsar-admin namespaces unload --bundle 0x00000000_0xffffffff --destinationBroker broker1.use.org.com:8080 test-tenant/namespace1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|PUT|/admin/v2/namespaces/:tenant/:namespace/:bundle/unload|operation/unloadNamespaceBundle?version=@pulsar:version_number@&destinationBroker=broker1.use.org.com:8080}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.namespaces().unloadNamespaceBundle(namespace, bundle)
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+#### Split namespace bundles
+
+One namespace bundle can contain multiple topics but can be served by only one broker. If a single bundle is creating an excessive load on a broker, an admin can split the bundle using the command below, permitting one or more of the new bundles to be unloaded, thus balancing the load across the brokers.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin namespaces split-bundle --bundle 0x00000000_0xffffffff test-tenant/namespace1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|PUT|/admin/v2/namespaces/:tenant/:namespace/:bundle/split|operation/splitNamespaceBundle?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.namespaces().splitNamespaceBundle(namespace, bundle)
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Configure message TTL
+
+#### Set message-ttl
+
+You can configure the time to live (in seconds) duration for messages. In the example below, the message-ttl is set as 100s.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin namespaces set-message-ttl --messageTTL 100 test-tenant/namespace1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v2/namespaces/:tenant/:namespace/messageTTL|operation/setNamespaceMessageTTL?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.namespaces().setNamespaceMessageTTL(namespace, messageTTL)
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+#### Get message-ttl
+
+When the message-ttl for a namespace is set, you can use the command below to get the configured value. This example comtinues the example of the command `set message-ttl`, so the returned value is 100(s).
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin namespaces get-message-ttl test-tenant/namespace1
+```
+Example output:
+
+```
+100
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/namespaces/:tenant/:namespace/messageTTL|operation/getNamespaceMessageTTL?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.namespaces().getNamespaceMessageTTL(namespace)
+```
+
+```
+100
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+#### Remove message-ttl
+
+Remove a message TTL of the configured namespace.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin namespaces remove-message-ttl test-tenant/namespace1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|DELETE|/admin/v2/namespaces/:tenant/:namespace/messageTTL|operation/removeNamespaceMessageTTL?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.namespaces().removeNamespaceMessageTTL(namespace)
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+
+### Clear backlog
+
+#### Clear namespace backlog
+
+It clears all message backlogs for all the topics that belong to a specific namespace. You can also clear backlogs for a specific subscription as well.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin namespaces clear-backlog --sub my-subscription test-tenant/namespace1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v2/namespaces/:tenant/:namespace/clearBacklog|operation/clearNamespaceBacklogForSubscription?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.namespaces().clearNamespaceBacklogForSubscription(namespace, subscription)
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+#### Clear bundle backlog
+
+It clears all message backlogs for all the topics that belong to a specific NamespaceBundle. You can also clear backlogs for a specific subscription as well.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin namespaces clear-backlog \
+ --bundle 0x00000000_0xffffffff \
+ --sub my-subscription \
+ test-tenant/namespace1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v2/namespaces/:tenant/:namespace/:bundle/clearBacklog|operation/clearNamespaceBundleBacklogForSubscription?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.namespaces().clearNamespaceBundleBacklogForSubscription(namespace, bundle, subscription)
+
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Configure retention
+
+#### Set retention
+
+Each namespace contains multiple topics and the retention size (storage size) of each topic should not exceed a specific threshold or it should be stored for a certain period. This command helps configure the retention size and time of topics in a given namespace.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin namespaces set-retention --size 100M --time 10m test-tenant/namespace1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v2/namespaces/:tenant/:namespace/retention|operation/setRetention?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.namespaces().setRetention(namespace, new RetentionPolicies(retentionTimeInMin, retentionSizeInMB))
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+#### Get retention
+
+It shows the retention information of a given namespace.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin namespaces get-retention test-tenant/namespace1
+```
+
+```json
+{
+ "retentionTimeInMinutes": 10,
+ "retentionSizeInMB": 100
+}
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/namespaces/:tenant/:namespace/retention|operation/getRetention?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.namespaces().getRetention(namespace)
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Configure dispatch throttling for topics
+
+#### Set dispatch throttling for topics
+
+It sets the message dispatch rate for all the topics under a given namespace. The dispatch rate can be restricted by the number of messages per X seconds (`msg-dispatch-rate`) or by the number of message-bytes per X second (`byte-dispatch-rate`). The dispatch rate is in second and it can be configured with `dispatch-rate-period`. The default value of `msg-dispatch-rate` and `byte-dispatch-rate` is -1 which
+disables the throttling.
+
+:::note
+
+- If neither `clusterDispatchRate` nor `topicDispatchRate` is configured, dispatch throttling is disabled.
+- If `topicDispatchRate` is not configured, `clusterDispatchRate` takes effect.
+- If `topicDispatchRate` is configured, `topicDispatchRate` takes effect.
+
+:::
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin namespaces set-dispatch-rate test-tenant/namespace1 \
+ --msg-dispatch-rate 1000 \
+ --byte-dispatch-rate 1048576 \
+ --dispatch-rate-period 1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v2/namespaces/:tenant/:namespace/dispatchRate|operation/setDispatchRate?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.namespaces().setDispatchRate(namespace, new DispatchRate(1000, 1048576, 1))
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+#### Get configured message-rate for topics
+
+It shows the configured message-rate for the namespace (topics under this namespace can dispatch this many messages per second)
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin namespaces get-dispatch-rate test-tenant/namespace1
+```
+
+Example output:
+
+```json
+{
+ "dispatchThrottlingRateInMsg" : 1000,
+ "dispatchThrottlingRateInByte" : 1048576,
+ "relativeToPublishRate" : false,
+ "ratePeriodInSecond" : 1
+}
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/namespaces/:tenant/:namespace/dispatchRate|operation/getDispatchRate?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.namespaces().getDispatchRate(namespace)
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Configure dispatch throttling for subscription
+
+#### Set dispatch throttling for subscription
+
+It sets the message dispatch rate for all the subscriptions of topics under a given namespace. The dispatch rate can be restricted by the number of messages per X seconds (`msg-dispatch-rate`) or by the number of message-bytes per X second (`byte-dispatch-rate`). The dispatch rate is in second and it can be configured with `dispatch-rate-period`. The default value of `msg-dispatch-rate` and `byte-dispatch-rate` is -1 which
+disables the throttling.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin namespaces set-subscription-dispatch-rate test-tenant/namespace1 \
+ --msg-dispatch-rate 1000 \
+ --byte-dispatch-rate 1048576 \
+ --dispatch-rate-period 1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v2/namespaces/:tenant/:namespace/subscriptionDispatchRate|operation/setDispatchRate?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.namespaces().setSubscriptionDispatchRate(namespace, new DispatchRate(1000, 1048576, 1))
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+#### Get configured message-rate for subscription
+
+It shows the configured message-rate for the namespace (topics under this namespace can dispatch this many messages per second).
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin namespaces get-subscription-dispatch-rate test-tenant/namespace1
+```
+
+Example output:
+
+```json
+{
+ "dispatchThrottlingRateInMsg" : 1000,
+ "dispatchThrottlingRateInByte" : 1048576,
+ "relativeToPublishRate" : false,
+ "ratePeriodInSecond" : 1
+}
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/namespaces/:tenant/:namespace/subscriptionDispatchRate|operation/getDispatchRate?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.namespaces().getSubscriptionDispatchRate(namespace)
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Configure dispatch throttling for replicators
+
+#### Set dispatch throttling for replicators
+
+It sets the message dispatch rate for all the replicators between replication clusters under a given namespace. The dispatch rate can be restricted by the number of messages per X seconds (`msg-dispatch-rate`) or by the number of message-bytes per X second (`byte-dispatch-rate`). The dispatch rate is in second and it can be configured with `dispatch-rate-period`. The default value of `msg-dispatch-rate` and `byte-dispatch-rate` is -1 which disables the throttling.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin namespaces set-replicator-dispatch-rate test-tenant/namespace1 \
+ --msg-dispatch-rate 1000 \
+ --byte-dispatch-rate 1048576 \
+ --dispatch-rate-period 1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v2/namespaces/:tenant/:namespace/replicatorDispatchRate|operation/setDispatchRate?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.namespaces().setReplicatorDispatchRate(namespace, new DispatchRate(1000, 1048576, 1))
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+#### Get configured message-rate for replicators
+
+It shows the configured message-rate for the namespace (topics under this namespace can dispatch this many messages per second)
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin namespaces get-replicator-dispatch-rate test-tenant/namespace1
+```
+
+```json
+{
+ "dispatchThrottlingRatePerTopicInMsg" : 1000,
+ "dispatchThrottlingRatePerTopicInByte" : 1048576,
+ "ratePeriodInSecond" : 1
+}
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/namespaces/:tenant/:namespace/replicatorDispatchRate|operation/getDispatchRate?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.namespaces().getReplicatorDispatchRate(namespace)
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Configure deduplication snapshot interval
+
+#### Get deduplication snapshot interval
+
+It shows the configured `deduplicationSnapshotInterval` for a namespace (Each topic under the namespace will take a deduplication snapshot according to this interval)
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin namespaces get-deduplication-snapshot-interval test-tenant/namespace1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/namespaces/:tenant/:namespace/deduplicationSnapshotInterval|operation/getDeduplicationSnapshotInterval?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.namespaces().getDeduplicationSnapshotInterval(namespace)
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+#### Set deduplication snapshot interval
+
+Set the configured `deduplicationSnapshotInterval` for a namespace. Each topic under the namespace will take a deduplication snapshot according to this interval. `brokerDeduplicationEnabled` must be set to `true` for this property to take effect.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin namespaces set-deduplication-snapshot-interval test-tenant/namespace1 --interval 1000
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v2/namespaces/:tenant/:namespace/deduplicationSnapshotInterval|operation/setDeduplicationSnapshotInterval?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.namespaces().setDeduplicationSnapshotInterval(namespace, 1000)
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+#### Remove deduplication snapshot interval
+
+Remove configured `deduplicationSnapshotInterval` of a namespace (Each topic under the namespace will take a deduplication snapshot according to this interval).
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin namespaces remove-deduplication-snapshot-interval test-tenant/namespace1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|DELETE|/admin/v2/namespaces/:tenant/:namespace/deduplicationSnapshotInterval|operation/deleteDeduplicationSnapshotInterval?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.namespaces().removeDeduplicationSnapshotInterval(namespace)
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Namespace isolation
+
+You can use the [Pulsar isolation policy](administration-isolation.md) to allocate resources (broker and bookie) for a namespace.
+
+### Unload namespaces from a broker
+
+You can unload a namespace, or a [namespace bundle](reference-terminology.md#namespace-bundle), from the Pulsar [broker](reference-terminology.md#broker) that is currently responsible for it.
+
+#### pulsar-admin
+
+Use the [`unload`](/tools/pulsar-admin/) subcommand of the [`namespaces`](/tools/pulsar-admin/) command.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin namespaces unload my-tenant/my-ns
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|PUT|/admin/v2/namespaces/:tenant/:namespace/unload|operation/unloadNamespace?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.namespaces().unload(namespace)
+```
+
+</TabItem>
+
+</Tabs>
+````
+### Configure entry filters policy
+
+#### Set entry filters policy
+
+Entry filter helps with filtering message on server side.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```
+pulsar-admin namespaces set-entry-filters \
+ --desc "The description of the entry filter to be used for user help." \
+ --entry-filters-name "The class name for the entry filter." \
+ --entry-filters-dir "The directory for all the entry filter implementations." \
+ test-tenant/namespace1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v2/namespaces/:tenant/:namespace/entryFilters|operation/setEntryFilters?
+version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.namespaces().setEntryFilters(namespace, new EntryFilters("desc", "classes name", "class files localtion"))
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+#### Get entry filters policies
+
+You can get a configured entry filter for a given namespace.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin namespaces get-entry-filters test-tenant/namespace1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/namespaces/:tenant/:namespace/entryFilters|operation/getEntryFilters?
+version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.namespaces().getEntryFilters(namespace);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+#### Remove entry filters policies
+
+You can remove entry filters policies for a given namespace.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin namespaces remove-entry-filters test-tenant/namespace1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|DELETE|/admin/v2/namespaces/:tenant/:namespace/entryFilters|operation/removeEntryFilters?
+version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.namespaces().removeEntryFilters(namespace)
+```
+
+</TabItem>
+
+</Tabs>
+````
diff --git a/versioned_docs/version-2.11.0/admin-api-non-partitioned-topics.md b/versioned_docs/version-2.11.0/admin-api-non-partitioned-topics.md
new file mode 100644
index 00000000000..b6fedac2422
--- /dev/null
+++ b/versioned_docs/version-2.11.0/admin-api-non-partitioned-topics.md
@@ -0,0 +1,7 @@
+---
+id: admin-api-non-partitioned-topics
+title: Managing non-partitioned topics
+sidebar_label: "Non-partitioned topics"
+---
+
+For details of the content, refer to [manage topics](admin-api-topics.md).
\ No newline at end of file
diff --git a/versioned_docs/version-2.11.0/admin-api-non-persistent-topics.md b/versioned_docs/version-2.11.0/admin-api-non-persistent-topics.md
new file mode 100644
index 00000000000..2c645e507ca
--- /dev/null
+++ b/versioned_docs/version-2.11.0/admin-api-non-persistent-topics.md
@@ -0,0 +1,7 @@
+---
+id: admin-api-non-persistent-topics
+title: Managing non-persistent topics
+sidebar_label: "Non-Persistent topics"
+---
+
+For details of the content, refer to [manage topics](admin-api-topics.md).
\ No newline at end of file
diff --git a/versioned_docs/version-2.11.0/admin-api-overview.md b/versioned_docs/version-2.11.0/admin-api-overview.md
new file mode 100644
index 00000000000..6d8756ff963
--- /dev/null
+++ b/versioned_docs/version-2.11.0/admin-api-overview.md
@@ -0,0 +1,48 @@
+---
+id: admin-api-overview
+title: Pulsar admin interfaces
+sidebar_label: "Overview"
+---
+
+````mdx-code-block
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+````
+
+Pulsar admin APIs enable you to administer clusters programmatically. For example, you can create, update, delete, and manage all the entities within Pulsar instances (such as clusters, namespaces, tenants, topics, schemas, connectors, functions, and so on), and set various policies for data, resources, and security.
+
+
+
+You can interact with the admin interface via:
+
+- The `pulsar-admin` CLI tool, which is available in the `bin` folder of your Pulsar installation:
+
+ ```shell
+ bin/pulsar-admin
+ ```
+
+ :::tip
+
+ For the latest and complete information about `Pulsar admin`, including commands, flags, descriptions, and more information, see [Pulsar admin doc](/tools/pulsar-admin/).
+
+ [Pulsar Shell](administration-pulsar-shell.md) extends `pulsar-admin` with an improved user experience for more flexibility and easier navigation between multiple clusters.
+
+ :::
+
+- HTTP calls, which are made against the admin {@inject: rest:REST:/} API provided by Pulsar brokers. For some RESTful APIs, they might be redirected to the owner brokers for serving with [`307 Temporary Redirect`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/307), hence the HTTP callers should handle `307 Temporary Redirect`. If you use `curl` commands, you should specify `-L` to handle redirections.
+
+ :::tip
+
+ For the latest and complete information about `REST API`, including parameters, responses, samples, and more, see {@inject: rest:REST:/} API doc.
+
+ :::
+
+- A Java client interface.
+
+ :::tip
+
+ For the latest and complete information about `Java admin API`, including classes, methods, descriptions, and more, see [Java admin API doc](/api/admin/).
+
+ :::
+
+> **The REST API is the admin interface**. Both the `pulsar-admin` CLI tool and the Java client use the REST API. If you implement your own admin interface client, you should use the REST API.
\ No newline at end of file
diff --git a/versioned_docs/version-2.11.0/admin-api-packages.md b/versioned_docs/version-2.11.0/admin-api-packages.md
new file mode 100644
index 00000000000..c55ffcf546b
--- /dev/null
+++ b/versioned_docs/version-2.11.0/admin-api-packages.md
@@ -0,0 +1,362 @@
+---
+id: admin-api-packages
+title: Manage packages
+sidebar_label: "Packages"
+---
+
+````mdx-code-block
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+````
+
+
+:::tip
+
+ This page only shows **some frequently used operations**.
+
+ - For the latest and complete information about `Pulsar admin`, including commands, flags, descriptions, and more, see [Pulsar admin doc](/tools/pulsar-admin/).
+
+ - For the latest and complete information about `REST API`, including parameters, responses, samples, and more, see {@inject: rest:REST:/} API doc.
+
+ - For the latest and complete information about `Java admin API`, including classes, methods, descriptions, and more, see [Java admin API doc](/api/admin/).
+
+:::
+
+Package managers or package-management systems automatically manage packages in a consistent manner. These tools simplify the installation tasks, upgrade process, and deletion operations for users. A package is a minimal unit that a package manager deals with. In Pulsar, packages are organized at the tenant-level and namespace-level to manage Pulsar Functions and Pulsar IO connectors (i.e., source and sink).
+
+## What is a package?
+
+A package is a set of elements that the user would like to reuse in later operations. In Pulsar, a package can be a group of functions, sources, and sinks. You can define a package according to your needs.
+
+The package management system in Pulsar stores the data and metadata of each package (as shown in the table below) and tracks the package versions.
+
+|Metadata|Description|
+|--|--|
+|description|The description of the package.|
+|contact|The contact information of a package. For example, an email address of the developer team.|
+|create_time|The time when the package is created.|
+|modification_time|The time when the package is lastly modified.|
+|properties|A user-defined key/value map to store other information.|
+
+## How to use a package
+
+Packages can efficiently use the same set of functions and IO connectors. For example, you can use the same function, source, and sink in multiple namespaces. The main steps are:
+
+1. Create a package in the package manager by providing the following information: type, tenant, namespace, package name, and version.
+
+ |Component|Description|
+ |-|-|
+ |type|Specify one of the supported package types: function, sink and source.|
+ |tenant|Specify the tenant where you want to create the package.|
+ |namespace|Specify the namespace where you want to create the package.|
+ |name|Specify the complete name of the package, using the format `<tenant>/<namespace>/<package name>`.|
+ |version|Specify the version of the package using the format `MajorVerion.MinorVersion` in numerals.|
+
+ The information you provide creates a URL for a package, in the format `<type>://<tenant>/<namespace>/<package name>/<version>`.
+
+2. Upload the elements to the package, i.e., the functions, sources, and sinks that you want to use across namespaces.
+
+3. Apply permissions to this package from various namespaces.
+
+Now, you can use the elements you defined in the package by calling this package from within the package manager. The package manager locates it by the URL. For example,
+
+```
+sink://public/default/mysql-sink@1.0
+function://my-tenant/my-ns/my-function@0.1
+source://my-tenant/my-ns/mysql-cdc-source@2.3
+```
+
+## Package management in Pulsar
+
+You can use the command line tools, REST API, or the Java client to manage your package resources in Pulsar. More specifically, you can use these tools to [upload](#upload-a-package), [download](#download-a-package), and [delete](#delete-a-package) a package, [get the metadata](#get-the-metadata-of-a-package) and [update the metadata](#update-the-metadata-of-a-package) of a package, [get the versions](#list-all-versions-of-a-package) of a package, and [get all packages of a specific type [...]
+
+To use package management service, ensure that the package management service has been enabled in your cluster by setting the following properties in `broker.conf`.
+
+:::note
+
+Package management service is not enabled by default.
+
+:::
+
+```properties
+enablePackagesManagement=true
+packagesManagementStorageProvider=org.apache.pulsar.packages.management.storage.bookkeeper.BookKeeperPackagesStorageProvider
+packagesReplicas=1
+packagesManagementLedgerRootPath=/ledgers
+```
+
+### Upload a package
+
+You can use the following commands to upload a package.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+bin/pulsar-admin packages upload function://public/default/example@v0.1 --path package-file --description package-description
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v3/packages/:type/:tenant/:namespace/:packageName/:version|operation/upload?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+Upload a package to the package management service synchronously.
+
+```java
+void upload(PackageMetadata metadata, String packageName, String path) throws PulsarAdminException;
+```
+
+Upload a package to the package management service asynchronously.
+
+```java
+CompletableFuture<Void> uploadAsync(PackageMetadata metadata, String packageName, String path);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Download a package
+
+You can use the following commands to download a package.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+bin/pulsar-admin packages download function://public/default/example@v0.1 --path package-file
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v3/packages/:type/:tenant/:namespace/:packageName/:version|operation/download?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+Download a package from the package management service synchronously.
+
+```java
+void download(String packageName, String path) throws PulsarAdminException;
+```
+
+Download a package from the package management service asynchronously.
+
+```java
+CompletableFuture<Void> downloadAsync(String packageName, String path);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Delete a package
+
+You can use the following commands to delete a package.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+The following command deletes a package of version 0.1.
+
+```shell
+bin/pulsar-admin packages delete functions://public/default/example@v0.1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|DELETE|/admin/v3/packages/:type/:tenant/:namespace/:packageName/:version|operation/delete?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+Delete a specified package synchronously.
+
+```java
+void delete(String packageName) throws PulsarAdminException;
+```
+
+Delete a specified package asynchronously.
+
+```java
+CompletableFuture<Void> deleteAsync(String packageName);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Get the metadata of a package
+
+You can use the following commands to get the metadata of a package.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+bin/pulsar-admin packages get-metadata function://public/default/test@v1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v3/packages/:type/:tenant/:namespace/:packageName/:version/metadata|operation/getMeta?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+Get the metadata of a package synchronously.
+
+```java
+PackageMetadata getMetadata(String packageName) throws PulsarAdminException;
+```
+
+Get the metadata of a package asynchronously.
+
+```java
+CompletableFuture<PackageMetadata> getMetadataAsync(String packageName);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Update the metadata of a package
+
+You can use the following commands to update the metadata of a package.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+bin/pulsar-admin packages update-metadata function://public/default/example@v0.1 --description update-description
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|PUT|/admin/v3/packages/:type/:tenant/:namespace/:packageName/:version/metadata|operation/updateMeta?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+Update the metadata of a package synchronously.
+
+```java
+void updateMetadata(String packageName, PackageMetadata metadata) throws PulsarAdminException;
+```
+
+Update the metadata of a package asynchronously.
+
+```java
+CompletableFuture<Void> updateMetadataAsync(String packageName, PackageMetadata metadata);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### List all versions of a package
+
+You can use the following commands to list all versions of a package.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+bin/pulsar-admin packages list-versions type://tenant/namespace/packageName
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v3/packages/:type/:tenant/:namespace/:packageName|operation/listPackageVersion?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+List all versions of a package synchronously.
+
+```java
+List<String> listPackageVersions(String packageName) throws PulsarAdminException;
+```
+
+List all versions of a package asynchronously.
+
+```java
+CompletableFuture<List<String>> listPackageVersionsAsync(String packageName);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### List all packages of a specific type under a namespace
+
+You can use the following commands to list all packages of a specific type under a namespace.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+
+<TabItem value="pulsar-admin">
+
+```shell
+bin/pulsar-admin packages list --type function public/default
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|PUT|/admin/v3/packages/:type/:tenant/:namespace|operation/listPackages?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+List all packages of a specific type under a namespace synchronously.
+
+```java
+List<String> listPackages(String type, String namespace) throws PulsarAdminException;
+```
+
+List all packages of a specific type under a namespace asynchronously.
+
+```java
+CompletableFuture<List<String>> listPackagesAsync(String type, String namespace);
+```
+
+</TabItem>
+
+</Tabs>
+````
diff --git a/versioned_docs/version-2.11.0/admin-api-partitioned-topics.md b/versioned_docs/version-2.11.0/admin-api-partitioned-topics.md
new file mode 100644
index 00000000000..da99c440302
--- /dev/null
+++ b/versioned_docs/version-2.11.0/admin-api-partitioned-topics.md
@@ -0,0 +1,7 @@
+---
+id: admin-api-partitioned-topics
+title: Managing partitioned topics
+sidebar_label: "Partitioned topics"
+---
+
+For details of the content, refer to [manage topics](admin-api-topics.md).
\ No newline at end of file
diff --git a/versioned_docs/version-2.11.0/admin-api-permissions.md b/versioned_docs/version-2.11.0/admin-api-permissions.md
new file mode 100644
index 00000000000..b25d2f1c8fc
--- /dev/null
+++ b/versioned_docs/version-2.11.0/admin-api-permissions.md
@@ -0,0 +1,176 @@
+---
+id: admin-api-permissions
+title: Managing permissions
+sidebar_label: "Permissions"
+---
+
+````mdx-code-block
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+````
+
+
+:::tip
+
+ This page only shows **some frequently used operations**.
+
+ - For the latest and complete information about `Pulsar admin`, including commands, flags, descriptions, and more, see [Pulsar admin doc](/tools/pulsar-admin/)
+
+ - For the latest and complete information about `REST API`, including parameters, responses, samples, and more, see {@inject: rest:REST:/} API doc.
+
+ - For the latest and complete information about `Java admin API`, including classes, methods, descriptions, and more, see [Java admin API doc](/api/admin/).
+
+:::
+
+Pulsar allows you to grant namespace-level or topic-level permission to users.
+
+- If you grant namespace-level permission to a user, then the user can access all the topics under the namespace.
+
+- If you grant topic-level permission to a user, then the user can access only the topic.
+
+The chapters below demonstrate how to grant namespace-level permissions to users. For how to grant topic-level permissions to users, see [manage topics](admin-api-topics.md#grant-permission).
+
+## Grant permissions
+
+You can grant permissions to specific roles for lists of operations such as `produce` and `consume`.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+Use the [`grant-permission`](/tools/pulsar-admin/) subcommand and specify a namespace, actions using the `--actions` flag, and a role using the `--role` flag:
+
+```shell
+pulsar-admin namespaces grant-permission test-tenant/namespace1 \
+ --actions produce,consume \
+ --role admin10
+```
+
+Wildcard authorization can be performed when `authorizationAllowWildcardsMatching` is set to `true` in `broker.conf`.
+
+**Example**
+
+```shell
+pulsar-admin namespaces grant-permission test-tenant/namespace1 \
+ --actions produce,consume \
+ --role 'my.role.*'
+```
+
+Then, roles `my.role.1`, `my.role.2`, `my.role.foo`, `my.role.bar`, etc. can produce and consume.
+
+```shell
+pulsar-admin namespaces grant-permission test-tenant/namespace1 \
+ --actions produce,consume \
+ --role '*.role.my'
+```
+
+Then, roles `1.role.my`, `2.role.my`, `foo.role.my`, `bar.role.my`, etc. can produce and consume.
+
+:::note
+
+A wildcard matching works at **the beginning or end of the role name only**.
+
+:::
+
+**Example**
+
+```shell
+pulsar-admin namespaces grant-permission test-tenant/namespace1 \
+ --actions produce,consume \
+ --role 'my.*.role'
+```
+
+In this case, only the role `my.*.role` has permissions.
+Roles `my.1.role`, `my.2.role`, `my.foo.role`, `my.bar.role`, etc. **cannot** produce and consume.
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v2/namespaces/:tenant/:namespace/permissions/:role|operation/grantPermissionOnNamespace?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.namespaces().grantPermissionOnNamespace(namespace, role, getAuthActions(actions));
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+## Get permissions
+
+You can see which permissions have been granted to which roles in a namespace.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+Use the [`permissions`](/tools/pulsar-admin/) subcommand and specify a namespace:
+
+```shell
+pulsar-admin namespaces permissions test-tenant/namespace1
+```
+
+Example output:
+
+```
+my.role.* [produce, consume]
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/namespaces/:tenant/:namespace/permissions|operation/getPermissions?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.namespaces().getPermissions(namespace);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+## Revoke permissions
+
+You can revoke permissions from specific roles, which means that those roles will no longer have access to the specified namespace.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+Use the [`revoke-permission`](/tools/pulsar-admin/) subcommand and specify a namespace and a role using the `--role` flag:
+
+```shell
+pulsar-admin namespaces revoke-permission test-tenant/namespace1 \
+ --role admin10
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|DELETE|/admin/v2/namespaces/:tenant/:namespace/permissions/:role|operation/revokePermissionsOnNamespace?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.namespaces().revokePermissionsOnNamespace(namespace, role);
+```
+
+</TabItem>
+
+</Tabs>
+````
\ No newline at end of file
diff --git a/versioned_docs/version-2.11.0/admin-api-persistent-topics.md b/versioned_docs/version-2.11.0/admin-api-persistent-topics.md
new file mode 100644
index 00000000000..206304005da
--- /dev/null
+++ b/versioned_docs/version-2.11.0/admin-api-persistent-topics.md
@@ -0,0 +1,7 @@
+---
+id: admin-api-persistent-topics
+title: Managing persistent topics
+sidebar_label: "Persistent topics"
+---
+
+For details of the content, refer to [manage topics](admin-api-topics.md).
\ No newline at end of file
diff --git a/versioned_docs/version-2.11.0/admin-api-schemas.md b/versioned_docs/version-2.11.0/admin-api-schemas.md
new file mode 100644
index 00000000000..77326c3a9c8
--- /dev/null
+++ b/versioned_docs/version-2.11.0/admin-api-schemas.md
@@ -0,0 +1,659 @@
+---
+id: admin-api-schemas
+title: Manage Schemas
+sidebar_label: "Schemas"
+---
+
+
+````mdx-code-block
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+````
+
+:::tip
+
+This page only shows **some frequently used operations**.
+
+- For the latest and complete information about `Pulsar admin`, including commands, flags, descriptions, and more, see [Pulsar admin doc](/tools/pulsar-admin/).
+
+- For the latest and complete information about `REST API`, including parameters, responses, samples, and more, see {@inject: rest:REST:/} API doc.
+
+- For the latest and complete information about `Java admin API`, including classes, methods, descriptions, and more, see [Java admin API doc](/api/admin/).
+
+:::
+
+## Manage schema
+
+### Upload a schema
+
+To upload (register) a new schema for a topic, you can use one of the following methods.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="Admin CLI"
+ values={[{"label":"Admin CLI","value":"Admin CLI"},{"label":"REST API","value":"REST API"},{"label":"Java Admin API","value":"Java Admin API"}]}>
+
+<TabItem value="Admin CLI">
+
+Use the `upload` subcommand.
+
+```bash
+pulsar-admin schemas upload --filename <schema-definition-file> <topic-name>
+```
+
+The `schema-definition-file` is in JSON format.
+
+```json
+{
+ "type": "<schema-type>",
+ "schema": "<an-utf8-encoded-string-of-schema-definition-data>",
+ "properties": {} // the properties associated with the schema
+}
+```
+
+The following is an example of the `schema-definition-file` for a JSON schema.
+
+**Example**
+
+```json
+{
+ "type": "JSON",
+ "schema": "{\"type\":\"record\",\"name\":\"User\",\"namespace\":\"com.foo\",\"fields\":[{\"name\":\"file1\",\"type\":[\"null\",\"string\"],\"default\":null},{\"name\":\"file2\",\"type\":[\"null\",\"string\"],\"default\":null},{\"name\":\"file3\",\"type\":[\"string\",\"null\"],\"default\":\"dfdf\"}]}",
+ "properties": {}
+}
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+Send a `POST` request to this endpoint: {@inject: endpoint|POST|/admin/v2/schemas/:tenant/:namespace/:topic/schema|operation/uploadSchema?version=@pulsar:version_number@}
+
+The post payload is in JSON format.
+
+```json
+{
+ "type": "<schema-type>",
+ "schema": "<an-utf8-encoded-string-of-schema-definition-data>",
+ "properties": {} // the properties associated with the schema
+}
+```
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+```java
+void createSchema(String topic, PostSchemaPayload schemaPayload)
+```
+
+Here is an example of `PostSchemaPayload`:
+
+```java
+PulsarAdmin admin = …;
+
+PostSchemaPayload payload = new PostSchemaPayload();
+payload.setType("INT8");
+payload.setSchema("");
+
+admin.createSchema("my-tenant/my-ns/my-topic", payload);
+```
+
+</TabItem>
+</Tabs>
+````
+
+### Get the latest schema
+
+To get the latest schema for a topic, you can use one of the following methods.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="Admin CLI"
+ values={[{"label":"Admin CLI","value":"Admin CLI"},{"label":"REST API","value":"REST API"},{"label":"Java Admin API","value":"Java Admin API"}]}>
+
+<TabItem value="Admin CLI">
+
+Use the `get` subcommand.
+
+```bash
+pulsar-admin schemas get <topic-name>
+```
+
+Example output:
+
+```json
+{
+ "version": 0,
+ "type": "String",
+ "timestamp": 0,
+ "data": "string",
+ "properties": {
+ "property1": "string",
+ "property2": "string"
+ }
+}
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+Send a `GET` request to this endpoint: {@inject: endpoint|GET|/admin/v2/schemas/:tenant/:namespace/:topic/schema|operation/getSchema?version=@pulsar:version_number@}
+
+Here is an example of a response, which is returned in JSON format.
+
+```json
+{
+ "version": "<the-version-number-of-the-schema>",
+ "type": "<the-schema-type>",
+ "timestamp": "<the-creation-timestamp-of-the-version-of-the-schema>",
+ "data": "<an-utf8-encoded-string-of-schema-definition-data>",
+ "properties": {} // the properties associated with the schema
+}
+```
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+```java
+SchemaInfo createSchema(String topic)
+```
+
+Here is an example of `SchemaInfo`:
+
+```java
+PulsarAdmin admin = …;
+
+SchemaInfo si = admin.getSchema("my-tenant/my-ns/my-topic");
+```
+
+</TabItem>
+</Tabs>
+````
+
+### Get a specific schema
+
+To get a specific version of a schema, you can use one of the following methods.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="Admin CLI"
+ values={[{"label":"Admin CLI","value":"Admin CLI"},{"label":"REST API","value":"REST API"},{"label":"Java Admin API","value":"Java Admin API"}]}>
+
+<TabItem value="Admin CLI">
+
+Use the `get` subcommand.
+
+```bash
+pulsar-admin schemas get <topic-name> --version=<version>
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+Send a `GET` request to a schema endpoint: {@inject: endpoint|GET|/admin/v2/schemas/:tenant/:namespace/:topic/schema/:version|operation/getSchema?version=@pulsar:version_number@}
+
+Here is an example of a response, which is returned in JSON format.
+
+```json
+{
+ "version": "<the-version-number-of-the-schema>",
+ "type": "<the-schema-type>",
+ "timestamp": "<the-creation-timestamp-of-the-version-of-the-schema>",
+ "data": "<an-utf8-encoded-string-of-schema-definition-data>",
+ "properties": {} // the properties associated with the schema
+}
+```
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+```java
+SchemaInfo createSchema(String topic, long version)
+```
+
+Here is an example of `SchemaInfo`:
+
+```java
+PulsarAdmin admin = …;
+
+SchemaInfo si = admin.getSchema("my-tenant/my-ns/my-topic", 1L);
+```
+
+</TabItem>
+</Tabs>
+````
+
+### Extract a schema
+
+To extract (provide) a schema via a topic, use the following method.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="Admin CLI"
+ values={[{"label":"Admin CLI","value":"Admin CLI"}]}>
+
+<TabItem value="Admin CLI">
+
+Use the `extract` subcommand.
+
+```bash
+pulsar-admin schemas extract --classname <class-name> --jar <jar-path> --type <type-name>
+```
+
+</TabItem>
+</Tabs>
+````
+
+### Delete a schema
+
+:::note
+
+In any case, the `delete` action deletes **all versions** of a schema registered for a topic.
+
+:::
+
+To delete a schema for a topic, you can use one of the following methods.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="Admin CLI"
+ values={[{"label":"Admin CLI","value":"Admin CLI"},{"label":"REST API","value":"REST API"},{"label":"Java Admin API","value":"Java Admin API"}]}>
+
+<TabItem value="Admin CLI">
+
+Use the `delete` subcommand.
+
+```bash
+pulsar-admin schemas delete <topic-name>
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+Send a `DELETE` request to a schema endpoint: {@inject: endpoint|DELETE|/admin/v2/schemas/:tenant/:namespace/:topic/schema|operation/deleteSchema?version=@pulsar:version_number@}
+
+Here is an example of a response returned in JSON format.
+
+```json
+{
+ "version": "<the-latest-version-number-of-the-schema>",
+}
+```
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+```java
+void deleteSchema(String topic)
+```
+
+Here is an example of deleting a schema.
+
+```java
+PulsarAdmin admin = …;
+
+admin.deleteSchema("my-tenant/my-ns/my-topic");
+```
+
+</TabItem>
+</Tabs>
+````
+
+## Manage schema AutoUpdate
+
+### Enable schema AutoUpdate
+
+To enable/enforce schema auto-update at the namespace level, you can use one of the following methods.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="Admin CLI"
+ values={[{"label":"Admin CLI","value":"Admin CLI"},{"label":"REST API","value":"REST API"},{"label":"Java Admin API","value":"Java Admin API"}]}>
+
+<TabItem value="Admin CLI">
+
+Use the `set-is-allow-auto-update-schema` subcommand.
+
+```bash
+bin/pulsar-admin namespaces set-is-allow-auto-update-schema --enable tenant/namespace
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+Send a `POST` request to a namespace endpoint: {@inject: endpoint|POST|/admin/v2/namespaces/:tenant/:namespace/isAllowAutoUpdateSchema|operation/isAllowAutoUpdateSchema?version=@pulsar:version_number@}
+
+The post payload is in JSON format.
+
+```json
+{
+“isAllowAutoUpdateSchema”: “true”
+}
+```
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+Here is an example to enable schema auto-update for a tenant/namespace.
+
+```java
+admin.namespaces().setIsAllowAutoUpdateSchema("my-namspace", true);
+```
+
+</TabItem>
+</Tabs>
+````
+
+### Disable schema AutoUpdate
+
+:::note
+
+When schema auto-update is disabled, you can only [register a new schema](#upload-a-schema).
+
+:::
+
+To disable schema auto-update at the **namespace** level, you can use one of the following commands.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="Admin CLI"
+ values={[{"label":"Admin CLI","value":"Admin CLI"},{"label":"REST API","value":"REST API"},{"label":"Java Admin API","value":"Java Admin API"}]}>
+
+<TabItem value="Admin CLI">
+
+Use the `set-is-allow-auto-update-schema` subcommand.
+
+```bash
+bin/pulsar-admin namespaces set-is-allow-auto-update-schema --disable tenant/namespace
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+Send a `POST` request to a namespace endpoint: {@inject: endpoint|POST|/admin/v2/namespaces/:tenant/:namespace/isAllowAutoUpdateSchema|operation/isAllowAutoUpdateSchema?version=@pulsar:version_number@}
+
+The post payload is in JSON format.
+
+```json
+{
+“isAllowAutoUpdateSchema”: “false”
+}
+```
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+Here is an example to enable schema auto-unpdate of a tenant/namespace.
+
+```java
+admin.namespaces().setIsAllowAutoUpdateSchema("my-namspace", false);
+```
+
+</TabItem>
+</Tabs>
+````
+
+## Manage schema validation enforcement
+
+### Enable schema validation enforcement
+
+To enforce schema validation enforcement at the **cluster** level, you can configure `schemaValidationEnforced` to `true` in the `conf/broker.conf` file.
+
+To enable schema validation enforcement at the **namespace** level, you can use one of the following commands.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="Admin CLI"
+ values={[{"label":"Admin CLI","value":"Admin CLI"},{"label":"REST API","value":"REST API"},{"label":"Java Admin API","value":"Java Admin API"}]}>
+
+<TabItem value="Admin CLI">
+
+Use the `set-schema-validation-enforce` subcommand.
+
+```bash
+bin/pulsar-admin namespaces set-schema-validation-enforce --enable tenant/namespace
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+Send a `POST` request to a namespace endpoint: {@inject: endpoint|POST|/admin/v2/namespaces/:tenant/:namespace/schemaValidationEnforced|operation/schemaValidationEnforced?version=@pulsar:version_number@}
+
+The post payload is in JSON format.
+
+```json
+{
+“schemaValidationEnforced”: “true”
+}
+```
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+Here is an example to enable schema validation enforcement for a tenant/namespace.
+
+```java
+admin.namespaces().setSchemaValidationEnforced("my-namspace", true);
+```
+
+</TabItem>
+</Tabs>
+````
+
+### Disable schema validation enforcement
+
+To disable schema validation enforcement at the **namespace** level, you can use one of the following commands.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="Admin CLI"
+ values={[{"label":"Admin CLI","value":"Admin CLI"},{"label":"REST API","value":"REST API"},{"label":"Java Admin API","value":"Java Admin API"}]}>
+
+<TabItem value="Admin CLI">
+
+Use the `set-schema-validation-enforce` subcommand.
+
+```bash
+bin/pulsar-admin namespaces set-schema-validation-enforce --disable tenant/namespace
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+Send a `POST` request to a namespace endpoint: {@inject: endpoint|POST|/admin/v2/namespaces/:tenant/:namespace/schemaValidationEnforced|operation/schemaValidationEnforced?version=@pulsar:version_number@}
+
+The post payload is in JSON format.
+
+```json
+{
+“schemaValidationEnforced”: “false”
+}
+```
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+Here is an example to enable schema validation enforcement for a tenant/namespace.
+
+```java
+admin.namespaces().setSchemaValidationEnforced("my-namspace", false);
+```
+
+</TabItem>
+</Tabs>
+````
+
+## Manage schema compatibility strategy
+
+The [schema compatibility check strategy](schema-understand.md#schema-compatibility-check-strategy) configured at different levels has priority: topic level > namespace level > cluster level. In other words:
+ * If you set the strategy at both topic and namespace levels, the topic-level strategy is used.
+ * If you set the strategy at both namespace and cluster levels, the namespace-level strategy is used.
+
+### Set schema compatibility strategy
+
+#### Set topic-level schema compatibility strategy
+
+To set a schema compatibility check strategy at the topic level, you can use one of the following methods.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="Admin CLI"
+ values={[{"label":"Admin CLI","value":"Admin CLI"},{"label":"REST API","value":"REST API"},{"label":"Java Admin API","value":"Java Admin API"}]}>
+
+<TabItem value="Admin CLI">
+
+Use the [`pulsar-admin topicPolicies set-schema-compatibility-strategy`](/tools/pulsar-admin/) command.
+
+```shell
+pulsar-admin topicPolicies set-schema-compatibility-strategy <strategy> <topicName>
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+Send a `PUT` request to this endpoint: {@inject: endpoint|PUT|/admin/v2/topics/:tenant/:namespace/:topic|operation/schemaCompatibilityStrategy?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+```java
+void setSchemaCompatibilityStrategy(String topic, SchemaCompatibilityStrategy strategy)
+```
+
+Here is an example of setting a schema compatibility check strategy at the topic level.
+
+```java
+PulsarAdmin admin = …;
+
+admin.topicPolicies().setSchemaCompatibilityStrategy("my-tenant/my-ns/my-topic", SchemaCompatibilityStrategy.ALWAYS_INCOMPATIBLE);
+```
+
+</TabItem>
+</Tabs>
+````
+
+#### Set namespace-level schema compatibility strategy
+
+To set schema compatibility check strategy at the namespace level, you can use one of the following methods.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="Admin CLI"
+ values={[{"label":"Admin CLI","value":"Admin CLI"},{"label":"REST API","value":"REST API"},{"label":"Java Admin API","value":"Java Admin API"}]}>
+
+<TabItem value="Admin CLI">
+
+Use the [`pulsar-admin namespaces set-schema-compatibility-strategy`](/tools/pulsar-admin/) command.
+
+```shell
+pulsar-admin namespaces set-schema-compatibility-strategy options
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+Send a `PUT` request to this endpoint: {@inject: endpoint|PUT|/admin/v2/namespaces/:tenant/:namespace|operation/schemaCompatibilityStrategy?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+Use the [`setSchemaCompatibilityStrategy`](/api/admin/) method.
+
+```java
+admin.namespaces().setSchemaCompatibilityStrategy("test", SchemaCompatibilityStrategy.FULL);
+```
+
+</TabItem>
+</Tabs>
+````
+
+#### Set cluster-level schema compatibility strategy
+
+To set schema compatibility check strategy at the **cluster** level, set `schemaCompatibilityStrategy` in the `conf/broker.conf` file.
+
+The following is an example:
+
+```conf
+schemaCompatibilityStrategy=ALWAYS_INCOMPATIBLE
+```
+
+### Get schema compatibility strategy
+
+#### Get topic-level schema compatibility strategy
+
+To get the topic-level schema compatibility check strategy, you can use one of the following methods.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="Admin CLI"
+ values={[{"label":"Admin CLI","value":"Admin CLI"},{"label":"REST API","value":"REST API"},{"label":"Java Admin API","value":"Java Admin API"}]}>
+
+<TabItem value="Admin CLI">
+
+Use the [`pulsar-admin topicPolicies get-schema-compatibility-strategy`](/tools/pulsar-admin/) command.
+
+```shell
+pulsar-admin topicPolicies get-schema-compatibility-strategy <topicName>
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+Send a `GET` request to this endpoint: {@inject: endpoint|GET|/admin/v2/topics/:tenant/:namespace/:topic|operation/schemaCompatibilityStrategy?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+```java
+SchemaCompatibilityStrategy getSchemaCompatibilityStrategy(String topic, boolean applied)
+```
+
+Here is an example of getting the topic-level schema compatibility check strategy.
+
+```java
+PulsarAdmin admin = …;
+
+// get the current applied schema compatibility strategy
+admin.topicPolicies().getSchemaCompatibilityStrategy("my-tenant/my-ns/my-topic", true);
+
+// only get the schema compatibility strategy from topic policies
+admin.topicPolicies().getSchemaCompatibilityStrategy("my-tenant/my-ns/my-topic", false);
+```
+
+</TabItem>
+</Tabs>
+````
+
+#### Get namespace-level schema compatibility strategy
+
+You can get schema compatibility check strategy at namespace level using one of the following methods.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="Admin CLI"
+ values={[{"label":"Admin CLI","value":"Admin CLI"},{"label":"REST API","value":"REST API"},{"label":"Java Admin API","value":"Java Admin API"}]}>
+
+<TabItem value="Admin CLI">
+
+Use the [`pulsar-admin namespaces get-schema-compatibility-strategy`](/tools/pulsar-admin/) command.
+
+```shell
+pulsar-admin namespaces get-schema-compatibility-strategy options
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+Send a `GET` request to this endpoint: {@inject: endpoint|GET|/admin/v2/namespaces/:tenant/:namespace|operation/schemaCompatibilityStrategy?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+Use the [`getSchemaCompatibilityStrategy`](/api/admin/) method.
+
+```java
+admin.namespaces().getSchemaCompatibilityStrategy("test", SchemaCompatibilityStrategy.FULL);
+```
+
+</TabItem>
+</Tabs>
+````
\ No newline at end of file
diff --git a/versioned_docs/version-2.11.0/admin-api-tenants.md b/versioned_docs/version-2.11.0/admin-api-tenants.md
new file mode 100644
index 00000000000..49679662f8e
--- /dev/null
+++ b/versioned_docs/version-2.11.0/admin-api-tenants.md
@@ -0,0 +1,233 @@
+---
+id: admin-api-tenants
+title: Managing Tenants
+sidebar_label: "Tenants"
+---
+
+````mdx-code-block
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+````
+
+
+:::tip
+
+ This page only shows **some frequently used operations**.
+
+ - For the latest and complete information about `Pulsar admin`, including commands, flags, descriptions, and more, see [Pulsar admin doc](/tools/pulsar-admin/)
+
+ - For the latest and complete information about `REST API`, including parameters, responses, samples, and more, see {@inject: rest:REST:/} API doc.
+
+ - For the latest and complete information about `Java admin API`, including classes, methods, descriptions, and more, see [Java admin API doc](/api/admin/).
+
+:::
+
+Tenants, like namespaces, can be managed using the [admin API](admin-api-overview.md). There are currently two configurable aspects of tenants:
+
+* Admin roles
+* Allowed clusters
+
+## Tenant resources
+
+### List
+
+You can list all of the tenants associated with an [instance](reference-terminology.md#instance).
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+Use the [`list`](/tools/pulsar-admin/) subcommand.
+
+```shell
+pulsar-admin tenants list
+```
+
+Output:
+
+```
+my-tenant-1
+my-tenant-2
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/tenants|operation/getTenants?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.tenants().getTenants();
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Create
+
+You can create a new tenant.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+Use the [`create`](/tools/pulsar-admin/) subcommand:
+
+```shell
+pulsar-admin tenants create my-tenant
+```
+
+When creating a tenant, you can optionally assign admin roles using the `-r`/`--admin-roles`
+flag, and clusters using the `-c`/`--allowed-clusters` flag. You can specify multiple values
+as a comma-separated list. Here are some examples:
+
+```shell
+pulsar-admin tenants create my-tenant \
+ --admin-roles role1,role2,role3 \
+ --allowed-clusters cluster1
+```
+
+```shell
+pulsar-admin tenants create my-tenant \
+ -r role1 \
+ -c cluster1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|PUT|/admin/v2/tenants/:tenant|operation/createTenant?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.tenants().createTenant(tenantName, tenantInfo);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Get configuration
+
+You can fetch the [configuration](reference-configuration.md) for an existing tenant at any time.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+Use the [`get`](/tools/pulsar-admin/) subcommand and specify the name of the tenant. Here's an example:
+
+```shell
+pulsar-admin tenants get my-tenant
+```
+
+```json
+{
+ "adminRoles": [
+ "admin1",
+ "admin2"
+ ],
+ "allowedClusters": [
+ "cl1",
+ "cl2"
+ ]
+}
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/tenants/:tenant|operation/getTenant?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.tenants().getTenantInfo(tenantName);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Delete
+
+Tenants can be deleted from a Pulsar [instance](reference-terminology.md#instance).
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+Use the [`delete`](/tools/pulsar-admin/) subcommand and specify the name of the tenant.
+
+```shell
+pulsar-admin tenants delete my-tenant
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|DELETE|/admin/v2/tenants/:tenant|operation/deleteTenant?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.Tenants().deleteTenant(tenantName);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Update
+
+You can update a tenant's configuration.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+Use the [`update`](/tools/pulsar-admin/) subcommand.
+
+```shell
+pulsar-admin tenants update my-tenant \
+ --admin-roles role1,role2 \
+ --allowed-clusters cluster1,cluster2
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v2/tenants/:tenant|operation/updateTenant?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.tenants().updateTenant(tenantName, tenantInfo);
+```
+
+</TabItem>
+
+</Tabs>
+````
diff --git a/versioned_docs/version-2.11.0/admin-api-topics.md b/versioned_docs/version-2.11.0/admin-api-topics.md
new file mode 100644
index 00000000000..2f71d897cba
--- /dev/null
+++ b/versioned_docs/version-2.11.0/admin-api-topics.md
@@ -0,0 +1,2058 @@
+---
+id: admin-api-topics
+title: Manage topics
+sidebar_label: "Topics"
+---
+
+````mdx-code-block
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+````
+
+
+:::tip
+
+This page only shows **some frequently used operations**.
+
+- For the latest and complete information about `Pulsar admin`, including commands, flags, descriptions, and more, see [Pulsar admin doc](/tools/pulsar-admin/)
+
+- For the latest and complete information about `REST API`, including parameters, responses, samples, and more, see {@inject: rest:REST:/} API doc.
+
+- For the latest and complete information about `Java admin API`, including classes, methods, descriptions, and more, see [Java admin API doc](/api/admin/).
+
+:::
+
+Pulsar has persistent and non-persistent topics. A persistent topic is a logical endpoint for publishing and consuming messages. The topic name structure for persistent topics is:
+
+```shell
+persistent://tenant/namespace/topic
+```
+
+Non-persistent topics are used in applications that only consume real-time published messages and do not need persistent guarantees. In this way, it reduces message-publish latency by removing overhead of persisting messages. The topic name structure for non-persistent topics is:
+
+```shell
+non-persistent://tenant/namespace/topic
+```
+
+## Manage topic resources
+Whether it is a persistent or non-persistent topic, you can obtain the topic resources through `pulsar-admin` tool, REST API and Java.
+
+:::note
+
+In REST API, `:schema` stands for persistent or non-persistent. `:tenant`, `:namespace`, `:x` are variables, replace them with the real tenant, namespace, and `x` names when using them.
+Take {@inject: endpoint|GET|/admin/v2/:schema/:tenant/:namespace|operation/getList?version=@pulsar:version_number@} as an example, to get the list of persistent topics in REST API, use `https://pulsar.apache.org/admin/v2/persistent/my-tenant/my-namespace`. To get the list of non-persistent topics in REST API, use `https://pulsar.apache.org/admin/v2/non-persistent/my-tenant/my-namespace`.
+
+:::
+
+### List of topics
+
+You can get the list of topics under a given namespace in the following ways.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics list my-tenant/my-namespace
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/:schema/:tenant/:namespace|operation/getList?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+String namespace = "my-tenant/my-namespace";
+admin.topics().getList(namespace);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Grant permission
+
+You can grant permissions on a client role to perform specific actions on a given topic in the following ways.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics grant-permission \
+ --actions produce,consume \
+ --role application1 \
+ persistent://test-tenant/ns1/tp1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v2/:schema/:tenant/:namespace/:topic/permissions/:role|operation/grantPermissionsOnTopic?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+String role = "test-role";
+Set<AuthAction> actions = Sets.newHashSet(AuthAction.produce, AuthAction.consume);
+admin.topics().grantPermission(topic, role, actions);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Get permission
+
+You can fetch permission in the following ways.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics permissions persistent://test-tenant/ns1/tp1
+```
+
+Example output:
+
+```
+application1 [consume, produce]
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/:schema/:tenant/:namespace/:topic/permissions|operation/getPermissionsOnTopic?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+admin.topics().getPermissions(topic);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Revoke permission
+
+You can revoke permissions granted on a client role in the following ways.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics revoke-permission \
+ --role application1 \
+ persistent://test-tenant/ns1/tp1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|DELETE|/admin/v2/:schema/:tenant/:namespace/:topic/permissions/:role|operation/revokePermissionsOnTopic?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+String role = "test-role";
+admin.topics().revokePermissions(topic, role);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Delete topic
+
+You can delete a topic in the following ways. You cannot delete a topic if any active subscription or producer is connected to the topic.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics delete persistent://test-tenant/ns1/tp1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|DELETE|/admin/v2/:schema/:tenant/:namespace/:topic|operation/deleteTopic?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+admin.topics().delete(topic);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Unload topic
+
+You can unload a topic in the following ways.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics unload persistent://test-tenant/ns1/tp1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|PUT|/admin/v2/:schema/:tenant/:namespace/:topic/unload|operation/unloadTopic?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+admin.topics().unload(topic);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Get stats
+
+For the detailed statistics of a topic, see [Pulsar statistics](administration-stats.md#topic-stats).
+
+The following is an example of a topic status.
+
+```json
+{
+ "msgRateIn" : 0.0,
+ "msgThroughputIn" : 0.0,
+ "msgRateOut" : 0.0,
+ "msgThroughputOut" : 0.0,
+ "bytesInCounter" : 504,
+ "msgInCounter" : 9,
+ "bytesOutCounter" : 2296,
+ "msgOutCounter" : 41,
+ "averageMsgSize" : 0.0,
+ "msgChunkPublished" : false,
+ "storageSize" : 504,
+ "backlogSize" : 0,
+ "filteredEntriesCount" : 100,
+ "earliestMsgPublishTimeInBacklogs": 0,
+ "offloadedStorageSize" : 0,
+ "publishers" : [ {
+ "accessMode" : "Shared",
+ "msgRateIn" : 0.0,
+ "msgThroughputIn" : 0.0,
+ "averageMsgSize" : 0.0,
+ "chunkedMessageRate" : 0.0,
+ "producerId" : 0,
+ "metadata" : { },
+ "address" : "/127.0.0.1:65402",
+ "connectedSince" : "2021-06-09T17:22:55.913+08:00",
+ "clientVersion" : "2.9.0-SNAPSHOT",
+ "producerName" : "standalone-1-0"
+ } ],
+ "waitingPublishers" : 0,
+ "subscriptions" : {
+ "sub-demo" : {
+ "msgRateOut" : 0.0,
+ "msgThroughputOut" : 0.0,
+ "bytesOutCounter" : 2296,
+ "msgOutCounter" : 41,
+ "msgRateRedeliver" : 0.0,
+ "chunkedMessageRate" : 0,
+ "msgBacklog" : 0,
+ "backlogSize" : 0,
+ "earliestMsgPublishTimeInBacklog": 0,
+ "msgBacklogNoDelayed" : 0,
+ "blockedSubscriptionOnUnackedMsgs" : false,
+ "msgDelayed" : 0,
+ "unackedMessages" : 0,
+ "type" : "Exclusive",
+ "activeConsumerName" : "20b81",
+ "msgRateExpired" : 0.0,
+ "totalMsgExpired" : 0,
+ "lastExpireTimestamp" : 0,
+ "lastConsumedFlowTimestamp" : 1623230565356,
+ "lastConsumedTimestamp" : 1623230583946,
+ "lastAckedTimestamp" : 1623230584033,
+ "lastMarkDeleteAdvancedTimestamp" : 1623230584033,
+ "filterProcessedMsgCount": 100,
+ "filterAcceptedMsgCount": 100,
+ "filterRejectedMsgCount": 0,
+ "filterRescheduledMsgCount": 0,
+ "consumers" : [ {
+ "msgRateOut" : 0.0,
+ "msgThroughputOut" : 0.0,
+ "bytesOutCounter" : 2296,
+ "msgOutCounter" : 41,
+ "msgRateRedeliver" : 0.0,
+ "chunkedMessageRate" : 0.0,
+ "consumerName" : "20b81",
+ "availablePermits" : 959,
+ "unackedMessages" : 0,
+ "avgMessagesPerEntry" : 314,
+ "blockedConsumerOnUnackedMsgs" : false,
+ "lastAckedTimestamp" : 1623230584033,
+ "lastConsumedTimestamp" : 1623230583946,
+ "metadata" : { },
+ "address" : "/127.0.0.1:65172",
+ "connectedSince" : "2021-06-09T17:22:45.353+08:00",
+ "clientVersion" : "2.9.0-SNAPSHOT"
+ } ],
+ "allowOutOfOrderDelivery": false,
+ "consumersAfterMarkDeletePosition" : { },
+ "nonContiguousDeletedMessagesRanges" : 0,
+ "nonContiguousDeletedMessagesRangesSerializedSize" : 0,
+ "durable" : true,
+ "replicated" : false
+ }
+ },
+ "replication" : { },
+ "deduplicationStatus" : "Disabled",
+ "nonContiguousDeletedMessagesRanges" : 0,
+ "nonContiguousDeletedMessagesRangesSerializedSize" : 0,
+ "ownerBroker" : "localhost:8080"
+}
+```
+
+To get the status of a topic, you can use the following ways.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics stats persistent://test-tenant/ns1/tp1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/:schema/:tenant/:namespace/:topic/stats|operation/getStats?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+admin.topics().getStats(topic);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Get internal stats
+
+For the detailed internal statistics inside a topic, see [Pulsar statistics](administration-stats.md#topic-internal-stats).
+
+The following is an example of the internal statistics of a topic.
+
+```json
+{
+ "entriesAddedCounter":0,
+ "numberOfEntries":0,
+ "totalSize":0,
+ "currentLedgerEntries":0,
+ "currentLedgerSize":0,
+ "lastLedgerCreatedTimestamp":"2021-01-22T21:12:14.868+08:00",
+ "lastLedgerCreationFailureTimestamp":null,
+ "waitingCursorsCount":0,
+ "pendingAddEntriesCount":0,
+ "lastConfirmedEntry":"3:-1",
+ "state":"LedgerOpened",
+ "ledgers":[
+ {
+ "ledgerId":3,
+ "entries":0,
+ "size":0,
+ "offloaded":false,
+ "metadata":null
+ }
+ ],
+ "cursors":{
+ "test":{
+ "markDeletePosition":"3:-1",
+ "readPosition":"3:-1",
+ "waitingReadOp":false,
+ "pendingReadOps":0,
+ "messagesConsumedCounter":0,
+ "cursorLedger":4,
+ "cursorLedgerLastEntry":1,
+ "individuallyDeletedMessages":"[]",
+ "lastLedgerSwitchTimestamp":"2021-01-22T21:12:14.966+08:00",
+ "state":"Open",
+ "numberOfEntriesSinceFirstNotAckedMessage":0,
+ "totalNonContiguousDeletedMessagesRange":0,
+ "properties":{
+
+ }
+ }
+ },
+ "schemaLedgers":[
+ {
+ "ledgerId":1,
+ "entries":11,
+ "size":10,
+ "offloaded":false,
+ "metadata":null
+ }
+ ],
+ "compactedLedger":{
+ "ledgerId":-1,
+ "entries":-1,
+ "size":-1,
+ "offloaded":false,
+ "metadata":null
+ }
+}
+```
+
+To get the internal status of a topic, you can use the following ways.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics stats-internal persistent://test-tenant/ns1/tp1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/:schema/:tenant/:namespace/:topic/internalStats|operation/getInternalStats?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+admin.topics().getInternalStats(topic);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Peek messages
+
+You can peek a number of messages for a specific subscription of a given topic in the following ways.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics peek-messages \
+ --count 10 --subscription my-subscription \
+ persistent://test-tenant/ns1/tp1
+```
+
+Example output:
+
+```
+Message ID: 77:2
+Publish time: 1668674963028
+Event time: 0
+ +-------------------------------------------------+
+ | 0 1 2 3 4 5 6 7 8 9 a b c d e f |
++--------+-------------------------------------------------+----------------+
+|00000000| 68 65 6c 6c 6f 2d 31 |hello-1 |
++--------+-------------------------------------------------+----------------+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/:schema/:tenant/:namespace/:topic/subscription/:subName/position/:messagePosition|operation/peekNthMessage?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+String subName = "my-subscription";
+int numMessages = 1;
+admin.topics().peekMessages(topic, subName, numMessages);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Get message by ID
+
+You can fetch the message with the given ledger ID and entry ID in the following ways.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics get-message-by-id \
+ -l 10 -e 0 persistent://public/default/my-topic
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/:schema/:tenant/:namespace/:topic/ledger/:ledgerId/entry/:entryId|operation/getMessageById?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+long ledgerId = 10;
+long entryId = 10;
+admin.topics().getMessageById(topic, ledgerId, entryId);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Examine messages
+
+You can examine a specific message on a topic by position relative to the earliest or the latest message.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics examine-messages \
+ -i latest -m 1 persistent://public/default/my-topic
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/:schema/:tenant/:namespace/:topic/examinemessage?initialPosition=:initialPosition&messagePosition=:messagePosition|operation/examineMessage?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+admin.topics().examineMessage(topic, "latest", 1);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Get message ID
+
+You can get message ID published at or just after the given datetime.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics get-message-id \
+ persistent://public/default/my-topic \
+ -d 2021-06-28T19:01:17Z
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/:schema/:tenant/:namespace/:topic/messageid/:timestamp|operation/getMessageIdByTimestamp?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+long timestamp = System.currentTimeMillis()
+admin.topics().getMessageIdByTimestamp(topic, timestamp);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+
+### Skip messages
+
+You can skip a number of messages for a specific subscription of a given topic in the following ways.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics skip \
+ --count 10 --subscription my-subscription \
+ persistent://test-tenant/ns1/tp1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v2/:schema/:tenant/:namespace/:topic/subscription/:subName/skip/:numMessages|operation/skipMessages?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+String subName = "my-subscription";
+int numMessages = 1;
+admin.topics().skipMessages(topic, subName, numMessages);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Skip all messages
+
+You can skip all the old messages for a specific subscription of a given topic.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics clear-backlog \
+ --subscription my-subscription \
+ persistent://test-tenant/ns1/tp1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v2/:schema/:tenant/:namespace/:topic/subscription/:subName/skip_all|operation/skipAllMessages?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+String subName = "my-subscription";
+admin.topics().skipAllMessages(topic, subName);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Reset cursor
+
+You can reset a subscription cursor position back to the position which is recorded X minutes before. It essentially calculates the time and position of the cursor at X minutes before and resets it at that position. You can reset the cursor in the following ways.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics reset-cursor \
+ --subscription my-subscription --time 10 \
+ persistent://test-tenant/ns1/tp1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v2/:schema/:tenant/:namespace/:topic/subscription/:subName/resetcursor/:timestamp|operation/resetCursor?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+String subName = "my-subscription";
+long timestamp = 2342343L;
+admin.topics().resetCursor(topic, subName, timestamp);
+
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Look up topic's owner broker
+
+You can locate the owner broker of the given topic in the following ways.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics lookup persistent://test-tenant/ns1/tp1
+```
+
+Example output:
+
+```
+"pulsar://broker1.org.com:4480"
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/lookup/v2/topic/:topic-domain/:tenant/:namespace/:topic|operation/lookupTopicAsync?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+admin.lookups().lookupDestination(topic);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Look up partitioned topic's owner broker
+
+You can locate the owner broker of the given partitioned topic in the following ways.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics partitioned-lookup persistent://test-tenant/ns1/my-topic
+```
+
+Example output:
+
+```
+"persistent://test-tenant/ns1/my-topic-partition-0 pulsar://localhost:6650"
+"persistent://test-tenant/ns1/my-topic-partition-1 pulsar://localhost:6650"
+"persistent://test-tenant/ns1/my-topic-partition-2 pulsar://localhost:6650"
+"persistent://test-tenant/ns1/my-topic-partition-3 pulsar://localhost:6650"
+```
+
+Lookup the partitioned topics sorted by broker URL
+
+```shell
+pulsar-admin topics partitioned-lookup \
+ persistent://test-tenant/ns1/my-topic --sort-by-broker
+```
+
+Example output:
+
+```
+pulsar://localhost:6650 [persistent://test-tenant/ns1/my-topic-partition-0, persistent://test-tenant/ns1/my-topic-partition-1, persistent://test-tenant/ns1/my-topic-partition-2, persistent://test-tenant/ns1/my-topic-partition-3]
+```
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+admin.lookups().lookupPartitionedTopic(topic);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Get bundle
+
+You can get the range of the bundle that the given topic belongs to in the following ways.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics bundle-range persistent://test-tenant/ns1/tp1
+```
+
+Example output:
+
+```
+"0x00000000_0xffffffff"
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/lookup/v2/topic/:topic_domain/:tenant/:namespace/:topic/bundle|operation/getNamespaceBundle?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+admin.lookups().getBundleRange(topic);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Get subscriptions
+
+You can check all subscription names for a given topic in the following ways.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics subscriptions persistent://test-tenant/ns1/tp1
+```
+
+Example output:
+
+```
+my-subscription
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/:schema/:tenant/:namespace/:topic/subscriptions|operation/getSubscriptions?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+admin.topics().getSubscriptions(topic);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Last Message Id
+
+You can get the last committed message ID for a persistent topic. It is available since 2.3.0 release.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics last-message-id topic-name
+```
+
+Example output:
+
+```json
+{
+ "ledgerId" : 97,
+ "entryId" : 9,
+ "partitionIndex" : -1
+}
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|Get|/admin/v2/:schema/:tenant/:namespace/:topic/lastMessageId|operation/getLastMessageId?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+admin.topics().getLastMessage(topic);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Get backlog size
+
+You can get the backlog size of a single partition topic or a non-partitioned topic with a given message ID (in bytes).
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics get-backlog-size \
+ -m 1:1 \
+ persistent://test-tenant/ns1/tp1-partition-0
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|PUT|/admin/v2/:schema/:tenant/:namespace/:topic/backlogSize|operation/getBacklogSizeByMessageId?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+MessageId messageId = MessageId.earliest;
+admin.topics().getBacklogSizeByMessageId(topic, messageId);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+
+### Configure deduplication snapshot interval
+
+#### Get deduplication snapshot interval
+
+To get the topic-level deduplication snapshot interval, use one of the following methods.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics get-deduplication-snapshot-interval my-topic
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/topics/:tenant/:namespace/:topic/deduplicationSnapshotInterval|operation/getDeduplicationSnapshotInterval?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.topics().getDeduplicationSnapshotInterval(topic)
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+#### Set deduplication snapshot interval
+
+To set the topic-level deduplication snapshot interval, use one of the following methods.
+
+> **Prerequisite** `brokerDeduplicationEnabled` must be set to `true`.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics set-deduplication-snapshot-interval my-topic -i 1000
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v2/topics/:tenant/:namespace/:topic/deduplicationSnapshotInterval|operation/setDeduplicationSnapshotInterval?version=@pulsar:version_number@}
+
+```json
+{
+ "interval": 1000
+}
+```
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.topics().setDeduplicationSnapshotInterval(topic, 1000)
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+#### Remove deduplication snapshot interval
+
+To remove the topic-level deduplication snapshot interval, use one of the following methods.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics remove-deduplication-snapshot-interval my-topic
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|DELETE|/admin/v2/topics/:tenant/:namespace/:topic/deduplicationSnapshotInterval|operation/deleteDeduplicationSnapshotInterval?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.topics().removeDeduplicationSnapshotInterval(topic)
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+
+### Configure inactive topic policies
+
+#### Get inactive topic policies
+
+To get the topic-level inactive topic policies, use one of the following methods.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics get-inactive-topic-policies my-topic
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/topics/:tenant/:namespace/:topic/inactiveTopicPolicies|operation/getInactiveTopicPolicies?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.topics().getInactiveTopicPolicies(topic)
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+#### Set inactive topic policies
+
+To set the topic-level inactive topic policies, use one of the following methods.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics set-inactive-topic-policies my-topic
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v2/topics/:tenant/:namespace/:topic/inactiveTopicPolicies|operation/setInactiveTopicPolicies?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.topics().setInactiveTopicPolicies(topic, inactiveTopicPolicies)
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+#### Remove inactive topic policies
+
+To remove the topic-level inactive topic policies, use one of the following methods.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics remove-inactive-topic-policies my-topic
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|DELETE|/admin/v2/topics/:tenant/:namespace/:topic/inactiveTopicPolicies|operation/removeInactiveTopicPolicies?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.topics().removeInactiveTopicPolicies(topic)
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+
+### Configure offload policies
+
+#### Get offload policies
+
+To get the topic-level offload policies, use one of the following methods.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics get-offload-policies my-topic
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/topics/:tenant/:namespace/:topic/offloadPolicies|operation/getOffloadPolicies?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.topics().getOffloadPolicies(topic)
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+#### Set offload policies
+
+To set the topic-level offload policies, use one of the following methods.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics set-offload-policies my-topic
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v2/topics/:tenant/:namespace/:topic/offloadPolicies|operation/setOffloadPolicies?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.topics().setOffloadPolicies(topic, offloadPolicies)
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+#### Remove offload policies
+
+To remove the topic-level offload policies, use one of the following methods.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics remove-offload-policies my-topic
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|DELETE|/admin/v2/topics/:tenant/:namespace/:topic/offloadPolicies|operation/removeOffloadPolicies?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.topics().removeOffloadPolicies(topic)
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+
+## Manage non-partitioned topics
+You can use Pulsar [admin API](admin-api-overview.md) to create, delete and check the status of non-partitioned topics.
+
+### Create
+Non-partitioned topics must be explicitly created. When creating a new non-partitioned topic, you need to provide a name for the topic.
+
+By default, 60 seconds after creation, topics are considered inactive and deleted automatically to avoid generating trash data. To disable this feature, set `brokerDeleteInactiveTopicsEnabled` to `false`. To change the frequency of checking inactive topics, set `brokerDeleteInactiveTopicsFrequencySeconds` to a specific value.
+
+For more information about the two parameters, see [here](reference-configuration.md#broker).
+
+You can create non-partitioned topics in the following ways.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+When you create non-partitioned topics with the [`create`](/tools/pulsar-admin/) command, you need to specify the topic name as an argument.
+
+```shell
+pulsar-admin topics create \
+ persistent://my-tenant/my-namespace/my-topic
+```
+
+:::note
+
+When you create a non-partitioned topic with the suffix '-partition-' followed by numeric value like 'xyz-topic-partition-x' for the topic name, if a partitioned topic with same suffix 'xyz-topic-partition-y' exists, then the numeric value(x) for the non-partitioned topic must be larger than the number of partitions(y) of the partitioned topic. Otherwise, you cannot create such a non-partitioned topic.
+
+:::
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|PUT|/admin/v2/:schema/:tenant/:namespace/:topic|operation/createNonPartitionedTopic?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+String topicName = "persistent://my-tenant/my-namespace/my-topic";
+admin.topics().createNonPartitionedTopic(topicName);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Delete
+
+You can delete non-partitioned topics in the following ways.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics delete \
+ persistent://my-tenant/my-namespace/my-topic
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|DELETE|/admin/v2/:schema/:tenant/:namespace/:topic|operation/deleteTopic?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.topics().delete(topic);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### List
+
+You can get the list of topics under a given namespace in the following ways.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics list tenant/namespace
+```
+
+Example output:
+
+```
+persistent://tenant/namespace/topic1
+persistent://tenant/namespace/topic2
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/:schema/:tenant/:namespace|operation/getList?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.topics().getList(namespace);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Stats
+
+
+You can check the current statistics of a given topic and its connected producers and consumers in the following ways.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics stats \
+ persistent://test-tenant/namespace/topic \
+ --get-precise-backlog
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/:schema/:tenant/:namespace/:topic/stats|operation/getStats?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.topics().getStats(topic, false /* is precise backlog */);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+The following is an example. For the description of topic stats, see [Pulsar statistics](administration-stats.md#topic-stats).
+
+```json
+{
+ "msgRateIn": 4641.528542257553,
+ "msgThroughputIn": 44663039.74947473,
+ "msgRateOut": 0,
+ "msgThroughputOut": 0,
+ "averageMsgSize": 1232439.816728665,
+ "storageSize": 135532389160,
+ "publishers": [
+ {
+ "msgRateIn": 57.855383881403576,
+ "msgThroughputIn": 558994.7078932219,
+ "averageMsgSize": 613135,
+ "producerId": 0,
+ "producerName": null,
+ "address": null,
+ "connectedSince": null
+ }
+ ],
+ "subscriptions": {
+ "my-topic_subscription": {
+ "msgRateOut": 0,
+ "msgThroughputOut": 0,
+ "msgBacklog": 116632,
+ "type": null,
+ "msgRateExpired": 36.98245516804671,
+ "consumers": []
+ }
+ },
+ "replication": {}
+}
+```
+
+### Internal stats
+
+You can check the detailed statistics of a topic. The following is an example. For the description of each internal topic stats, see [Pulsar statistics](administration-stats.md#topic-internal-stats).
+
+```json
+{
+ "entriesAddedCounter": 20449518,
+ "numberOfEntries": 3233,
+ "totalSize": 331482,
+ "currentLedgerEntries": 3233,
+ "currentLedgerSize": 331482,
+ "lastLedgerCreatedTimestamp": "2016-06-29 03:00:23.825",
+ "lastLedgerCreationFailureTimestamp": null,
+ "waitingCursorsCount": 1,
+ "pendingAddEntriesCount": 0,
+ "lastConfirmedEntry": "324711539:3232",
+ "state": "LedgerOpened",
+ "ledgers": [
+ {
+ "ledgerId": 324711539,
+ "entries": 0,
+ "size": 0
+ }
+ ],
+ "cursors": {
+ "my-subscription": {
+ "markDeletePosition": "324711539:3133",
+ "readPosition": "324711539:3233",
+ "waitingReadOp": true,
+ "pendingReadOps": 0,
+ "messagesConsumedCounter": 20449501,
+ "cursorLedger": 324702104,
+ "cursorLedgerLastEntry": 21,
+ "individuallyDeletedMessages": "[(324711539:3134‥324711539:3136], (324711539:3137‥324711539:3140], ]",
+ "lastLedgerSwitchTimestamp": "2016-06-29 01:30:19.313",
+ "state": "Open"
+ }
+ }
+}
+```
+
+You can get the internal stats for the partitioned topic in the following ways.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics stats-internal \
+ persistent://test-tenant/namespace/topic
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/:schema/:tenant/:namespace/:topic/internalStats|operation/getInternalStats?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.topics().getInternalStats(topic);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+## Manage partitioned topics
+You can use Pulsar [admin API](admin-api-overview.md) to create, update, delete and check the status of partitioned topics.
+
+### Create
+
+When creating a new partitioned topic, you need to provide a name and the number of partitions for the topic.
+
+:::note
+
+By default, if there are no messages 60 seconds after creation, topics are considered inactive and deleted automatically to avoid generating trash data. To disable this feature, set `brokerDeleteInactiveTopicsEnabled` to `false`. To change the frequency of checking inactive topics, set `brokerDeleteInactiveTopicsFrequencySeconds` to a specific value.
+
+:::
+
+For more information about the two parameters, see [here](reference-configuration.md#broker).
+
+You can create partitioned topics in the following ways.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+When you create partitioned topics with the [`create-partitioned-topic`](/tools/pulsar-admin/)
+command, you need to specify the topic name as an argument and the number of partitions using the `-p` or `--partitions` flag.
+
+```shell
+pulsar-admin topics create-partitioned-topic \
+ persistent://my-tenant/my-namespace/my-topic \
+ --partitions 4
+```
+
+:::note
+
+If a non-partitioned topic with the suffix '-partition-' followed by a numeric value like 'xyz-topic-partition-10', you can not create a partitioned topic with name 'xyz-topic', because the partitions of the partitioned topic could override the existing non-partitioned topic. To create such partitioned topic, you have to delete that non-partitioned topic first.
+
+:::
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|PUT|/admin/v2/:schema/:tenant/:namespace/:topic/partitions|operation/createPartitionedTopic?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+String topicName = "persistent://my-tenant/my-namespace/my-topic";
+int numPartitions = 4;
+admin.topics().createPartitionedTopic(topicName, numPartitions);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Create missed partitions
+
+When topic auto-creation is disabled, and you have a partitioned topic without any partitions, you can use the [`create-missed-partitions`](/tools/pulsar-admin/) command to create partitions for the topic.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+You can create missed partitions with the [`create-missed-partitions`](/tools/pulsar-admin/) command and specify the topic name as an argument.
+
+```shell
+pulsar-admin topics create-missed-partitions \
+ persistent://my-tenant/my-namespace/my-topic
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v2/:schema/:tenant/:namespace/:topic|operation/createMissedPartitions?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+String topicName = "persistent://my-tenant/my-namespace/my-topic";
+admin.topics().createMissedPartitions(topicName);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Get metadata
+
+Partitioned topics are associated with metadata, you can view it as a JSON object. The following metadata field is available.
+
+Field | Description
+:-----|:-------
+`partitions` | The number of partitions into which the topic is divided.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+You can check the number of partitions in a partitioned topic with the [`get-partitioned-topic-metadata`](/tools/pulsar-admin/) subcommand.
+
+```shell
+pulsar-admin topics get-partitioned-topic-metadata \
+ persistent://my-tenant/my-namespace/my-topic
+```
+
+Example output:
+
+```json
+{
+ "partitions" : 4,
+ "deleted" : false
+}
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/:schema/:tenant/:namespace/:topic/partitions|operation/getPartitionedMetadata?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+String topicName = "persistent://my-tenant/my-namespace/my-topic";
+admin.topics().getPartitionedTopicMetadata(topicName);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Update
+
+You can update the number of partitions for an existing partitioned topic *if* the topic is non-global. However, you can only add the partition number. Decrementing the number of partitions would delete the topic, which is not supported in Pulsar.
+
+Producers and consumers can find the newly created partitions automatically.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+You can update partitioned topics with the [`update-partitioned-topic`](/tools/pulsar-admin/) command.
+
+```shell
+pulsar-admin topics update-partitioned-topic \
+ persistent://my-tenant/my-namespace/my-topic \
+ --partitions 8
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v2/:schema/:tenant/:cluster/:namespace/:destination/partitions|operation/updatePartitionedTopic?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.topics().updatePartitionedTopic(topic, numPartitions);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Delete
+You can delete partitioned topics with the [`delete-partitioned-topic`](/tools/pulsar-admin/) command, REST API and Java.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics delete-partitioned-topic \
+ persistent://my-tenant/my-namespace/my-topic
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|DELETE|/admin/v2/:schema/:topic/:namespace/:destination/partitions|operation/deletePartitionedTopic?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.topics().delete(topic);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### List
+
+You can get the list of partitioned topics under a given namespace in the following ways.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics list-partitioned-topics tenant/namespace
+```
+
+Example output:
+
+```
+persistent://tenant/namespace/topic1
+persistent://tenant/namespace/topic2
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/:schema/:tenant/:namespace|operation/getPartitionedTopicList?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.topics().getPartitionedTopicList(namespace);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Stats
+
+You can check the current statistics of a given partitioned topic and its connected producers and consumers in the following ways.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics partitioned-stats \
+ persistent://test-tenant/namespace/topic \
+ --per-partition
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/:schema/:tenant/:namespace/:topic/partitioned-stats|operation/getPartitionedStats?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.topics().getPartitionedStats(topic, true /* per partition */, false /* is precise backlog */);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+The following is an example. For the description of each topic stats, see [Pulsar statistics](administration-stats.md#topic-stats).
+
+Note that in the subscription JSON object, `chuckedMessageRate` is deprecated. Please use `chunkedMessageRate`. Both will be sent in the JSON for now.
+
+```json
+{
+ "msgRateIn" : 999.992947159793,
+ "msgThroughputIn" : 1070918.4635439808,
+ "msgRateOut" : 0.0,
+ "msgThroughputOut" : 0.0,
+ "bytesInCounter" : 270318763,
+ "msgInCounter" : 252489,
+ "bytesOutCounter" : 0,
+ "msgOutCounter" : 0,
+ "averageMsgSize" : 1070.926056966454,
+ "msgChunkPublished" : false,
+ "storageSize" : 270316646,
+ "backlogSize" : 200921133,
+ "publishers" : [ {
+ "msgRateIn" : 999.992947159793,
+ "msgThroughputIn" : 1070918.4635439808,
+ "averageMsgSize" : 1070.3333333333333,
+ "chunkedMessageRate" : 0.0,
+ "producerId" : 0
+ } ],
+ "subscriptions" : {
+ "test" : {
+ "msgRateOut" : 0.0,
+ "msgThroughputOut" : 0.0,
+ "bytesOutCounter" : 0,
+ "msgOutCounter" : 0,
+ "msgRateRedeliver" : 0.0,
+ "chuckedMessageRate" : 0,
+ "chunkedMessageRate" : 0,
+ "msgBacklog" : 144318,
+ "msgBacklogNoDelayed" : 144318,
+ "blockedSubscriptionOnUnackedMsgs" : false,
+ "msgDelayed" : 0,
+ "unackedMessages" : 0,
+ "msgRateExpired" : 0.0,
+ "lastExpireTimestamp" : 0,
+ "lastConsumedFlowTimestamp" : 0,
+ "lastConsumedTimestamp" : 0,
+ "lastAckedTimestamp" : 0,
+ "consumers" : [ ],
+ "isDurable" : true,
+ "isReplicated" : false
+ }
+ },
+ "replication" : { },
+ "metadata" : {
+ "partitions" : 3
+ },
+ "partitions" : { }
+}
+```
+
+### Internal stats
+
+You can check the detailed statistics of a partitioned topic. The following is an example. For the description of each internal topic stats, see [Pulsar statistics](administration-stats.md#topic-internal-stats).
+
+```json
+{
+ "entriesAddedCounter": 20449518,
+ "numberOfEntries": 3233,
+ "totalSize": 331482,
+ "currentLedgerEntries": 3233,
+ "currentLedgerSize": 331482,
+ "lastLedgerCreatedTimestamp": "2016-06-29 03:00:23.825",
+ "lastLedgerCreationFailureTimestamp": null,
+ "waitingCursorsCount": 1,
+ "pendingAddEntriesCount": 0,
+ "lastConfirmedEntry": "324711539:3232",
+ "state": "LedgerOpened",
+ "ledgers": [
+ {
+ "ledgerId": 324711539,
+ "entries": 0,
+ "size": 0
+ }
+ ],
+ "cursors": {
+ "my-subscription": {
+ "markDeletePosition": "324711539:3133",
+ "readPosition": "324711539:3233",
+ "waitingReadOp": true,
+ "pendingReadOps": 0,
+ "messagesConsumedCounter": 20449501,
+ "cursorLedger": 324702104,
+ "cursorLedgerLastEntry": 21,
+ "individuallyDeletedMessages": "[(324711539:3134‥324711539:3136], (324711539:3137‥324711539:3140], ]",
+ "lastLedgerSwitchTimestamp": "2016-06-29 01:30:19.313",
+ "state": "Open"
+ }
+ }
+}
+```
+
+You can get the internal stats for the partitioned topic in the following ways.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics partitioned-stats-internal \
+ persistent://test-tenant/namespace/topic
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/:schema/:tenant/:namespace/:topic/partitioned-internalStats|operation/getPartitionedInternalStats?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.topics().getPartitionedInternalStats(topic);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+
+## Manage subscriptions
+
+You can use [Pulsar admin API](admin-api-overview.md) to create, check, and delete subscriptions.
+
+### Create subscription
+
+You can create a subscription for a topic using one of the following methods.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics create-subscription \
+ --subscription my-subscription \
+ persistent://test-tenant/ns1/tp1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|PUT|/admin/v2/persistent/:tenant/:namespace/:topic/subscription/:subscription|operation/createSubscriptions?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+String subscriptionName = "my-subscription";
+admin.topics().createSubscription(topic, subscriptionName, MessageId.latest);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Get subscription
+
+You can check all subscription names for a given topic using one of the following methods.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics subscriptions persistent://test-tenant/ns1/tp1
+```
+
+Example output:
+
+```
+my-subscription
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/:schema/:tenant/:namespace/:topic/subscriptions|operation/getSubscriptions?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+admin.topics().getSubscriptions(topic);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+### Unsubscribe subscription
+
+When a subscription does not process messages anymore, you can unsubscribe it using one of the following methods.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin topics unsubscribe \
+ --subscription my-subscription \
+ persistent://test-tenant/ns1/tp1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|DELETE|/admin/v2/namespaces/:tenant/:namespace/:topic/subscription/:subscription|operation/deleteSubscription?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+String subscriptionName = "my-subscription";
+admin.topics().deleteSubscription(topic, subscriptionName);
+```
+
+</TabItem>
+
+</Tabs>
+````
diff --git a/versioned_docs/version-2.11.0/admin-api-transactions.md b/versioned_docs/version-2.11.0/admin-api-transactions.md
new file mode 100644
index 00000000000..818409454e3
--- /dev/null
+++ b/versioned_docs/version-2.11.0/admin-api-transactions.md
@@ -0,0 +1,725 @@
+---
+id: admin-api-transactions
+title: Manage transactions
+sidebar_label: "Transactions"
+---
+
+````mdx-code-block
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+````
+
+
+:::tip
+
+This page only shows **some frequently used operations**.
+
+- For the latest and complete information about `Pulsar admin`, including commands, flags, descriptions, and more, see [Pulsar admin doc](/tools/pulsar-admin/)
+
+- For the latest and complete information about `REST API`, including parameters, responses, samples, and more, see {@inject: rest:REST:/} API doc.
+
+- For the latest and complete information about `Java admin API`, including classes, methods, descriptions, and more, see [Java admin API doc](/api/admin/).
+
+:::
+
+## Transaction resources
+
+### GetSlowTransactions
+
+In the production environment, there may be some long-lasting transactions that have never been completed. You can get these slow transactions that have survived over a certain time under a coordinator or all coordinators in the following ways.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin transactions slow-transactions -c 1 -t 1s
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v3/transactions/slowTransactions/:timeout|operation/getSlowTransactions?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.transactions().getSlowTransactionsByCoordinatorId(coordinatorId, timeout, timeUnit)
+//Or get slow transactions from all coordinators
+admin.transactions().getSlowTransactions(timeout, timeUnit)
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+The following is an example of the returned values.
+
+```json
+{
+ "(0,3)": {
+ "txnId": "(0,3)",
+ "status": "OPEN",
+ "openTimestamp": 1658120122474,
+ "timeoutAt": 300000,
+ "producedPartitions": {},
+ "ackedPartitions": {}
+ },
+ "(0,2)": {
+ "txnId": "(0,2)",
+ "status": "OPEN",
+ "openTimestamp": 1658120122471,
+ "timeoutAt": 300000,
+ "producedPartitions": {},
+ "ackedPartitions": {}
+ },
+ "(0,5)": {
+ "txnId": "(0,5)",
+ "status": "OPEN",
+ "openTimestamp": 1658120122478,
+ "timeoutAt": 300000,
+ "producedPartitions": {},
+ "ackedPartitions": {}
+ },
+ "(0,4)": {
+ "txnId": "(0,4)",
+ "status": "OPEN",
+ "openTimestamp": 1658120122476,
+ "timeoutAt": 300000,
+ "producedPartitions": {},
+ "ackedPartitions": {}
+ },
+ "(0,7)": {
+ "txnId": "(0,7)",
+ "status": "OPEN",
+ "openTimestamp": 1658120122482,
+ "timeoutAt": 300000,
+ "producedPartitions": {},
+ "ackedPartitions": {}
+ },
+ "(0,10)": {
+ "txnId": "(0,10)",
+ "status": "OPEN",
+ "openTimestamp": 1658120122488,
+ "timeoutAt": 300000,
+ "producedPartitions": {},
+ "ackedPartitions": {}
+ },
+ "(0,6)": {
+ "txnId": "(0,6)",
+ "status": "OPEN",
+ "openTimestamp": 1658120122480,
+ "timeoutAt": 300000,
+ "producedPartitions": {},
+ "ackedPartitions": {}
+ },
+ "(0,9)": {
+ "txnId": "(0,9)",
+ "status": "OPEN",
+ "openTimestamp": 1658120122486,
+ "timeoutAt": 300000,
+ "producedPartitions": {},
+ "ackedPartitions": {}
+ },
+ "(0,8)": {
+ "txnId": "(0,8)",
+ "status": "OPEN",
+ "openTimestamp": 1658120122484,
+ "timeoutAt": 300000,
+ "producedPartitions": {},
+ "ackedPartitions": {}
+ },
+ "(0,11)": {
+ "txnId": "(0,11)",
+ "status": "OPEN",
+ "openTimestamp": 1658120122490,
+ "timeoutAt": 300000,
+ "producedPartitions": {},
+ "ackedPartitions": {}
+ }
+}
+```
+
+### ScaleTransactionCoordinators
+
+When the performance of transactions reaches a bottleneck due to the insufficient number of transaction coordinators, you can scale the number of the transaction coordinators in the following ways.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin transactions scale-transactionCoordinators -r 17
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v3/transactions/transactionCoordinator/:replicas|operation/scaleTransactionCoordinators?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.transactions().scaleTransactionCoordinators(replicas);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+## Transaction stats
+
+### Get transaction metadata
+
+The transaction metadata that can be retrieved include:
+* **txnId:** The ID of this transaction.
+* **status:** The status of this transaction.
+* **openTimestamp:** The open time of this transaction.
+* **timeoutAt:** The timeout of this transaction.
+* **producedPartitions:** The partitions or topics that messages have been sent to with this transaction.
+* **ackedPartitions:** The partitions or topics where messages have been acknowledged with this transaction.
+
+Use one of the following ways to get your transaction metadata.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin transactions transaction-metadata -m 1 -l 1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v3/transactions/transactionMetadata/:mostSigBits/:leastSigBits|operation/getTransactionMetadata?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.transactions().getTransactionMetadata(txnID);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+The following is an example of the returned values.
+
+```json
+{
+ "txnId" : "(1,18)",
+ "status" : "ABORTING",
+ "openTimestamp" : 1656592983374,
+ "timeoutAt" : 5000,
+ "producedPartitions" : {
+ "my-topic" : {
+ "startPosition" : "127:4959",
+ "aborted" : true
+ }
+ },
+ "ackedPartitions" : {
+ "my-topic" : {
+ "mysubName" : {
+ "cumulativeAckPosition" : null
+ }
+ }
+ }
+}
+```
+
+### Get transaction stats in transaction pending ack
+
+The transaction stats in transaction pending ack that can be retrieved include:
+* **cumulativeAckPosition:** The position that this transaction cumulatively acknowledges in this subscription.
+
+Use one of the following ways to get transaction stats in pending ack:
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin transactions transaction-in-pending-ack-stats -m 1 -l 1 -t my-topic -s mysubname
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v3/transactions/transactionInPendingAckStats/:tenant/:namespace/:topic/:subName/:mostSigBits/:leastSigBits|operation/getTransactionInPendingAckStats?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.transactions().getTransactionInPendingAckStats(txnID, topic, subname);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+The following is an example of the returned value.
+
+```json
+{
+ "cumulativeAckPosition" : "137:49959"
+ }
+```
+
+### Get transaction stats in transaction buffer
+
+The transaction stats in the transaction buffer that can be retrieved include:
+* **startPosition:** The start position of this transaction in the transaction buffer.
+* **aborted:** The flag of whether this transaction has been aborted.
+
+Use one of the following ways to get transaction stats in transaction buffer:
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin transactions transaction-in-buffer-stats -m 1 -l 1 -t my-topic
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v3/transactions/transactionInBufferStats/:tenant/:namespace/:topic/:mostSigBits/:leastSigBits|operation/getTransactionInBufferStats?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.transactions().getTransactionInBufferStatsAsync(txnID, topic);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+The following is an example of the returned values.
+
+```json
+{
+ "startPosition" : "137:49759",
+ "aborted" : false
+}
+```
+
+## Transaction coordinator stats
+
+The transaction coordinator (TC) is a module inside a Pulsar broker. It maintains the entire life cycle of transactions and handles transaction timeout.
+
+### Get coordinator stats
+The transaction coordinator stats that can be retrieved include:
+* **state:** The state of this transaction coordinator.
+* **leastSigBit:s** The sequence ID of this transaction coordinator.
+* **lowWaterMark:** The low watermark of this transaction coordinator.
+* **ongoingTxnSize:** The total number of ongoing transactions in this transaction coordinator.
+* **recoverStartTime:** The start timestamp of transaction coordinator recovery. `0L` means no startup.
+* **recoverEndTime:** The end timestamp of transaction coordinator recovery. `0L` means no startup.
+
+Use one of the following ways to get transaction coordinator stats:
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin transactions coordinator-stats -c 1
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v3/transactions/coordinatorStats|operation/getCoordinatorStats?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.transactions().getCoordinatorStatsById(coordinatorId);
+//Or get all coordinator stats.
+admin.transactions().getCoordinatorStats();
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+The following is an example of the returned values.
+
+```json
+{
+ "state" : "Ready",
+ "leastSigBits" : 1,
+ "lowWaterMark" : 0,
+ "ongoingTxnSize" : 0,
+ "recoverStartTime" : 1657021892377,
+ "recoverEndTime" : 1657021892378
+}
+```
+
+### Get coordinator internal stats
+
+The coordinator's internal stats that can be retrieved include:
+* **transactionLogStats:** The stats of the transaction coordinator log.
+* **managedLedgerName:** The name of the managed ledger where the transaction coordinator log is stored.
+* **managedLedgerInternalStats:** The internal stats of the managed ledger where the transaction coordinator log is stored. See `[managedLedgerInternalStats](admin-api-topics.md#get-internal-stats)` for more details.
+
+Use one of the following ways to get coordinator’s internal stats:
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin transactions coordinator-internal-stats -c 1 -m
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v3/transactions/coordinatorInternalStats/:coordinatorId|operation/getCoordinatorInternalStats?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.transactions().getCoordinatorInternalStats(coordinatorId, metadata);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+The following is an example of the returned values.
+
+```json
+{
+ "transactionLogStats" : {
+ "managedLedgerName" : "pulsar/system/persistent/__transaction_log_1",
+ "managedLedgerInternalStats" : {
+ "entriesAddedCounter" : 3,
+ "numberOfEntries" : 3,
+ "totalSize" : 63,
+ "currentLedgerEntries" : 3,
+ "currentLedgerSize" : 63,
+ "lastLedgerCreatedTimestamp" : "2022-06-30T18:18:05.88+08:00",
+ "waitingCursorsCount" : 0,
+ "pendingAddEntriesCount" : 0,
+ "lastConfirmedEntry" : "13:2",
+ "state" : "LedgerOpened",
+ "ledgers" : [ {
+ "ledgerId" : 13,
+ "entries" : 0,
+ "size" : 0,
+ "offloaded" : false,
+ "metadata" : "LedgerMetadata{formatVersion=3, ensembleSize=1, writeQuorumSize=1, ackQuorumSize=1, state=CLOSED, length=63, lastEntryId=2, digestType=CRC32C, password=OMITTED, ensembles={0=[10.20.240.119:3181]}, customMetadata={component=base64:bWFuYWdlZC1sZWRnZXI=, pulsar/managed-ledger=base64:cHVsc2FyL3N5c3RlbS9wZXJzaXN0ZW50L19fdHJhbnNhY3Rpb25fbG9nXzE=, application=base64:cHVsc2Fy}}",
+ "underReplicated" : false
+ } ],
+ "cursors" : {
+ "transaction.subscription" : {
+ "markDeletePosition" : "13:2",
+ "readPosition" : "13:3",
+ "waitingReadOp" : false,
+ "pendingReadOps" : 0,
+ "messagesConsumedCounter" : 3,
+ "cursorLedger" : 22,
+ "cursorLedgerLastEntry" : 1,
+ "individuallyDeletedMessages" : "[]",
+ "lastLedgerSwitchTimestamp" : "2022-06-30T18:18:05.932+08:00",
+ "state" : "Open",
+ "numberOfEntriesSinceFirstNotAckedMessage" : 1,
+ "totalNonContiguousDeletedMessagesRange" : 0,
+ "subscriptionHavePendingRead" : false,
+ "subscriptionHavePendingReplayRead" : false,
+ "properties" : { }
+ }
+ }
+ }
+ }
+}
+```
+
+## Transaction pending ack stats
+
+Pending ack maintains message acknowledgments within a transaction before a transaction completes. If a message is in the pending acknowledge state, the message cannot be acknowledged by other transactions until the message is removed from the pending acknowledge state.
+
+### Get transaction pending ack stats
+
+The transaction pending ack state stats that can be retrieved include:
+* **state:** The state of this transaction coordinator.
+* **lowWaterMark:** The low watermark of this transaction coordinator.
+* **ongoingTxnSize:** The total number of ongoing transactions in this transaction coordinator.
+* **recoverStartTime:** The start timestamp of transaction pendingAck recovery. `0L` means no startup.
+* **recoverEndTime:** The end timestamp of transaction pendingAck recovery. `0L` means no startup.
+
+Use one of the following ways to get transaction pending ack stats:
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin.transactions()s pending-ack-stats -t my-topic -s mysubName -l
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v3/transactions/pendingAckStats/:tenant/:namespace:/:topic:/:subName|operation/getPendingAckStats?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.transactions().getPendingAckStats(topic, subName, lowWaterMarks)
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+The following is an example of the returned values.
+
+```json
+{
+ "state" : "Ready",
+ "lowWaterMarks" : {
+ "1" : 0
+ },
+ "ongoingTxnSize" : 1,
+ "recoverStartTime" : 1657021899202,
+ "recoverEndTime" : 1657021899203
+}
+```
+
+### Get transaction pending ack internal stats
+
+The transaction pending ack internal stats that can be retrieved include:
+* **transactionLogStats:** The stats of the transaction pending ack log.
+* **managedLedgerName:** The name of the managed ledger where the transaction pending ack log is stored.
+* **managedLedgerInternalStats:** The internal stats of the managed ledger where the transaction coordinator log is stored. See `[managedLedgerInternalStats](admin-api-topics.md#get-internal-stats)` for more details.
+
+Use one of the following ways to get transaction pending ack internal stats:
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin transactions pending-ack-internal-stats -t my-topic -s mysubName -m
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v3/transactions/pendingAckInternalStats/:tenant/:namespace:/:topic:/:subName|operation/getPendingAckInternalStats?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.transactions().getPendingAckInternalStats(topic, subName, boolean metadata);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+The following is an example of the returned values.
+
+```json
+{
+ "pendingAckLogStats" : {
+ "managedLedgerName" : "public/default/persistent/my-topic-mysubName__transaction_pending_ack",
+ "managedLedgerInternalStats" : {
+ "entriesAddedCounter" : 2247,
+ "numberOfEntries" : 2247,
+ "totalSize" : 37212,
+ "currentLedgerEntries" : 104,
+ "currentLedgerSize" : 1732,
+ "lastLedgerCreatedTimestamp" : "2022-06-30T19:02:09.746+08:00",
+ "waitingCursorsCount" : 0,
+ "pendingAddEntriesCount" : 52,
+ "lastConfirmedEntry" : "64:51",
+ "state" : "LedgerOpened",
+ "ledgers" : [ {
+ "ledgerId" : 56,
+ "entries" : 2195,
+ "size" : 36346,
+ "offloaded" : false,
+ "metadata" : "LedgerMetadata{formatVersion=3, ensembleSize=1, writeQuorumSize=1, ackQuorumSize=1, state=CLOSED, length=36346, lastEntryId=2194, digestType=CRC32C, password=OMITTED, ensembles={0=[10.20.240.119:3181]}, customMetadata={component=base64:bWFuYWdlZC1sZWRnZXI=, pulsar/managed-ledger=base64:cHVibGljL2RlZmF1bHQvcGVyc2lzdGVudC9teS10b3BpYy1teXN1Yk5hbWVfX3RyYW5zYWN0aW9uX3BlbmRpbmdfYWNr, application=base64:cHVsc2Fy}}",
+ "underReplicated" : false
+ }, {
+ "ledgerId" : 64,
+ "entries" : 0,
+ "size" : 0,
+ "offloaded" : false,
+ "metadata" : "LedgerMetadata{formatVersion=3, ensembleSize=1, writeQuorumSize=1, ackQuorumSize=1, state=CLOSED, length=866, lastEntryId=51, digestType=CRC32C, password=OMITTED, ensembles={0=[10.20.240.119:3181]}, customMetadata={component=base64:bWFuYWdlZC1sZWRnZXI=, pulsar/managed-ledger=base64:cHVibGljL2RlZmF1bHQvcGVyc2lzdGVudC9teS10b3BpYy1teXN1Yk5hbWVfX3RyYW5zYWN0aW9uX3BlbmRpbmdfYWNr, application=base64:cHVsc2Fy}}",
+ "underReplicated" : false
+ } ],
+ "cursors" : {
+ "__pending_ack_state" : {
+ "markDeletePosition" : "56:-1",
+ "readPosition" : "56:0",
+ "waitingReadOp" : false,
+ "pendingReadOps" : 0,
+ "messagesConsumedCounter" : 0,
+ "cursorLedger" : 57,
+ "cursorLedgerLastEntry" : 0,
+ "individuallyDeletedMessages" : "[]",
+ "lastLedgerSwitchTimestamp" : "2022-06-30T18:55:26.842+08:00",
+ "state" : "Open",
+ "numberOfEntriesSinceFirstNotAckedMessage" : 1,
+ "totalNonContiguousDeletedMessagesRange" : 0,
+ "subscriptionHavePendingRead" : false,
+ "subscriptionHavePendingReplayRead" : false,
+ "properties" : { }
+ }
+ }
+ }
+ }
+}
+```
+
+### Get position stats in pending ack
+
+The position stats in pending ack include:
+* **PendingAck** The position is in pending ack stats.
+* **MarkDelete** The position is already acknowledged.
+* **NotInPendingAck** The position is not acknowledged within a transaction.
+* **PendingAckNotReady** The pending ack has not been initialized.
+* **InvalidPosition** The position is invalid, for example, batch index > batch size.
+
+If you want to know whether the position has been acknowledged, you can use one of the following ways to get position stats pending ack:
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin transactions position-stats-in-pending-ack -t my-topic -s mysubName -l 15 -e 6
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v3/transactions/pendingAckStats
+/:tenant/:namespace:/:topic:/:subName/:ledgerId/:entryId?batchIndex=batchIndex|operation/getPositionStatsInPendingAck?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.transactions().getPositionStatsInPendingAckAsync(topic, subName, ledgerId, entryId, lowWaterMarks);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+The following is an example of the returned values.
+
+```json
+{
+ "State" : "MarkDelete"
+}
+```
+
+## Transaction buffer stats
+
+Transaction buffer handles messages produced to a topic partition within a transaction.
+The messages in the transaction buffer are not visible to consumers until the transactions are committed. The messages in the transaction buffer are discarded when the transactions are aborted.
+
+### Get transaction buffer stats
+
+The transaction buffer stats that can be retrieved include:
+* **state:** The state of this transaction buffer.
+* **maxReadPosition:** The maximum read position of this transaction buffer.
+* **lastSnapshotTimestamps:** The last snapshot timestamp of this transaction buffer.
+* **lowWaterMarks (Optional):** The low watermark details of the transaction buffer.
+* **ongoingTxnSize:** The total number of ongoing transactions in this transaction buffer.
+* **recoverStartTime:** The start timestamp of transaction buffer recovery. `0L` means no startup.
+* **recoverEndTime:** The end timestamp of transaction buffer recovery. `0L` means no startup.
+
+Use one of the following ways to get transaction buffer stats:
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+```shell
+pulsar-admin transactions transaction-buffer-stats -t my-topic -l
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v3/transactions/transactionBufferStats/:tenant/:namespace:/:topic:/:subName|operation/getTransactionBufferStats?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+admin.transactions().getTransactionBufferStats(topic, lowWaterMarks);
+```
+
+</TabItem>
+
+</Tabs>
+````
+
+The following is an example of the returned values.
+
+```json
+{
+ "state" : "Ready",
+ "maxReadPosition" : "38:101",
+ "lastSnapshotTimestamps" : 1657021903534,
+ "lowWaterMarks" : {
+ "1" : -1,
+ "2" : -1
+ },
+ "ongoingTxnSize" : 0,
+ "recoverStartTime" : 1657021892850,
+ "recoverEndTime" : 1657021893372
+}
+```
\ No newline at end of file
diff --git a/versioned_docs/version-2.11.0/admin-get-started.md b/versioned_docs/version-2.11.0/admin-get-started.md
new file mode 100644
index 00000000000..a68dc556b23
--- /dev/null
+++ b/versioned_docs/version-2.11.0/admin-get-started.md
@@ -0,0 +1,82 @@
+---
+id: admin-api-get-started
+title: Get started
+sidebar_label: "Get started"
+---
+
+````mdx-code-block
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+````
+
+## Admin setup
+
+Each of the three admin interfaces (the `pulsar-admin` CLI tool, the {@inject: rest:REST:/} API, and the [Java admin API](/api/admin)) requires some special setup if you have enabled authentication in your Pulsar instance.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"},{"label":"Java","value":"Java"}]}>
+<TabItem value="pulsar-admin">
+
+If you have enabled authentication, you need to provide an auth configuration to use the `pulsar-admin` tool. By default, the configuration for the `pulsar-admin` tool is in the [`conf/client.conf`](reference-configuration.md#client) file. The following are the available parameters:
+
+|Name|Description|Default|
+|----|-----------|-------|
+|webServiceUrl|The web URL for the cluster.|http://localhost:8080/|
+|brokerServiceUrl|The Pulsar protocol URL for the cluster.|pulsar://localhost:6650/|
+|authPlugin|The authentication plugin.| |
+|authParams|The authentication parameters for the cluster, as a comma-separated string.| |
+|useTls|Whether or not TLS authentication will be enforced in the cluster.|false|
+|tlsAllowInsecureConnection|Accept untrusted TLS certificate from client.|false|
+|tlsTrustCertsFilePath|Path for the trusted TLS certificate file.| |
+
+</TabItem>
+<TabItem value="REST API">
+
+You can find details for the REST API exposed by Pulsar brokers in this {@inject: rest:document:/}.
+
+</TabItem>
+<TabItem value="Java">
+
+To use the Java admin API, instantiate a {@inject: javadoc:PulsarAdmin:/admin/org/apache/pulsar/client/admin/PulsarAdmin} object, and specify a URL for a Pulsar broker and a {@inject: javadoc:PulsarAdminBuilder:/admin/org/apache/pulsar/client/admin/PulsarAdminBuilder}. The following is a minimal example using `localhost`.
+
+```java
+String url = "http://localhost:8080";
+// Pass auth-plugin class fully-qualified name if Pulsar-security enabled
+String authPluginClassName = "com.org.MyAuthPluginClass";
+// Pass auth-param if auth-plugin class requires it
+String authParams = "param1=value1";
+boolean tlsAllowInsecureConnection = false;
+String tlsTrustCertsFilePath = null;
+PulsarAdmin admin = PulsarAdmin.builder()
+ .authentication(authPluginClassName,authParams)
+ .serviceHttpUrl(url)
+ .tlsTrustCertsFilePath(tlsTrustCertsFilePath)
+ .allowTlsInsecureConnection(tlsAllowInsecureConnection)
+ .build();
+```
+
+If you use multiple brokers, you can use multi-host like Pulsar service. For example,
+
+```java
+String url = "http://localhost:8080,localhost:8081,localhost:8082";
+// Below are the same to the line 2 - line 13 in the code snippet above
+// Pass auth-plugin class fully-qualified name if Pulsar-security enabled
+String authPluginClassName = "com.org.MyAuthPluginClass";
+// Pass auth-param if auth-plugin class requires it
+String authParams = "param1=value1";
+boolean tlsAllowInsecureConnection = false;
+String tlsTrustCertsFilePath = null;
+PulsarAdmin admin = PulsarAdmin.builder()
+ .authentication(authPluginClassName,authParams)
+ .serviceHttpUrl(url)
+ .tlsTrustCertsFilePath(tlsTrustCertsFilePath)
+ .allowTlsInsecureConnection(tlsAllowInsecureConnection)
+ .build();
+```
+
+</TabItem>
+
+</Tabs>
+````
diff --git a/versioned_docs/version-2.11.0/administration-geo.md b/versioned_docs/version-2.11.0/administration-geo.md
new file mode 100644
index 00000000000..cce2e607b3d
--- /dev/null
+++ b/versioned_docs/version-2.11.0/administration-geo.md
@@ -0,0 +1,275 @@
+---
+id: administration-geo
+title: Pulsar geo-replication
+sidebar_label: "Geo-replication"
+---
+
+````mdx-code-block
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+````
+
+
+## Enable geo-replication for a namespace
+
+You must enable geo-replication on a [per-tenant basis](#concepts-multi-tenancy) in Pulsar. For example, you can enable geo-replication between two specific clusters only when a tenant has access to both clusters.
+
+Geo-replication is managed at the namespace level, which means you only need to create and configure a namespace to replicate messages between two or more provisioned clusters that a tenant can access.
+
+Complete the following tasks to enable geo-replication for a namespace:
+
+* [Enable a geo-replication namespace](#enable-geo-replication-at-namespace-level)
+* [Configure that namespace to replicate across two or more provisioned clusters](admin-api-namespaces.md#configure-replication-clusters)
+
+Any message published on *any* topic in that namespace is replicated to all clusters in the specified set.
+
+## Local persistence and forwarding
+
+When messages are produced on a Pulsar topic, messages are first persisted in the local cluster, and then forwarded asynchronously to the remote clusters.
+
+In normal cases, when connectivity issues are none, messages are replicated immediately, at the same time as they are dispatched to local consumers. Typically, the network [round-trip time](https://en.wikipedia.org/wiki/Round-trip_delay_time) (RTT) between the remote regions defines end-to-end delivery latency.
+
+Applications can create producers and consumers in any of the clusters, even when the remote clusters are not reachable (like during a network partition).
+
+Producers and consumers can publish messages to and consume messages from any cluster in a Pulsar instance. However, subscriptions cannot only be local to the cluster where the subscriptions are created but also can be transferred between clusters after the replicated subscription is enabled. Once the replicated subscription is enabled, you can keep the subscription state in synchronization. Therefore, a topic can be asynchronously replicated across multiple geographical regions. In case [...]
+
+
+
+In the aforementioned example, the **T1** topic is replicated among three clusters, **Cluster-A**, **Cluster-B**, and **Cluster-C**.
+
+All messages produced in any of the three clusters are delivered to all subscriptions in other clusters. In this case, **C1** and **C2** consumers receive all messages that **P1**, **P2**, and **P3** producers publish. Ordering is still guaranteed on a per-producer basis.
+
+## Configure replication
+
+This section guides you through the steps to configure geo-replicated clusters.
+1. [Connect replication clusters](#connect-replication-clusters)
+2. [Grant permissions to properties](#grant-permissions-to-properties)
+3. [Enable geo-replication](#enable-geo-replication)
+4. [Use topics with geo-replication](#use-topics-with-geo-replication)
+
+### Connect replication clusters
+
+To replicate data among clusters, you need to configure each cluster to connect to the other. You can use the [`pulsar-admin`](/tools/pulsar-admin/) tool to create a connection.
+
+**Example**
+
+Suppose that you have 3 replication clusters: `us-west`, `us-cent`, and `us-east`.
+
+1. Configure the connection from `us-west` to `us-east`.
+
+ Run the following command on `us-west`.
+
+ ```shell
+ bin/pulsar-admin clusters create \
+ --broker-url pulsar://<DNS-OF-US-EAST>:<PORT> \
+ --url http://<DNS-OF-US-EAST>:<PORT> \
+ us-east
+ ```
+
+:::tip
+
+ - If you want to use a secure connection for a cluster, you can use the flags `--broker-url-secure` and `--url-secure`. For more information, see [pulsar-admin clusters create](/tools/pulsar-admin/).
+ - Different clusters may have different authentications. You can use the authentication flag `--auth-plugin` and `--auth-parameters` together to set cluster authentication, which overrides `brokerClientAuthenticationPlugin` and `brokerClientAuthenticationParameters` if `authenticationEnabled` sets to `true` in `broker.conf` and `standalone.conf`. For more information, see [authentication and authorization](concepts-authentication.md).
+
+:::
+
+2. Configure the connection from `us-west` to `us-cent`.
+
+ Run the following command on `us-west`.
+
+ ```shell
+ bin/pulsar-admin clusters create \
+ --broker-url pulsar://<DNS-OF-US-CENT>:<PORT> \
+ --url http://<DNS-OF-US-CENT>:<PORT> \
+ us-cent
+ ```
+
+3. Run similar commands on `us-east` and `us-cent` to create connections among clusters.
+
+### Grant permissions to properties
+
+To replicate to a cluster, the tenant needs permission to use that cluster. You can grant permission to the tenant when you create the tenant or grant it later.
+
+Specify all the intended clusters when you create a tenant:
+
+```shell
+bin/pulsar-admin tenants create my-tenant \
+--admin-roles my-admin-role \
+--allowed-clusters us-west,us-east,us-cent
+```
+
+To update permissions of an existing tenant, use `update` instead of `create`.
+
+### Enable geo-replication
+
+You can enable geo-replication at **namespace** or **topic** level.
+
+#### Enable geo-replication at namespace level
+
+You can create a namespace with the following command sample.
+
+```shell
+bin/pulsar-admin namespaces create my-tenant/my-namespace
+```
+
+Initially, the namespace is not assigned to any cluster. You can assign the namespace to clusters using the `set-clusters` subcommand:
+
+```shell
+bin/pulsar-admin namespaces set-clusters my-tenant/my-namespace \
+--clusters us-west,us-east,us-cent
+```
+
+#### Enable geo-replication at topic level
+
+You can set geo-replication at topic level using the command `pulsar-admin topics set-replication-clusters`. For the latest and complete information about `Pulsar admin`, including commands, flags, descriptions, and more information, see [Pulsar admin doc](/tools/pulsar-admin/).
+
+```shell
+bin/pulsar-admin topics set-replication-clusters --clusters us-west,us-east,us-cent my-tenant/my-namespace/my-topic
+```
+
+:::tip
+
+- You can change the replication clusters for a namespace at any time, without disruption to ongoing traffic. Replication channels are immediately set up or stopped in all clusters as soon as the configuration changes.
+- Once you create a geo-replication namespace, any topics that producers or consumers create within that namespace are replicated across clusters. Typically, each application uses the `serviceUrl` for the local cluster.
+- If you are using Pulsar version `2.10.x`, to enable geo-replication at topic level, you need to change the following configurations in the `conf/broker.conf` or `conf/standalone.conf` file to enable topic policies service.
+
+```conf
+systemTopicEnabled=true
+topicLevelPoliciesEnabled=true
+```
+
+:::
+
+### Use topics with geo-replication
+
+#### Selective replication
+
+By default, messages are replicated to all clusters configured for the namespace. You can restrict replication selectively by specifying a replication list for a message, and then that message is replicated only to the subset in the replication list.
+
+The following is an example of the [Java](client-libraries-java.md) API](client-libraries-java.md). Note the use of the `setReplicationClusters` method when you construct the {@inject: javadoc:Message:/client/org/apache/pulsar/client/api/Message} object:
+
+```java
+List<String> restrictReplicationTo = Arrays.asList(
+ "us-west",
+ "us-east"
+);
+
+Producer producer = client.newProducer()
+ .topic("some-topic")
+ .create();
+
+producer.newMessage()
+ .value("my-payload".getBytes())
+ .setReplicationClusters(restrictReplicationTo)
+ .send();
+```
+
+#### Topic stats
+
+You can check topic-specific statistics for geo-replication topics using one of the following methods.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="pulsar-admin"
+ values={[{"label":"pulsar-admin","value":"pulsar-admin"},{"label":"REST API","value":"REST API"}]}>
+<TabItem value="pulsar-admin">
+
+Use the [`pulsar-admin topics stats`](/tools/pulsar-admin/) command.
+
+```shell
+bin/pulsar-admin topics stats persistent://my-tenant/my-namespace/my-topic
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/:schema/:tenant/:namespace/:topic/stats|operation/getStats?version=@pulsar:version_number@}
+
+</TabItem>
+
+</Tabs>
+````
+
+Each cluster reports its own local stats, including the incoming and outgoing replication rates and backlogs.
+
+#### Delete a geo-replication topic
+
+Given that geo-replication topics exist in multiple regions, directly deleting a geo-replication topic is not possible. Instead, you should rely on automatic topic garbage collection.
+
+In Pulsar, a topic is automatically deleted when the topic meets the following three conditions:
+- no producers or consumers are connected to it;
+- no subscriptions to it;
+- no more messages are kept for retention.
+For geo-replication topics, each region uses a fault-tolerant mechanism to decide when deleting the topic locally is safe.
+
+You can explicitly disable topic garbage collection by setting `brokerDeleteInactiveTopicsEnabled` to `false` in your [broker configuration](reference-configuration.md#broker).
+
+To delete a geo-replication topic, close all producers and consumers on the topic, and delete all of its local subscriptions in every replication cluster. When Pulsar determines that no valid subscription for the topic remains across the system, it will garbage collect the topic.
+
+## Replicated subscriptions
+
+Pulsar supports replicated subscriptions, so you can keep the subscription state in sync, within a sub-second timeframe, in the context of a topic that is being asynchronously replicated across multiple geographical regions.
+
+In case of failover, a consumer can restart consuming from the failure point in a different cluster.
+
+### Enable replicated subscription
+
+Replicated subscription is disabled by default. You can enable replicated subscriptions when creating a consumer.
+
+```java
+Consumer<String> consumer = client.newConsumer(Schema.STRING)
+ .topic("my-topic")
+ .subscriptionName("my-subscription")
+ .replicateSubscriptionState(true)
+ .subscribe();
+```
+
+### Advantages
+
+ * It is easy to implement the logic.
+ * You can choose to enable or disable replicated subscription.
+ * When you enable it, the overhead is low, and it is easy to configure.
+ * When you disable it, the overhead is zero.
+
+### Limitations
+
+* When you enable replicated subscriptions, you're creating a consistent distributed snapshot to establish an association between message ids from different clusters. The snapshots are taken periodically. The default value is `1 second`. It means that a consumer failing over to a different cluster can potentially receive 1 second of duplicates. You can also configure the frequency of the snapshot in the `broker.conf` file.
+* Only the base line cursor position is synced in replicated subscriptions while the individual acknowledgments are not synced. This means the messages acknowledged out-of-order could end up getting delivered again, in the case of a cluster failover.
+
+## Migrate data between clusters using geo-replication
+
+Using geo-replication to migrate data between clusters is a special use case of the [active-active replication pattern](concepts-replication.md#active-active-replication) when you don't have a large amount of data.
+
+1. Create your new cluster.
+2. Add the new cluster to your old cluster.
+
+ ```shell
+ bin/pulsar-admin cluster create new-cluster
+ ```
+
+3. Add the new cluster to your tenant.
+
+ ```shell
+ bin/pulsar-admin tenants update my-tenant --cluster old-cluster,new-cluster
+ ```
+
+4. Set the clusters on your namespace.
+
+ ```shell
+ bin/pulsar-admin namespaces set-clusters my-tenant/my-ns --cluster old-cluster,new-cluster
+ ```
+
+5. Update your applications using [replicated subscriptions](#replicated-subscriptions).
+6. Validate subscription replication is active.
+ ```shell
+ bin/pulsar-admin topics stats-internal public/default/t1
+ ```
+
+7. Move your consumers and producers to the new cluster by modifying the values of `serviceURL`.
+
+:::note
+
+* The replication starts from step 4, which means existing messages in your old cluster are not replicated.
+* If you have some older messages to migrate, you can pre-create the replication subscriptions for each topic and set it at the earliest position by using `pulsar-admin topics create-subscription -s pulsar.repl.new-cluster -m earliest <topic>`.
+
+:::
diff --git a/versioned_docs/version-2.11.0/administration-isolation-bookie.md b/versioned_docs/version-2.11.0/administration-isolation-bookie.md
new file mode 100644
index 00000000000..9351c4d4146
--- /dev/null
+++ b/versioned_docs/version-2.11.0/administration-isolation-bookie.md
@@ -0,0 +1,269 @@
+---
+id: administration-isolation-bookie
+title: Isolate bookies
+sidebar_label: "Isolate bookies"
+---
+
+````mdx-code-block
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+````
+
+
+Isolating bookies equals isolating message storage, which is a data storage mechanism that provides isolation and safety for specific topics.
+
+Bookie isolation is controlled by BookKeeper clients. For Pulsar, there are two kinds of BookKeeper clients to read and write data.
+* BookKeeper clients on the broker side: Pulsar brokers use these BookKeeper clients to read and write topic messages.
+* BookKeeper clients on the bookie auto-recovery side:
+ * The bookie auditor checks whether ledger replicas fulfill the configured isolation policy;
+ * The bookie replication worker writes ledger replicas to target bookies according to the configured isolation policy.
+
+To isolate bookies, you need to complete the following tasks.
+1. Select a [data isolation policy](#understand-bookie-data-isolation-policy) based on your requirements.
+2. [Enable the policy on BookKeeper clients](#enable-bookie-data-placement-policy).
+3. [Configure the policy on bookie instances](#configure-data-placement-policy-on-bookie-instances).
+
+
+## Understand bookie data isolation policy
+
+Bookie data isolation policy is built on top of the existing BookKeeper rack-aware placement policy. The "rack" concept can be anything, for example, racks, regions, availability zones. It writes the configured isolation policy into the metadata store. Both BookKeeper clients on the broker and bookie auto-recovery side read the configured isolation policy from the metadata store and apply it when choosing bookies to store messages.
+
+BookKeeper provides three kinds of data isolation policies for disaster tolerance.
+* Rack-aware placement policy (default)
+* Region-aware placement policy
+* Zone-aware placement policy
+
+:::tip
+
+* Both [rack-aware placement policy](#rack-aware-placement-policy) and [region-aware placement policy](#region-aware-placement-policy) can be used in all kinds of deployments where racks are a subset of a region. The major difference between the two policies is:
+ * With `RackawareEnsemblePlacementPolicy` configured, the BookKeeper client chooses bookies from different **racks** to reduce the single point of failure. If there is only one rack available, the policy falls back on choosing a random bookie across available ones.
+ * With `RegionAwareEnsemblePlacementPolicy` configured, the BookKeeper client chooses bookies from different **regions**; for the selected region, it chooses bookies from different racks if more than one ensemble falls into the same region.
+
+* Zone-aware placement policy (`ZoneAwareEnsemblePlacementPolicy`) can be used in a public cloud infrastructure where Availability Zones (AZs) are isolated locations within the data center regions that public cloud services originate from and operate in.
+
+:::
+
+### Rack-aware placement policy
+
+Rack-aware placement policy enforces different data replicas to be placed in different racks to guarantee the rack-level disaster tolerance for your production environment. A data center usually has a lot of racks, and each rack has many storage nodes. You can use `RackAwareEnsemblePlacementPolicy` to configure the rack information for each bookie.
+
+#### Qualified rack size of bookies
+
+When the available rack size of bookies can meet the requirements configured on a topic, the rack-aware placement policy can work well and you don’t need any extra configurations.
+
+For example, the BookKeeper cluster has 4 racks and 13 bookie instances as shown in the following diagram. When a topic is configured with `EnsembleSize=3, WriteQuorum=3, AckQuorum=2`, the BookKeeper client chooses one bookie instance from three different racks to write data to, such as Bookie2, Bookie8, and Bookie12.
+
+
+
+
+#### Enforced minimum rack size of bookies
+
+When the available rack size of bookies cannot meet the requirements configured on a topic, the strategy that the BookKeeper client chooses bookies to recover old ledgers and create new ledgers depends on whether the enforced minimum rack size of bookies is configured.
+
+In this case, if you want to make the rack-aware placement policy work as usual, you need to configure an enforced minimum rack size of bookies (`MinNumRacksPerWriteQuorum`).
+
+For example, you have the same BookKeeper cluster with the same topic requirements `EnsembleSize=3, WriteQuorum=3, AckQuorum=2` as shown in the above diagram. When all the bookie instances in Rack3 and Rack4 fail, you only have 2 available racks and there are the following three possibilities.
+
+* If you have configured `EnforceMinNumRacksPerWriteQuorum=true` and `MinNumRacksPerWriteQuorum=3`, the BookKeeper client fails to choose bookies, which means new ledgers cannot be created and old ledgers cannot be recovered. Because the requirement of `MinNumRacksPerWriteQuorum=3` cannot be fulfilled.
+
+* If you have configured `EnforceMinNumRacksPerWriteQuorum=true` and `MinNumRacksPerWriteQuorum=2`, the BookKeeper client chooses one bookie from Rack1 and Rack2 to recover old ledgers, such as bookie1 and bookie5, to place 2 replicas for Bookie8 and Bookie12. For new ledger creation, it chooses one bookie from Rack1 and Rack2, such as Bookie4 and Bookie7, and a random bookie from either Rack1 or Rack2 to place the last replica.
+
+
+
+* If you have configured `EnforceMinNumRacksPerWriteQuorum=false`, the BookKeeper client tries its best effort to apply the placement policy depending on the available number of racks and bookies. It may still work as the above diagram or the following diagram.
+
+
+
+### Region-aware placement policy
+
+Region-aware placement policy enforces different data replicas to be placed in different regions and racks to guarantee region-level disaster tolerance. To achieve datacenter level disaster tolerance, you need to write data replicas into different data centers. You can use `RegionAwareEnsemblePlacementPolicy` to configure region and rack information for each bookie node to ensure region-level disaster tolerance.
+
+For example, the BookKeeper cluster has 4 regions, and each region has several racks with their bookie instances, as shown in the following diagram. If a topic is configured with `EnsembleSize=3, WriteQuorum=3, and AckQuorum=2`, the BookKeeper client chooses three different regions, such as Region A, Region C and Region D. For each region, it chooses one bookie on a single rack, such as Bookie5 on Rack2, Bookie17 on Rack6, and Bookie21 on Rack8.
+
+
+
+When two regions fail, such as Region B and Region C, as shown in the following diagram, the BookKeeper client chooses one bookie from Region A or Region D to replace the failed Bookie17 for recovering old ledgers. And it also chooses Region A and Region D to write replicas for creating new ledgers. In Region A, it falls back to rack-aware placement policy and chooses one bookie from Rack1 and Rack2, such as Bookie4 and Bookie7. For Region D, it has to choose one bookie from Rack8, such [...]
+
+
+
+## Enable bookie data placement policy
+
+By default, the rack-aware placement policy is enabled on both broker and bookie sides. If you want to switch to the region-aware placement policy, you need to enable the region-aware placement policy on both broker and bookie sides.
+
+### Enable region-aware placement policy on broker
+
+Configure the following field in the `conf/broker.conf` file.
+
+```properties
+bookkeeperClientRegionawarePolicyEnabled=true
+```
+
+To enforce the minimum rack size of bookies, configure the following fields:
+
+```properties
+bookkeeperClientEnforceMinNumRacksPerWriteQuorum=true
+bookkeeperClientMinNumRacksPerWriteQuorum=2
+```
+
+To balance the ledger disk usage of different bookies, you can enable the disk weight placement by configuring the following field:
+
+```properties
+bookkeeperDiskWeightBasedPlacementEnabled=true
+```
+### Enable region-aware placement policy on the auto-recovery instances (pods)
+
+Configure the following fields in the `conf/bookkeeper.conf` file.
+
+```properties
+ensemblePlacementPolicy=org.apache.bookkeeper.client.RegionAwareEnsemblePlacementPolicy
+reppDnsResolverClass=org.apache.pulsar.zookeeper.ZkBookieRackAffinityMapping
+```
+
+To enforce the minimum rack size of bookies, configure the following fields:
+
+```properties
+enforceMinNumRacksPerWriteQuorum=true
+minNumRacksPerWriteQuorum=2
+```
+
+To balance the ledger disk usage of different bookies, you can enable the disk weight placement by configuring the following field:
+
+```properties
+diskWeightBasedPlacementEnabled=true
+```
+
+## Configure data placement policy on bookie instances
+
+To configure a data placement policy on bookie instances, you can use one of the following methods.
+
+````mdx-code-block
+<Tabs
+ defaultValue="Pulsar-admin CLI"
+ values={[{"label":"Pulsar-admin CLI","value":"Pulsar-admin CLI"},{"label":"REST API","value":"REST API"}]}>
+
+<TabItem value="Pulsar-admin CLI">
+
+
+Specify the rack name to represent which region or rack this bookie belongs to.
+
+```bash
+bin/pulsar-admin bookies set-bookie-rack
+The following options are required: [-b | --bookie], [-r | --rack]
+
+Then we need to update the rack placement information for a specific bookie in the cluster. Note that the bookie address format is `address:port`.
+Usage: set-bookie-rack [options]
+ Options:
+ * -b, --bookie
+ Bookie address (format: `address:port`)
+ -g, --group
+ Bookie group name
+ Default: default
+ --hostname
+ Bookie host name
+ * -r, --rack
+ Bookie rack name
+```
+
+:::tip
+
+In addition, you can also group bookies across racks or regions to serve broker-level isolation by specifying a group name for each bookie and assigning the group name to a specific namespace. See [configure bookie affinity groups](#configure-bookie-affinity-groups) for more details.
+
+:::
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v2/bookies/racks-info/:bookie|operation/updateBookieRackInfo?version=@pulsar:version_number@}
+
+</TabItem>
+
+</Tabs>
+````
+
+
+#### Example of configuring rack-aware placement policy
+
+The following is an example of how to configure bookie instances with their rack properties.
+
+```bash
+bin/pulsar-admin bookies set-bookie-rack --bookie bookie1:3181 --hostname bookie1.pulsar.com:3181 --group group1 --rack rack1
+bin/pulsar-admin bookies set-bookie-rack --bookie bookie2:3181 --hostname bookie2.pulsar.com:3181 --group group1 --rack rack1
+bin/pulsar-admin bookies set-bookie-rack --bookie bookie3:3181 --hostname bookie3.pulsar.com:3181 --group group1 --rack rack1
+bin/pulsar-admin bookies set-bookie-rack --bookie bookie4:3181 --hostname bookie4.pulsar.com:3181 --group group1 --rack rack1
+bin/pulsar-admin bookies set-bookie-rack --bookie bookie5:3181 --hostname bookie5.pulsar.com:3181 --group group1 --rack rack2
+...
+```
+
+#### Example of configuring region-aware placement policy
+
+The following is an example of how to configure bookie instances with their region/rack properties.
+
+```bash
+bin/pulsar-admin bookies set-bookie-rack --bookie bookie1:3181 --hostname bookie1.pulsar.com:3181 --group group1 --rack RegionA/rack1
+bin/pulsar-admin bookies set-bookie-rack --bookie bookie2:3181 --hostname bookie2.pulsar.com:3181 --group group1 --rack RegionA/rack1
+bin/pulsar-admin bookies set-bookie-rack --bookie bookie3:3181 --hostname bookie3.pulsar.com:3181 --group group1 --rack RegionA/rack1
+bin/pulsar-admin bookies set-bookie-rack --bookie bookie4:3181 --hostname bookie4.pulsar.com:3181 --group group1 --rack RegionA/rack1
+bin/pulsar-admin bookies set-bookie-rack --bookie bookie5:3181 --hostname bookie5.pulsar.com:3181 --group group1 --rack RegionA/rack2
+bin/pulsar-admin bookies set-bookie-rack --bookie bookie6:3181 --hostname bookie6.pulsar.com:3181 --group group1 --rack RegionA/rack2
+bin/pulsar-admin bookies set-bookie-rack --bookie bookie7:3181 --hostname bookie7.pulsar.com:3181 --group group1 --rack RegionA/rack2
+bin/pulsar-admin bookies set-bookie-rack --bookie bookie8:3181 --hostname bookie8.pulsar.com:3181 --group group1 --rack RegionB/rack3
+...
+```
+
+## Configure bookie affinity groups
+
+The data of a namespace can be isolated into user-defined groups of bookies, as known as bookie affinity groups, which guarantee all the data that belongs to the namespace is stored in desired bookies.
+
+**Prerequisites:** Before configuring bookie affinity groups, you need to group bookies first. See [configure data placement policy on bookie instances](#configure-data-placement-policy-on-bookie-instances) for more details.
+
+To configure bookie affinity groups, you can use one of the following methods.
+
+````mdx-code-block
+<Tabs
+ defaultValue="Pulsar-admin CLI"
+ values={[{"label":"Pulsar-admin CLI","value":"Pulsar-admin CLI"},{"label":"REST API","value":"REST API"},{"label":"Java admin API","value":"Java admin API"}]}>
+
+<TabItem value="Pulsar-admin CLI">
+
+```shell
+pulsar-admin namespaces set-bookie-affinity-group options
+```
+
+For more information about the command `pulsar-admin namespaces set-bookie-affinity-group options`, see [Pulsar admin docs](/tools/pulsar-admin/).
+
+**Example**
+
+```shell
+bin/pulsar-admin bookies set-bookie-rack \
+--bookie 127.0.0.1:3181 \
+--hostname 127.0.0.1:3181 \
+--group group-bookie1 \
+--rack rack1
+
+bin/pulsar-admin namespaces set-bookie-affinity-group public/default \
+--primary-group group-bookie1
+```
+
+:::note
+
+- Do not set a bookie rack name to slash (`/`) or an empty string (`""`) if you use Pulsar earlier than 2.7.5, 2.8.3, and 2.9.2. If you use Pulsar 2.7.5, 2.8.3, 2.9.2 or later versions, it falls back to `/default-rack` or `/default-region/default-rack`.
+- When `RackawareEnsemblePlacementPolicy` is enabled, the rack name is not allowed to contain one slash (`/`) except for the beginning and end of the rack name string. For example, a rack name like `/rack0` is allowed, but `/rack/0` is invalid.
+- When `RegionAwareEnsemblePlacementPolicy` is enabled, the rack name can only contain one slash (`/`) except for the beginning and end of the rack name string. For example, rack name like `/region0/rack0` is allowed, but `/region0rack0` and `/region0/rack/0` are invalid.
+For the bookie rack name restrictions, see [pulsar-admin bookies set-bookie-rack](/tools/pulsar-admin/).
+
+:::
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v2/namespaces/:tenant/:namespace/persistence/bookieAffinity|operation/setBookieAffinityGroup?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java admin API">
+
+For how to set bookie affinity group for a namespace using Java admin API, see [code](https://github.com/apache/pulsar/blob/master/pulsar-client-admin/src/main/java/org/apache/pulsar/client/admin/internal/NamespacesImpl.java#L1164).
+
+</TabItem>
+
+</Tabs>
+````
diff --git a/versioned_docs/version-2.11.0/administration-isolation-broker.md b/versioned_docs/version-2.11.0/administration-isolation-broker.md
new file mode 100644
index 00000000000..3a868e6dd8b
--- /dev/null
+++ b/versioned_docs/version-2.11.0/administration-isolation-broker.md
@@ -0,0 +1,60 @@
+---
+id: administration-isolation-broker
+title: Isolate brokers
+sidebar_label: "Isolate brokers"
+---
+
+````mdx-code-block
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+````
+
+
+In Pulsar, when namespaces (more specifically, namespace bundles) are assigned dynamically to brokers, the namespace isolation policy limits the set of brokers that can be used for assignment. Before topics are assigned to brokers, you can set the namespace isolation policy with a primary or a secondary regex to select desired brokers.
+
+To set a namespace isolation policy for a broker cluster, you can use one of the following methods.
+
+````mdx-code-block
+<Tabs
+ defaultValue="Pulsar-admin CLI"
+ values={[{"label":"Pulsar-admin CLI","value":"Pulsar-admin CLI"},{"label":"REST API","value":"REST API"},{"label":"Java admin API","value":"Java admin API"}]}>
+
+<TabItem value="Pulsar-admin CLI">
+
+```shell
+pulsar-admin ns-isolation-policy set options
+```
+
+For more information about the command `pulsar-admin ns-isolation-policy set options`, see [Pulsar admin docs](https://pulsar.apache.org/tools/pulsar-admin/).
+
+**Example**
+
+```shell
+bin/pulsar-admin ns-isolation-policy set \
+--auto-failover-policy-type min_available \
+--auto-failover-policy-params min_limit=1,usage_threshold=80 \
+--namespaces my-tenant/my-namespace \
+--primary 10.193.216.* my-cluster policy-name
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|PUT|/admin/v2/:namespace/:tenant/:namespace|operation/createNamespace?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java admin API">
+
+For how to set namespace isolation policy using Java admin API, see [code](https://github.com/apache/pulsar/blob/master/pulsar-client-admin/src/main/java/org/apache/pulsar/client/admin/internal/NamespacesImpl.java#L251).
+
+</TabItem>
+
+</Tabs>
+````
+
+
+:::tip
+
+To guarantee all the data that belongs to a namespace is stored in desired bookies, you can isolate the data of the namespace into user-defined groups of bookies. See [configure bookie affinity groups](administration-isolation-bookie.md#configure-bookie-affinity-groups) for more details.
+
+:::
\ No newline at end of file
diff --git a/versioned_docs/version-2.11.0/administration-isolation.md b/versioned_docs/version-2.11.0/administration-isolation.md
new file mode 100644
index 00000000000..4e78fe8095c
--- /dev/null
+++ b/versioned_docs/version-2.11.0/administration-isolation.md
@@ -0,0 +1,73 @@
+---
+id: administration-isolation
+title: Pulsar isolation
+sidebar_label: "Pulsar isolation"
+---
+
+
+In an organization, a Pulsar instance provides services to multiple teams. When organizing the resources across multiple teams, you want to make a suitable isolation plan to avoid resource competition between different teams and applications and provide high-quality messaging service. In this case, you need to consider resource isolation and weigh your intended actions against expected and unexpected consequences.
+
+The multi-layer and segment-centric architecture and hierarchical resource management of Pulsar provide a solid foundation for isolation, which allows you to isolate resources in your desired manner, prevent resource competition, and attain stability.
+
+
+## Isolation levels
+
+Pulsar supports isolation at either of the following two levels or both.
+* [Broker-level isolation](administration-isolation-broker.md) divides brokers into different groups and assigns broker groups to different namespaces. In this way, you can bind topics in a namespace to a set of brokers that belong to specific groups.
+* [Bookie-level isolation](administration-isolation-bookie.md) divides bookies into different racks/regions and assigns data replicas to bookies based on a specified data placement policy for disaster tolerance.
+
+
+
+:::tip
+
+On top of [broker-level isolation](administration-isolation-broker.md) and [bookie-level isolation](administration-isolation-bookie.md), if you want to guarantee all the data that belongs to a namespace is stored in desired bookies, you can define and configure [bookie affinity groups](administration-isolation-bookie.md#configure-bookie-affinity-groups). See [shared BookKeeper cluster deployment](#shared-bookkeeper-cluster) for more details.
+
+:::
+
+
+## Deployments to achieve isolation within Pulsar
+
+### Separate Pulsar clusters
+
+The following illustration demonstrates the deployment of separate Pulsar clusters to achieve the highest-level isolation.
+
+
+
+Here are some key points for understanding how it works:
+- Separate Pulsar clusters use a shared [configuration store](concepts-architecture-overview.md#configuration-store).
+- Each cluster exposes its service through a DNS entry point and makes sure a client can access the cluster through the DNS entry point. Clients can use one or multiple Pulsar URLs that the Pulsar cluster exposes as the service URL.
+- Each Pulsar cluster has one or multiple brokers and bookies.
+- Each Pulsar cluster has one metadata store, which can be separated into [Pulsar metadata store](concepts-architecture-overview.md#metadata-store) and [BookKeeper metadata store](https://bookkeeper.apache.org/docs/latest/getting-started/concepts/#metadata-storage).
+
+:::note
+
+When using this approach, if you want to achieve namespace isolation, you need to specify a cluster for a namespace. The cluster must be in the allowed cluster list of the tenant. Topics under the namespace are assigned to this cluster.
+
+:::
+
+### Shared BookKeeper cluster
+
+The following illustration demonstrates the deployment of shared BookKeeper clusters to achieve isolation.
+
+
+
+Here are some key points for understanding how it works:
+- Separate Pulsar clusters share a BookKeeper cluster and a [configuration store](concepts-architecture-overview.md#configuration-store).
+- Each cluster exposes its service through a DNS entry point and makes sure a client can access the cluster through the DNS entry point. Clients can use one or multiple Pulsar URLs that the Pulsar cluster exposes as the service URL.
+- Each Pulsar cluster has one or multiple brokers.
+- Each Pulsar cluster has one metadata store.
+
+As illustrated below, all bookie groups use a shared BookKeeper cluster and a metadata store, and each [bookie affinity group](administration-isolation-bookie.md#configure-bookie-affinity-groups) has one or several bookies. You can specify one or multiple primary/secondary groups for a namespace. Topics under the namespace are created on the bookies in the primary group first and then created on the bookies in the secondary group.
+
+
+
+### Single Pulsar cluster
+
+The following illustration demonstrates how to achieve isolation inside a single Pulsar cluster.
+
+
+
+Here are some key points for understanding how it works:
+- Each cluster exposes its service through a DNS entry point and makes sure a client can access the cluster through the DNS entry point. Clients can use one or multiple Pulsar URLs that the Pulsar cluster exposes as the service URL.
+- Broker isolation is achieved by setting a [namespace isolation policy](administration-isolation-broker.md).
+
diff --git a/versioned_docs/version-2.11.0/administration-load-balance.md b/versioned_docs/version-2.11.0/administration-load-balance.md
new file mode 100644
index 00000000000..c31cb88cf2f
--- /dev/null
+++ b/versioned_docs/version-2.11.0/administration-load-balance.md
@@ -0,0 +1,279 @@
+---
+id: administration-load-balance
+title: Load balance across brokers
+sidebar_label: "Load balance"
+---
+
+
+Pulsar is a horizontally scalable messaging system, so the traffic in a logical cluster must be balanced across all the available Pulsar brokers as evenly as possible, which is a core requirement.
+
+You can use multiple settings and tools to control the traffic distribution which requires a bit of context to understand how the traffic is managed in Pulsar. Though in most cases, the core requirement mentioned above is true out of the box and you should not worry about it.
+
+The following sections introduce how load-balanced assignments work across Pulsar brokers and how you can leverage the framework to adjust.
+
+## Dynamic assignments
+
+Topics are dynamically assigned to brokers based on the load conditions of all brokers in the cluster. The assignment of topics to brokers is not done at the topic level but the **bundle** level (a higher level). Instead of individual topic assignments, each broker takes ownership of a subset of the topics for a namespace. This subset is called a bundle and effectively this subset is a sharding mechanism.
+
+In other words, each namespace is an "administrative" unit and sharded into a list of bundles, with each bundle comprising a portion of the overall hash range of the namespace. Topics are assigned to a particular bundle by taking the hash of the topic name and checking in which bundle the hash falls. Each bundle is independent of the others and thus is independently assigned to different brokers.
+
+The benefit of the assignment granularity is to amortize the amount of information that you need to keep track of. Based on CPU, memory, traffic load, and other indexes, topics are assigned to a particular broker dynamically. For example:
+* When a client starts using new topics that are not assigned to any broker, a process is triggered to choose the best-suited broker to acquire ownership of these topics according to the load conditions.
+* If the broker owning a topic becomes overloaded, the topic is reassigned to a less-loaded broker.
+* If the broker owning a topic crashes, the topic is reassigned to another active broker.
+
+:::tip
+
+For partitioned topics, different partitions are assigned to different brokers. Here "topic" means either a non-partitioned topic or one partition of a topic.
+
+:::
+
+## Create namespaces with assigned bundles
+
+When you create a new namespace, a number of bundles are assigned to the namespace. You can set this number in the `conf/broker.conf` file:
+
+```conf
+# When a namespace is created without specifying the number of bundles, this
+# value will be used as the default
+defaultNumberOfNamespaceBundles=4
+```
+
+Alternatively, you can override the value when you create a new namespace using [Pulsar admin](/tools/pulsar-admin/):
+
+```shell
+bin/pulsar-admin namespaces create my-tenant/my-namespace --clusters us-west --bundles 16
+```
+
+With the above command, you create a namespace with 16 initial bundles. Therefore the topics for this namespace can immediately be spread across up to 16 brokers.
+
+In general, if you know the expected traffic and number of topics in advance, you had better start with a reasonable number of bundles instead of waiting for the system to auto-correct the distribution.
+
+On the same note, it is beneficial to start with more bundles than the number of brokers, due to the hashing nature of the distribution of topics into bundles. For example, for a namespace with 1000 topics, using something like 64 bundles achieves a good distribution of traffic across 16 brokers.
+
+
+## Split namespace bundles
+
+Since the load for the topics in a bundle might change over time and predicting the load might be hard, bundle split is designed to resolve these challenges. The broker splits a bundle into two and the new smaller bundles can be reassigned to different brokers.
+
+Pulsar supports the following two bundle split algorithms:
+* `range_equally_divide`: split the bundle into two parts with the same hash range size.
+* `topic_count_equally_divide`: split the bundle into two parts with the same number of topics.
+* `specified_positions_divide`: split the bundle into several parts by the specified positions.
+
+:::tip
+
+* The `specified_positions_divide` algorithms only support use by admin API and do not support set into `defaultNamespaceBundleSplitAlgorithm`.
+
+:::
+
+To enable bundle split, you need to configure the following settings in the `broker.conf` file, and set `defaultNamespaceBundleSplitAlgorithm` based on your needs.
+
+```conf
+loadBalancerAutoBundleSplitEnabled=true
+loadBalancerAutoUnloadSplitBundlesEnabled=true
+defaultNamespaceBundleSplitAlgorithm=range_equally_divide
+```
+
+You can configure more parameters for splitting thresholds. Any existing bundle that exceeds any of the thresholds is a candidate to be split. By default, the newly split bundles are immediately reassigned to other brokers, to facilitate the traffic distribution.
+
+```conf
+# maximum topics in a bundle, otherwise bundle split will be triggered
+loadBalancerNamespaceBundleMaxTopics=1000
+
+# maximum sessions (producers + consumers) in a bundle, otherwise bundle split will be triggered
+loadBalancerNamespaceBundleMaxSessions=1000
+
+# maximum msgRate (in + out) in a bundle, otherwise bundle split will be triggered
+loadBalancerNamespaceBundleMaxMsgRate=30000
+
+# maximum bandwidth (in + out) in a bundle, otherwise bundle split will be triggered
+loadBalancerNamespaceBundleMaxBandwidthMbytes=100
+
+# maximum number of bundles in a namespace (for auto-split)
+loadBalancerNamespaceMaximumBundles=128
+```
+
+## Shed load automatically
+
+The support for automatic load shedding is available in the load manager of Pulsar. This means that whenever the system recognizes a particular broker is overloaded, the system forces some traffic to be reassigned to less-loaded brokers.
+
+When a broker is identified as overloaded, the broker forces to "unload" a subset of the bundles, the ones with higher traffic, that make up for the overload percentage.
+
+For example, the default threshold is 85% and if a broker is over quota at 95% CPU usage, then the broker unloads the percent difference plus a 5% margin: `(95% - 85%) + 5% = 15%`. Given the selection of bundles to unload is based on traffic (as a proxy measure for CPU, network, and memory), the broker unloads bundles for at least 15% of traffic.
+
+:::tip
+
+* The automatic load shedding is enabled by default. To disable it, you can set `loadBalancerSheddingEnabled` to `false`.
+* Besides the automatic load shedding, you can [manually unload bundles](#unload-topics-and-bundles).
+
+:::
+
+Additional settings that apply to shedding:
+
+```conf
+# Load shedding interval. Broker periodically checks whether some traffic should be offload from
+# some over-loaded broker to other under-loaded brokers
+loadBalancerSheddingIntervalMinutes=1
+
+# Prevent the same topics to be shed and moved to other brokers more than once within this timeframe
+loadBalancerSheddingGracePeriodMinutes=30
+```
+
+Pulsar supports the following types of automatic load shedding strategies.
+* [ThresholdShedder](#thresholdshedder)
+* [OverloadShedder](#overloadshedder)
+* [UniformLoadShedder](#uniformloadshedder)
+
+:::note
+
+* From Pulsar 2.10, the **default** shedding strategy is `ThresholdShedder`.
+* You need to restart brokers if the shedding strategy is [dynamically updated](admin-api-brokers.md#dynamic-broker-configuration).
+
+:::
+
+### ThresholdShedder
+
+This strategy tends to shed the bundles if any broker's usage is above the configured threshold. It does this by first computing the average resource usage per broker for the whole cluster. The resource usage for each broker is calculated using the following method `LocalBrokerData#getMaxResourceUsageWithWeight`. Historical observations are included in the running average based on the broker's setting for `loadBalancerHistoryResourcePercentage`. Once the average resource usage is calcula [...]
+
+
+
+For example, assume you have three brokers, the average broker usage of broker1 is 40%, the average broker usage of broker2 and broker3 is 10%, then the cluster average usage is 20% ((40% + 10% + 10%) / 3). If you set `loadBalancerBrokerThresholdShedderPercentage` to `10`, then only broker1's certain bundles get unloaded, because the average usage of broker1 is greater than the sum of the cluster average usage (20%) plus `loadBalancerBrokerThresholdShedderPercentage`(10%).
+
+However, in some special cases, the above default strategy cannot leverage the resources of low-load or idle machines.
+
+For example:
+
+There are 11 brokers, of which 10 are loaded at 80% and 1 is loaded at 0%.
+The average load is 80% * 10 / 11 = 72.73%, and the threshold to unload is 72.73% + 10% = 82.73%.
+Since 80% < 82.73%, unload will not be triggered, and there is one idle Broker with load of 0%.
+
+To leverage the resources of low-load or idle machines, you can configure the `lowerBoundarySheddingEnabled` parameter on top of `ThresholdShedder`.
+When `lowerBoundarySheddingEnabled` is set to `true`, a leader decides the lower boundary of the load.
+If `current usage` is less than `average usage - lower boundary load`, e.g., 0% < (82.73% - 10%), the broker with the highest load will be triggered to unload.
+
+To use the `ThresholdShedder` strategy, configure brokers with this value.
+`loadBalancerLoadSheddingStrategy=org.apache.pulsar.broker.loadbalance.impl.ThresholdShedder`
+
+You can configure the weights for each resource per broker in the `conf/broker.conf` file.
+
+```conf
+# The BandWithIn usage weight when calculating new resource usage. The range is between 0 and 1.0.
+loadBalancerBandwithInResourceWeight=1.0
+
+# The BandWithOut usage weight when calculating new resource usage. The range is between 0 and 1.0.
+loadBalancerBandwithOutResourceWeight=1.0
+
+# The CPU usage weight when calculating new resource usage. The range is between 0 and 1.0.
+loadBalancerCPUResourceWeight=1.0
+
+# The heap memory usage weight when calculating new resource usage. The range is between 0 and 1.0.
+loadBalancerMemoryResourceWeight=1.0
+
+# The direct memory usage weight when calculating new resource usage. The range is between 0 and 1.0.
+loadBalancerDirectMemoryResourceWeight=1.0
+```
+
+### OverloadShedder
+This strategy attempts to shed exactly one bundle on brokers which are overloaded, that is, whose maximum system resource usage exceeds [`loadBalancerBrokerOverloadedThresholdPercentage`](#broker-overload-thresholds). To see which resources are considered when determining the maximum system resource. A bundle is recommended for unloading off that broker if and only if the following conditions hold: The broker has at least two bundles assigned and the broker has at least one bundle that h [...]
+
+
+
+To use the `OverloadShedder` strategy, configure brokers with this value.
+`loadBalancerLoadSheddingStrategy=org.apache.pulsar.broker.loadbalance.impl.OverloadShedder`
+
+#### Broker overload thresholds
+
+The determination of when a broker is overloaded is based on the threshold of CPU, network, and memory usage. Whenever either of those metrics reaches the threshold, the system triggers the shedding (if enabled).
+
+:::note
+
+The overload threshold `loadBalancerBrokerOverloadedThresholdPercentage` only applies to the [`OverloadShedder`](#overloadshedder) shedding strategy. By default, it is set to 85%.
+
+:::
+
+Pulsar gathers the CPU, network, and memory usage stats from the system metrics. In some cases of network utilization, the network interface speed that Linux reports is not correct and needs to be manually overridden. This is the case in AWS EC2 instances with 1Gbps NIC speed for which the OS reports 10Gbps speed.
+
+Because of the incorrect max speed, the load manager might think the broker has not reached the NIC capacity, while in fact the broker already uses all the bandwidth and the traffic is slowed down.
+
+You can set `loadBalancerOverrideBrokerNicSpeedGbps` in the `conf/broker.conf` file to correct the max NIC speed. When the value is empty, Pulsar uses the value that the OS reports.
+
+### UniformLoadShedder
+This strategy tends to distribute load uniformly across all brokers. This strategy checks the load difference between the broker with the highest load and the broker with the lowest load. If the difference is higher than configured thresholds `loadBalancerMsgRateDifferenceShedderThreshold` and `loadBalancerMsgThroughputMultiplierDifferenceShedderThreshold` then it finds out bundles that can be unloaded to distribute traffic evenly across all brokers.
+
+
+
+To use the `UniformLoadShedder` strategy, configure brokers with this value.
+`loadBalancerLoadSheddingStrategy=org.apache.pulsar.broker.loadbalance.impl.UniformLoadShedder`
+
+## Unload topics and bundles
+
+You can "unload" a topic in Pulsar manual admin operations. Unloading means closing topics, releasing ownership, and reassigning topics to a new broker, based on the current load.
+
+When unloading happens, the client experiences a small latency blip, typically in the order of tens of milliseconds, while the topic is reassigned.
+
+Unloading is the mechanism that the load manager uses to perform the load shedding, but you can also trigger the unloading manually, for example, to correct the assignments and redistribute traffic even before having any broker overloaded.
+
+Unloading a topic has no effect on the assignment, but just closes and reopens the particular topic:
+
+```shell
+pulsar-admin topics unload persistent://tenant/namespace/topic
+```
+
+To unload all topics for a namespace and trigger reassignments:
+
+```shell
+pulsar-admin namespaces unload tenant/namespace
+```
+
+## Distribute anti-affinity namespaces across failure domains
+
+When your application has multiple namespaces and you want one of them available all the time to avoid any downtime, you can group these namespaces and distribute them across different [failure domains](reference-terminology.md#failure-domain) and different brokers. Thus, if one of the failure domains is down (due to release rollout or brokers restart), it only disrupts namespaces owned by that specific failure domain and the rest of the namespaces owned by other domains remain available [...]
+
+Such a group of namespaces has anti-affinity to each other, that is, all the namespaces in this group are [anti-affinity namespaces](reference-terminology.md#anti-affinity-namespaces) and are distributed to different failure domains in a load-balanced manner.
+
+As illustrated in the following figure, Pulsar has 2 failure domains (Domain1 and Domain2) and each domain has 2 brokers in it. You can create an anti-affinity namespace group that has 4 namespaces in it, and all the 4 namespaces have anti-affinity to each other. The load manager tries to distribute namespaces evenly across all the brokers in the same domain. Since each domain has 2 brokers, every broker owns one namespace from this anti-affinity namespace group, and you can see each dom [...]
+
+
+
+The load manager follows an even distribution policy across failure domains to assign anti-affinity namespaces. The following table outlines the even-distributed assignment sequence illustrated in the above figure.
+
+| Assignment sequence | Namespace | Failure domain candidates | Broker candidates | Selected broker |
+|:---|:------------|:------------------|:------------------------------------|:-----------------|
+| 1 | Namespace1 | Domain1, Domain2 | Broker1, Broker2, Broker3, Broker4 | Domain1:Broker1 |
+| 2 | Namespace2 | Domain2 | Broker3, Broker4 | Domain2:Broker3 |
+| 3 | Namespace3 | Domain1, Domain2 | Broker2, Broker4 | Domain1:Broker2 |
+| 4 | Namespace4 | Domain2 | Broker4 | Domain2:Broker4 |
+
+:::tip
+
+* Each namespace belongs to only one anti-affinity group. If a namespace with an existing anti-affinity assignment is assigned to another anti-affinity group, the original assignment is dropped.
+
+* If there are more anti-affinity namespaces than failure domains, the load manager distributes namespaces evenly across all the domains, and also every domain distributes namespaces evenly across all the brokers under that domain.
+
+:::
+
+### Create a failure domain and register brokers
+
+:::note
+
+One broker can only be registered to a single failure domain.
+
+:::
+
+To create a domain under a specific cluster and register brokers, run the following command:
+
+```bash
+pulsar-admin clusters create-failure-domain <cluster-name> --domain-name <domain-name> --broker-list <broker-list-comma-separated>
+```
+
+You can also view, update, and delete domains under a specific cluster. For more information, refer to [Pulsar admin doc](/tools/pulsar-admin/).
+
+### Create an anti-affinity namespace group
+
+An anti-affinity group is created automatically when the first namespace is assigned to the group. To assign a namespace to an anti-affinity group, run the following command. It sets an anti-affinity group name for a namespace.
+
+```bash
+pulsar-admin namespaces set-anti-affinity-group <namespace> --group <group-name>
+```
+
+For more information about `anti-affinity-group` related commands, refer to [Pulsar admin doc](/tools/pulsar-admin/).
diff --git a/versioned_docs/version-2.11.0/administration-metadata-store.md b/versioned_docs/version-2.11.0/administration-metadata-store.md
new file mode 100644
index 00000000000..eef1603854e
--- /dev/null
+++ b/versioned_docs/version-2.11.0/administration-metadata-store.md
@@ -0,0 +1,110 @@
+---
+id: administration-metadata-store
+title: Configure metadata store
+sidebar_label: "Configure metadata store"
+---
+
+Pulsar metadata store maintains all the metadata, configuration, and coordination of a Pulsar cluster, such as topic metadata, schema, broker load data, and so on.
+
+The metadata store of each Pulsar instance should contain the following two components:
+* A local metadata store ensemble (`metadataStoreUrl`) that stores cluster-specific configuration and coordination, such as which brokers are responsible for which topics as well as ownership metadata, broker load reports, and BookKeeper ledger metadata.
+* A configuration store quorum (`configurationMetadataStoreUrl`) stores configuration for clusters, tenants, namespaces, topics, and other entities that need to be globally consistent.
+
+:::note
+
+If you are using a standalone Pulsar or a single Pulsar cluster, you only need to configure one metadata store (via `metadataStoreUrl`) and it also serves as a configuration store.
+
+:::
+
+Pulsar supports the following metadata store services:
+* [Apache ZooKeeper](https://zookeeper.apache.org/)
+* [Etcd](https://etcd.io/)
+* [RocksDB](http://rocksdb.org/)
+* Local memory
+
+:::note
+
+RocksDB and local memory are only applicable to standalone Pulsar or single-node Pulsar clusters.
+
+:::
+
+## Use ZooKeeper as metadata store
+
+Pulsar metadata store can be deployed on a separate ZooKeeper cluster or deployed on an existing ZooKeeper cluster.
+
+To use ZooKeeper as the metadata store, add the following parameters to the `conf/broker.conf` or `conf/standalone.conf` file.
+
+```conf
+metadataStoreUrl=zk:my-zk-1:2181,my-zk-2:2181,my-zk-3:2181
+configurationMetadataStoreUrl=zk:my-global-zk-1:2181,my-global-zk-2:2181,my-global-zk-3:2181
+```
+
+## Use etcd as metadata store
+
+To use etcd as the metadata store, add the following parameters to the `conf/broker.conf` or `conf/standalone.conf` file.
+
+```conf
+metadataStoreUrl=etcd:http://my-etcd-1:2379,http://my-etcd-2:2379,http://my-etcd-3:2379
+configurationMetadataStoreUrl=etcd:my-global-etcd-1:2379,my-global-etcd-2:2379,my-global-etcd-3:2379
+# metadataStoreConfigPath=/path/to/file
+```
+
+:::tip
+
+The `metadataStoreConfigPath` parameter is required when you want to use the following advanced configurations.
+
+```
+useTls=false
+tlsProvider=JDK
+tlsTrustCertsFilePath=
+tlsKeyFilePath=
+tlsCertificateFilePath=
+authority=
+```
+
+:::
+
+## Use RocksDB as metadata store
+
+To use RocksDB as the metadata store, add the following parameters to the `conf/broker.conf` or `conf/standalone.conf` file.
+
+```conf
+metadataStoreUrl=rocksdb://data/metadata
+# metadataStoreConfigPath=/path/to/file
+```
+
+:::tip
+
+The `metadataStoreConfigPath` parameter is required when you want to use advanced configurations. See [this example](https://github.com/facebook/rocksdb/blob/main/examples/rocksdb_option_file_example.ini) for more information.
+
+:::
+
+## Use local memory as metadata store
+
+To use local memory as the metadata store, add the following parameters to the `conf/broker.conf` or `conf/standalone.conf` file.
+
+```conf
+metadataStoreUrl=memory://local
+```
+
+
+## Enable batch operations on metadata store
+
+Pulsar metadata store supports batch operations and caching to meet low latency and high throughput and improve performance.
+
+To enable batch operations on the metadata store, you can configure the following parameters in the `conf/broker.conf` or `conf/standalone.conf` file.
+
+```conf
+# Whether we should enable metadata operations batching
+metadataStoreBatchingEnabled=true
+
+# Maximum delay to impose on batching grouping
+metadataStoreBatchingMaxDelayMillis=5
+
+# Maximum number of operations to include in a singular batch
+metadataStoreBatchingMaxOperations=1000
+
+# Maximum size of a batch
+metadataStoreBatchingMaxSizeKb=128
+```
+
diff --git a/versioned_docs/version-2.11.0/administration-proxy.md b/versioned_docs/version-2.11.0/administration-proxy.md
new file mode 100644
index 00000000000..5a4eae023ba
--- /dev/null
+++ b/versioned_docs/version-2.11.0/administration-proxy.md
@@ -0,0 +1,123 @@
+---
+id: administration-proxy
+title: Pulsar proxy
+sidebar_label: "Pulsar proxy"
+---
+
+Pulsar proxy is an optional gateway. Pulsar proxy is used when direct connections between clients and Pulsar brokers are either infeasible or undesirable. For example, when you run Pulsar in a cloud environment or on [Kubernetes](https://kubernetes.io) or an analogous platform, you can run Pulsar proxy.
+
+The Pulsar proxy is not intended to be exposed on the public internet. The security considerations in the current design expect network perimeter security. The requirement of network perimeter security can be achieved with private networks.
+
+If a proxy deployment cannot be protected with network perimeter security, the alternative would be to use [Pulsar's "Proxy SNI routing" feature](concepts-proxy-sni-routing.md) with a properly secured and audited solution. In that case Pulsar proxy component is not used at all.
+
+## Configure the proxy
+
+Before using a proxy, you need to configure it with a broker's address in the cluster. You can configure the broker URL in the proxy configuration, or the proxy to connect directly using service discovery.
+
+> In a production environment service discovery is not recommended.
+
+### Use broker URLs
+
+It is more secure to specify a URL to connect to the brokers.
+
+Proxy authorization requires access to ZooKeeper, so if you use these broker URLs to connect to the brokers, you need to disable authorization at the Proxy level. Brokers still authorize requests after the proxy forwards them.
+
+You can configure the broker URLs in `conf/proxy.conf` as follows.
+
+```properties
+brokerServiceURL=pulsar://brokers.example.com:6650
+brokerWebServiceURL=http://brokers.example.com:8080
+functionWorkerWebServiceURL=http://function-workers.example.com:8080
+```
+
+If you use TLS, configure the broker URLs in the following way:
+
+```properties
+brokerServiceURLTLS=pulsar+ssl://brokers.example.com:6651
+brokerWebServiceURLTLS=https://brokers.example.com:8443
+functionWorkerWebServiceURL=https://function-workers.example.com:8443
+```
+
+The hostname in the URLs provided should be a DNS entry that points to multiple brokers or a virtual IP address, which is backed by multiple broker IP addresses, so that the proxy does not lose connectivity to Pulsar cluster if a single broker becomes unavailable.
+
+The ports to connect to the brokers (6650 and 8080, or in the case of TLS, 6651 and 8443) should be open in the network ACLs.
+
+Note that if you do not use functions, you do not need to configure `functionWorkerWebServiceURL`.
+
+### Use service discovery
+
+Pulsar uses [ZooKeeper](https://zookeeper.apache.org) for service discovery. To connect the proxy to ZooKeeper, specify the following in `conf/proxy.conf`.
+
+```properties
+metadataStoreUrl=my-zk-0:2181,my-zk-1:2181,my-zk-2:2181
+configurationMetadataStoreUrl=my-zk-0:2184,my-zk-remote:2184
+```
+
+> To use service discovery, you need to open the network ACLs, so the proxy can connects to the ZooKeeper nodes through the ZooKeeper client port (port `2181`) and the configuration store client port (port `2184`).
+
+> However, it is not secure to use service discovery. Because if the network ACL is open, when someone compromises a proxy, they have full access to ZooKeeper.
+
+### Restricting target broker addresses to mitigate CVE-2022-24280
+
+The Pulsar Proxy trusts clients to provide valid target broker addresses to connect to.
+Unless the Pulsar Proxy is explicitly configured to limit access, the Pulsar Proxy is vulnerable as described in the security advisory [Apache Pulsar Proxy target broker address isn't validated (CVE-2022-24280)](https://github.com/apache/pulsar/wiki/CVE-2022-24280).
+
+It is necessary to limit proxied broker connections to known broker addresses by specifying `brokerProxyAllowedHostNames` and `brokerProxyAllowedIPAddresses` settings.
+
+When specifying `brokerProxyAllowedHostNames`, it's possible to use a wildcard.
+Please notice that `*` is a wildcard that matches any character in the hostname. It also matches dot `.` characters.
+
+It is recommended to use a pattern that matches only the desired brokers and no other hosts in the local network. Pulsar lookups will use the default host name of the broker by default. This can be overridden with the `advertisedAddress` setting in `broker.conf`.
+
+To increase security, it is also possible to restrict access with the `brokerProxyAllowedIPAddresses` setting. It is not mandatory to configure `brokerProxyAllowedIPAddresses` when `brokerProxyAllowedHostNames` is properly configured so that the pattern matches only the target brokers.
+`brokerProxyAllowedIPAddresses` setting supports a comma separate list of IP address, IP address ranges and IP address networks [(supported format reference)](https://seancfoley.github.io/IPAddress/IPAddress/apidocs/inet/ipaddr/IPAddressString.html).
+
+Example: limiting by host name in a Kubernetes deployment
+```yaml
+ # example of limiting to Kubernetes statefulset hostnames that contain "broker-"
+ PULSAR_PREFIX_brokerProxyAllowedHostNames: '*broker-*.*.*.svc.cluster.local'
+```
+
+Example: limiting by both host name and ip address in a `proxy.conf` file for host deployment.
+```properties
+# require "broker" in host name
+brokerProxyAllowedHostNames=*broker*.localdomain
+# limit target ip addresses to a specific network
+brokerProxyAllowedIPAddresses=10.0.0.0/8
+```
+
+Example: limiting by multiple host name patterns and multiple ip address ranges in a `proxy.conf` file for host deployment.
+```properties
+# require "broker" in host name
+brokerProxyAllowedHostNames=*broker*.localdomain,*broker*.otherdomain
+# limit target ip addresses to a specific network or range demonstrating multiple supported formats
+brokerProxyAllowedIPAddresses=10.10.0.0/16,192.168.1.100-120,172.16.2.*,10.1.2.3
+```
+
+
+## Start the proxy
+
+To start the proxy:
+
+```bash
+cd /path/to/pulsar/directory
+bin/pulsar proxy \
+ --metadata-store zk:my-zk-1:2181,my-zk-2:2181,my-zk-3:2181 \
+ --configuration-metadata-store zk:my-zk-1:2181,my-zk-2:2181,my-zk-3:2181
+```
+
+> You can run multiple instances of the Pulsar proxy in a cluster.
+
+## Stop the proxy
+
+Pulsar proxy runs in the foreground by default. To stop the proxy, simply stop the process in which the proxy is running.
+
+## Proxy frontends
+
+You can run Pulsar proxy behind some kind of load-distributing frontend, such as an [HAProxy](https://www.digitalocean.com/community/tutorials/an-introduction-to-haproxy-and-load-balancing-concepts) load balancer.
+
+## Use Pulsar clients with the proxy
+
+Once your Pulsar proxy is up and running, preferably behind a load-distributing [frontend](#proxy-frontends), clients can connect to the proxy via whichever address that the frontend uses. If the address is the DNS address `pulsar.cluster.default`, for example, the connection URL for clients is `pulsar://pulsar.cluster.default:6650`.
+
+For more information on Proxy configuration, refer to [Pulsar proxy](reference-configuration.md#pulsar-proxy).
diff --git a/versioned_docs/version-2.11.0/administration-pulsar-manager.md b/versioned_docs/version-2.11.0/administration-pulsar-manager.md
new file mode 100644
index 00000000000..1b46f053e1b
--- /dev/null
+++ b/versioned_docs/version-2.11.0/administration-pulsar-manager.md
@@ -0,0 +1,183 @@
+---
+id: administration-pulsar-manager
+title: Pulsar Manager
+sidebar_label: "Pulsar Manager"
+---
+
+Pulsar Manager is a web-based GUI management and monitoring tool that helps administrators and users manage and monitor tenants, namespaces, topics, subscriptions, brokers, clusters, and so on, and supports dynamic configuration of multiple environments.
+
+## Install
+
+### Quick Install
+The easiest way to use the Pulsar Manager is to run it inside a [Docker](https://www.docker.com/products/docker) container.
+
+```shell
+docker pull apachepulsar/pulsar-manager:v0.3.0
+docker run -it \
+ -p 9527:9527 -p 7750:7750 \
+ -e SPRING_CONFIGURATION_FILE=/pulsar-manager/pulsar-manager/application.properties \
+ apachepulsar/pulsar-manager:v0.3.0
+```
+
+* Pulsar Manager is divided into front-end and back-end, the front-end service port is `9527` and the back-end service port is `7750`.
+* `SPRING_CONFIGURATION_FILE`: Default configuration file for spring.
+* By default, Pulsar Manager uses the `herddb` database. HerdDB is a SQL distributed database implemented in Java and can be found at [herddb.org](https://herddb.org/) for more information.
+
+### Configure Database or JWT authentication
+#### Configure Database (optional)
+
+If you have a large amount of data, you can use a custom database. Otherwise, some display errors may occur. For example, the topic information cannot be displayed when the topic exceeds 10000.
+The following is an example of PostgreSQL.
+
+1. Initialize database and table structures using the [file](https://github.com/apache/pulsar-manager/blob/master/src/main/resources/META-INF/sql/postgresql-schema.sql).
+2. Download and modify the [configuration file](https://github.com/apache/pulsar-manager/blob/master/src/main/resources/application.properties), then add the PostgreSQL configuration.
+
+```properties
+spring.datasource.driver-class-name=org.postgresql.Driver
+spring.datasource.url=jdbc:postgresql://127.0.0.1:5432/pulsar_manager
+spring.datasource.username=postgres
+spring.datasource.password=postgres
+```
+
+3. Add a configuration mount and start with a docker image.
+
+```bash
+docker pull apachepulsar/pulsar-manager:v0.3.0
+docker run -it \
+ -p 9527:9527 -p 7750:7750 \
+ -v /your-path/application.properties:/pulsar-manager/pulsar-manager/application.properties
+ -e SPRING_CONFIGURATION_FILE=/pulsar-manager/pulsar-manager/application.properties \
+ apachepulsar/pulsar-manager:v0.3.0
+```
+
+#### Enable JWT authentication (optional)
+
+If you want to turn on JWT authentication, configure the `application.properties` file.
+
+```properties
+backend.jwt.token=token
+
+jwt.broker.token.mode=PRIVATE
+jwt.broker.public.key=file:///path/broker-public.key
+jwt.broker.private.key=file:///path/broker-private.key
+
+or
+jwt.broker.token.mode=SECRET
+jwt.broker.secret.key=file:///path/broker-secret.key
+```
+
+* `backend.jwt.token`: token for the superuser. You need to configure this parameter during cluster initialization.
+* `jwt.broker.token.mode`: multiple modes of generating tokens, including PUBLIC, PRIVATE, and SECRET.
+* `jwt.broker.public.key`: configure this option if you use the PUBLIC mode.
+* `jwt.broker.private.key`: configure this option if you use the PRIVATE mode.
+* `jwt.broker.secret.key`: configure this option if you use the SECRET mode.
+For more information, see [Token Authentication Admin of Pulsar](security-token-admin.md).
+
+Docker command to add profile and key files mount.
+
+```bash
+docker pull apachepulsar/pulsar-manager:v0.3.0
+docker run -it \
+ -p 9527:9527 -p 7750:7750 \
+ -v /your-path/application.properties:/pulsar-manager/pulsar-manager/application.properties
+ -v /your-path/private.key:/pulsar-manager/private.key
+ -e SPRING_CONFIGURATION_FILE=/pulsar-manager/pulsar-manager/application.properties \
+ apachepulsar/pulsar-manager:v0.3.0
+```
+
+### Set the administrator account and password
+
+```bash
+CSRF_TOKEN=$(curl http://localhost:7750/pulsar-manager/csrf-token)
+curl \
+ -H 'X-XSRF-TOKEN: $CSRF_TOKEN' \
+ -H 'Cookie: XSRF-TOKEN=$CSRF_TOKEN;' \
+ -H "Content-Type: application/json" \
+ -X PUT http://localhost:7750/pulsar-manager/users/superuser \
+ -d '{"name": "admin", "password": "apachepulsar", "description": "test", "email": "username@test.org"}'
+```
+
+The request parameter in curl command:
+
+```json
+{"name": "admin", "password": "apachepulsar", "description": "test", "email": "username@test.org"}
+```
+
+- `name` is the Pulsar Manager login username, currently `admin`.
+- `password` is the password of the current user of Pulsar Manager, currently `apachepulsar`. The password should be more than or equal to 6 digits.
+
+
+### Configure the environment
+
+1. Login to the system, Visit http://localhost:9527 to login. The current default account is `admin/apachepulsar`
+
+2. Click "New Environment" button to add an environment.
+
+3. Input the "Environment Name". The environment name is used for identifying an environment.
+
+4. Input the "Service URL". The Service URL is the admin service URL of your Pulsar cluster.
+
+
+## Other Installation
+### Bare-metal installation
+
+When using binary packages for direct deployment, you can follow these steps.
+
+- Download and unzip the binary package, which is available on the [Pulsar Download](/download/) page.
+
+ ```bash
+ wget https://dist.apache.org/repos/dist/release/pulsar/pulsar-manager/pulsar-manager-0.3.0/apache-pulsar-manager-0.3.0-bin.tar.gz
+ tar -zxvf apache-pulsar-manager-0.3.0-bin.tar.gz
+ ```
+
+- Extract the back-end service binary package and place the front-end resources in the back-end service directory.
+
+ ```bash
+ cd pulsar-manager
+ tar -zxvf pulsar-manager.tar
+ cd pulsar-manager
+ cp -r ../dist ui
+ ```
+
+- Modify `application.properties` configuration on demand.
+
+ > If you don't want to modify the `application.properties` file, you can add the configuration to the startup parameters via `. /bin/pulsar-manager --backend.jwt.token=token` to add the configuration to the startup parameters. This is a capability of the spring boot framework.
+
+- Start Pulsar Manager
+
+ ```bash
+ ./bin/pulsar-manager
+ ```
+
+### Custom docker image installation
+
+You can find the docker image in the [Docker Hub](https://github.com/apache/pulsar-manager/tree/master/docker) directory and build an image from the source code as well:
+
+ ```bash
+ git clone https://github.com/apache/pulsar-manager
+ cd pulsar-manager/front-end
+ npm install --save
+ npm run build:prod
+ cd ..
+ ./gradlew build -x test
+ cd ..
+ docker build -f docker/Dockerfile --build-arg BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` --build-arg VCS_REF=`latest` --build-arg VERSION=`latest` -t apachepulsar/pulsar-manager .
+ ```
+
+## Configuration
+
+| application.properties | System env on Docker Image | Desc | Example |
+| ----------------------------------- | -------------------------- | ------------------------------------------------------------ | ------------------------------------------------- |
+| backend.jwt.token | JWT_TOKEN | token for the superuser. You need to configure this parameter during cluster initialization. | `token` |
+| jwt.broker.token.mode | N/A | multiple modes of generating token, including PUBLIC, PRIVATE, and SECRET. | `PUBLIC` or `PRIVATE` or `SECRET`. |
+| jwt.broker.public.key | PUBLIC_KEY | configure this option if you use the PUBLIC mode. | `file:///path/broker-public.key` |
+| jwt.broker.private.key | PRIVATE_KEY | configure this option if you use the PRIVATE mode. | `file:///path/broker-private.key` |
+| jwt.broker.secret.key | SECRET_KEY | configure this option if you use the SECRET mode. | `file:///path/broker-secret.key` |
+| spring.datasource.driver-class-name | DRIVER_CLASS_NAME | the driver class name of the database. | `org.postgresql.Driver` |
+| spring.datasource.url | URL | the JDBC URL of your database. | `jdbc:postgresql://127.0.0.1:5432/pulsar_manager` |
+| spring.datasource.username | USERNAME | the username of database. | `postgres` |
+| spring.datasource.password | PASSWORD | the password of database. | `postgres` |
+| N/A | LOG_LEVEL | the level of log. | DEBUG |
+* For more information about backend configurations, see [here](https://github.com/apache/pulsar-manager/blob/master/src/README).
+* For more information about frontend configurations, see [here](https://github.com/apache/pulsar-manager/tree/master/front-end).
+
diff --git a/versioned_docs/version-2.11.0/administration-pulsar-shell.md b/versioned_docs/version-2.11.0/administration-pulsar-shell.md
new file mode 100644
index 00000000000..cbbb548457e
--- /dev/null
+++ b/versioned_docs/version-2.11.0/administration-pulsar-shell.md
@@ -0,0 +1,174 @@
+---
+id: administration-pulsar-shell
+title: Pulsar Shell
+sidebar_label: "Pulsar Shell"
+---
+
+````mdx-code-block
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+````
+
+
+Pulsar shell is a fast and flexible shell for Pulsar cluster management, messaging, and more.
+It's great for quickly switching between different clusters, and can modify cluster or tenant configurations in an instant.
+
+
+## Use case
+- Administration: find all the [Admin API](admin-api-overview.md) features under the `admin` command.
+- Client: find all the [pulsar-client](reference-cli-tools#pulsar-client.md) features under the `client` command.
+
+
+## Install Pulsar Shell
+Download the tarball from the [download page](https://pulsar.apache.org/download) and extract it.
+
+```shell
+wget https://archive.apache.org/dist/pulsar/pulsar-@pulsar:version@/apache-pulsar-shell-@pulsar:version@-bin.tar.gz
+tar xzvf apache-pulsar-shell-@pulsar:version@-bin.tar.gz
+cd apache-pulsar-shell-@pulsar:version@-bin.tar.gz
+```
+
+Now you can enter Pulsar shell's interactive mode:
+
+```shell
+./bin/pulsar-shell
+Welcome to Pulsar shell!
+ Service URL: pulsar://localhost:6650/
+ Admin URL: http://localhost:8080/
+
+Type help to get started or try the autocompletion (TAB button).
+Type exit or quit to end the shell session.
+
+default(localhost)>
+```
+
+
+## Connect to your cluster
+
+By default, the shell tries to connect to a local Pulsar instance.
+To connect to a different cluster, you have to register the cluster with Pulsar shell. You can do this in a few different ways depending on where your config file is located:
+
+:::note
+
+The configuration file must be a valid `client.conf` file, the same one you use for `pulsar-admin`, `pulsar-client` and other client tools.
+
+:::
+
+````mdx-code-block
+<Tabs groupId="shell-config-modes"
+ defaultValue="url"
+ values={[{"label":"Remote URL","value":"url"},{"label":"File","value":"file"},{"label":"Inline","value":"inline"}]}>
+<TabItem value="url">
+
+
+The `--url` value must point to a valid remote file.
+
+```
+default(localhost)> config create --url https://<url_to_my_client.conf> mycluster
+```
+
+</TabItem>
+<TabItem value="file">
+
+If the file is on your local machine, use the `--file` option.
+
+
+```
+default(localhost)> config create --file ./my-cluster-my-client.conf mycluster
+```
+
+</TabItem>
+<TabItem value="inline">
+
+You can encode the content of the config to base64 and specify it with the `--value` option.
+
+```
+default(localhost)> config create --value "base64:<client.conf_base64_encoded>" mycluster
+```
+
+
+</TabItem>
+
+</Tabs>
+````
+
+
+Once you've configured your cluster, set it as current:
+
+```
+default(localhost)> config use mycluster
+Welcome to Pulsar shell!
+ Service URL: pulsar+ssl://mycluster:6651/
+ Admin URL: https://mycluster:8443/
+
+Type help to get started or try the autocompletion (TAB button).
+Type exit or quit to end the shell session.
+
+my-cluster(mycluster)>
+```
+
+
+## Run commands sequentially
+To run a bunch of admin commands sequentially, you can use Pulsar shell's non-interactive mode.
+For example, to set up a new tenant with policies, you would normally need to run multiple `pulsar-admin` commands.
+
+Let's say you want to create a new tenant `new-tenant` with a namespace `new-namespace` in it.
+There are multiple ways to do this with Pulsar shell non-interactive mode:
+
+````mdx-code-block
+<Tabs groupId="shell-noninteractive-modes"
+ defaultValue="single-command"
+ values={[{"label":"Single command","value":"single-command"},{"label":"File","value":"file"},{"label":"Unix pipe","value":"pipe"}]}>
+<TabItem value="single-command">
+
+Specify a multi-line command with the `-e` option.
+
+```shell
+./bin/pulsar-shell -e "
+config use my-cluster
+admin tenants create new-tenant
+admin namespaces create new-tenant/new-namespace
+" --fail-on-error
+```
+
+</TabItem>
+<TabItem value="file">
+
+Specify a file command with the `-f` option.
+
+
+```shell
+echo "
+# First use my-cluster config
+config use my-cluster
+# Now it creates a new tenant
+admin tenants create new-tenant
+# And then it creates a new namespace inside the tenant
+admin namespaces create new-tenant/new-namespace
+" > setup-shell.txt
+
+./bin/pulsar-shell -f ./setup-shell.txt --fail-on-error
+```
+
+</TabItem>
+<TabItem value="pipe">
+
+Make the shell read from the standard input `-` option.
+
+```shell
+
+echo "
+# First use my-cluster config
+config use my-cluster
+# Now it creates a new tenant
+admin tenants create new-tenant
+# And then it creates a new namespace inside the tenant
+admin namespaces create new-tenant/new-namespace
+" > ./bin/pulsar-shell --fail-on-error -
+
+```
+
+</TabItem>
+
+</Tabs>
+````
\ No newline at end of file
diff --git a/versioned_docs/version-2.11.0/administration-stats.md b/versioned_docs/version-2.11.0/administration-stats.md
new file mode 100644
index 00000000000..b1dfaa53524
--- /dev/null
+++ b/versioned_docs/version-2.11.0/administration-stats.md
@@ -0,0 +1,179 @@
+---
+id: administration-stats
+title: Pulsar stats
+sidebar_label: "Pulsar statistics"
+---
+
+## Topic stats
+
+The following table outlines the stats of a topic. For more details about how to get these stats, see [Get stats](admin-api-topics.md#get-stats).
+
+:::note
+
+All metrics below are *reset* to 0 upon broker restart, *except* gauges marked as "Not reset upon restart".
+
+:::
+
+
+| Stat | Description |
+|--------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------|
+| msgRateIn | The sum of all local and replication publishers' publish rates (message per second). |
+| msgThroughputIn | The sum of all local and replication publishers' publish rates (byte per second). |
+| msgRateOut | The sum of all local and replication consumers' dispatch rates (message per second). |
+| msgThroughputOut | The sum of all local and replication consumers' dispatch rates (byte per second). |
+| averageMsgSize | The average size (bytes) of messages published within the last interval. |
+| storageSize | The sum of the ledgers' storage size for this topic. The space used to store the messages for the topic. Not reset upon restart |
+| earliestMsgPublishTimeInBacklogs | The publish time of the earliest message in the backlog (in milliseconds). Not reset upon restart |
+| bytesInCounter | The total bytes published to the topic. |
+| msgInCounter | The total messages published to the topic. |
+| bytesOutCounter | The total bytes delivered to consumers. |
+| msgOutCounter | The total messages delivered to consumers. |
+| msgChunkPublished | The topics that have chunked messages published on it. |
+| backlogSize | The estimated total unconsumed or backlog size (in bytes). Not reset upon restart |
+| offloadedStorageSize | Space that is used to store the offloaded messages for the topic (in bytes). Not reset upon restart |
+| waitingPublishers | The number of publishers waiting in a queue in exclusive access mode. |
+| deduplicationStatus | The status of message deduplication for the topic. |
+| topicEpoch | The topic epoch or empty if not set. |
+| filteredEntriesCount | The count of skipped entries for the topic. |
+| nonContiguousDeletedMessagesRanges | The number of non-contiguous deleted messages ranges. |
+| nonContiguousDeletedMessagesRangesSerializedSize | The serialized size of non-contiguous deleted messages ranges. |
+| ownerBroker | The broker that owns this topic. |
+| [publishers](#producer-stats) | The list of all local publishers on the topic, ranging from zero to thousands. |
+| [subscriptions](#subscription-stats) | The list of all local subscriptions to the topic. |
+| [replication](#replication-stats) | This section gives the stats for cross-colo replication of this topic. |
+
+### Producer stats
+
+| Stat | Description |
+|--------------------|-------------------------------------------------------------------------------------|
+| producerId | The internal identifier for this producer on this topic. |
+| producerName | The internal identifier for this producer, generated by the client library. |
+| address | IP address and source port for the connection of this producer. |
+| connectedSince | The timestamp when this producer is created or reconnected last time. |
+| accessMode | The type of access to the topic that the producer requires. |
+| msgRateIn | The total rate of messages (message per second) published by this publisher. |
+| msgThroughputIn | The total throughput (byte per second) of the messages published by this publisher. |
+| averageMsgSize | The average message size in bytes from this publisher within the last interval. |
+| chunkedMessageRate | The total rate of chunked messages published by this publisher. |
+| clientVersion | The client library version of this producer. |
+| metadata | The metadata (key/value strings) associated with this publisher. |
+
+### Subscription stats
+
+| Stat | Description |
+|--------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| my-subscription | The name of this subscription. It is defined by the client. |
+| msgRateOut | The total rate of messages (message per second) delivered on this subscription. |
+| msgThroughputOut | The total throughput (byte per second) delivered on this subscription. |
+| msgBacklog | The number of messages in the subscription backlog. |
+| type | This subscription type. |
+| msgRateExpired | The rate at which messages are discarded instead of dispatched from this subscription due to TTL. |
+| lastExpireTimestamp | The timestamp of the last message expiration. |
+| lastConsumedFlowTimestamp | The timestamp of the last flow command received. |
+| lastConsumedTimestamp | The latest timestamp of all the consumed timestamps of the consumers. |
+| lastAckedTimestamp | The latest timestamp of all the acknowledged timestamps of the consumers. |
+| msgRateRedeliver | The total rate of messages redelivered on this subscription (message per second). |
+| chunkedMessageRate | The chunked message dispatch rate. |
+| earliestMsgPublishTimeInBacklog | The publish time of the earliest message in the backlog for the subscription (in milliseconds). Note that **this metric is not reset upon restart**. |
+| msgBacklogNoDelayed | The number of messages in the subscription backlog that do not contain the delay messages. |
+| blockedSubscriptionOnUnackedMsgs | The flag to verify if a subscription is blocked due to reaching the threshold of unacked messages. |
+| msgDelayed | The number of delayed messages that are currently tracked. |
+| unackedMessages | The number of unacknowledged messages for the subscription, where an unacknowledged message is one that has been sent to a consumer but not yet acknowledged. This field is only meaningful when using a subscription that tracks individual message acknowledgment. |
+| activeConsumerName | The name of the consumer that is active for single active consumer subscriptions (such as failover or exclusive). |
+| totalMsgExpired | The total messages expired on this subscription. |
+| lastMarkDeleteAdvancedTimestamp | The last `MarkDelete` position advanced timestamp. |
+| durable | Whether the subscription is durable or ephemeral (for example, from a reader). |
+| replicated | Mark that the subscription state is kept in sync across different regions. |
+| allowOutOfOrderDelivery | Whether out-of-order delivery is allowed on the Key_Shared subscription. |
+| keySharedMode | The options of the Key_Shared subscription mode include `AUTO_SPLIT` or `STICKY`. |
+| consumersAfterMarkDeletePosition | Get `recentJoinedConsumers` for the Key_Shared subscription. |
+| filterProcessedMsgCount | The number of messages processed by `EntryFilter`. |
+| filterAcceptedMsgCount | The number of messages accepted by `EntryFilter`. |
+| filterRejectedMsgCount | The number of messages rejected by `EntryFilter`. |
+| filterRescheduledMsgCount | The number of messages rescheduled by `EntryFilter`. |
+| bytesOutCounter | The total bytes delivered to a consumer. |
+| msgOutCounter | The total messages delivered to a consumer. |
+| backlogSize | The size of backlog for this subscription (in bytes). Note that **this metric is not reset upon restart**. |
+| nonContiguousDeletedMessagesRanges | The number of non-contiguous deleted messages ranges. |
+| nonContiguousDeletedMessagesRangesSerializedSize | The serialized size of non-contiguous deleted messages ranges. |
+| [consumers](#consumer-stats) | The list of connected consumers for this subscription. |
+
+### Consumer stats
+
+| Stat | Description |
+|------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| consumerName | Internal identifier for this consumer, generated by the client library. |
+| msgRateOut | The total rate of messages (message per second) delivered to the consumer. |
+| msgThroughputOut | The total throughput (byte per second) delivered to the consumer. |
+| availablePermits | The number of messages that the consumer has space for in the client library's listening queue. `0` means the client library's queue is full and `receive()` isn't called. A non-zero value means this consumer is ready for dispatched messages. |
+| unackedMessages | The number of unacknowledged messages for the consumer, where an unacknowledged message has been sent to the consumer but not yet acknowledged. This field is only meaningful when using a subscription that tracks individual message acknowledgment. |
+| blockedConsumerOnUnackedMsgs | The flag used to verify if the consumer is blocked due to reaching the threshold of the unacknowledged messages. |
+| lastConsumedTimestamp (Deprecated) | The timestamp when the consumer reads a message the last time. |
+| lastConsumedTime | The time when the consumer reads a message the last time. |
+| lastAckedTimestamp (Deprecated) | The timestamp when the consumer acknowledges a message the last time. |
+| lastAckedTime | The time when the consumer acknowledges a message the last time. |
+| address | The IP address and source port for the connection of this consumer. |
+| connectedSince | The timestamp when this consumer is created or reconnected last time. |
+| clientVersion | The client library version of this consumer. |
+| bytesOutCounter | The total bytes delivered to a consumer. |
+| msgOutCounter | The total messages delivered to a consumer. |
+| msgRateRedeliver | The total rate of messages redelivered by this consumer (message per second). |
+| chunkedMessageRate | The total rate of chunked messages delivered to this consumer. |
+| avgMessagesPerEntry | The number of average messages per entry for the consumer consumed. |
+| readPositionWhenJoining | The read position of the cursor when the consumer joins. |
+| keyHashRanges | The hash ranges assigned to this consumer if it uses Key_Shared sub mode. |
+| metadata | The metadata (key/value strings) associated with this consumer. |
+
+### Replication stats
+
+| Stat | Description |
+|---------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| msgRateIn | The total rate (message per second) of messages received from the remote cluster. |
+| msgThroughputIn | The total throughput (byte per second) received from the remote cluster. |
+| msgRateOut | The total rate of messages (message per second) delivered to the replication-subscriber. |
+| msgThroughputOut | The total throughput (byte per second) delivered to the replication-subscriber. |
+| msgRateExpired | The total rate of messages (message per second) expired. |
+| replicationBacklog | The number of messages pending to be replicated to remote cluster. |
+| connected | Whether the outbound replicator is connected. |
+| replicationDelayInSeconds | How long the oldest message has been waiting to be sent through the connection when connected. |
+| inboundConnection | The IP and port of the broker in the remote cluster's publisher connection to this broker. |
+| inboundConnectedSince | The TCP connection used to publish messages to the remote cluster. If no local publishers are connected, this connection is automatically closed after a minute. |
+| outboundConnection | The address of the outbound replication connection. |
+| outboundConnectedSince | The timestamp of establishing an outbound connection. |
+
+## Topic internal stats
+
+The following table outlines the internal stats inside a topic. For more details about how to get these stats, see [Get stats](admin-api-topics.md#get-internal-stats).
+
+| Stat | Description |
+|------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| entriesAddedCounter | Messages published since this broker loads this topic. |
+| numberOfEntries | The total number of messages tracked. |
+| totalSize | The total storage size in bytes of all messages. |
+| currentLedgerEntries | The count of messages written to the ledger that is currently open for writing. |
+| currentLedgerSize | The size in bytes of messages written to the ledger that is currently open for writing. |
+| lastLedgerCreatedTimestamp | The time when the last ledger is created. |
+| lastLedgerCreationFailureTimestamp | The time when the last ledger is failed. |
+| waitingCursorsCount | The number of cursors that are caught up and waiting for a new message to be published. |
+| pendingAddEntriesCount | The number of messages that have write requests (asynchronous) waiting on completion. |
+| lastConfirmedEntry | The `ledgerid:entryid` of the last message that is written successfully. If the `entryid` is `-1`, then the ledger is opened or is currently opened but has no entries written yet. |
+| state | The state of the cursor ledger. The state `LedgerOpened` means that a ledger is open for saving published messages. |
+| ledgers | The ordered list of all ledgers for this topic that holds its messages. |
+| cursors | The list of all cursors on this topic. Each subscription in the topic stats has a cursor. |
+| markDeletePosition | The ack position: the last message that the subscriber acknowledges. All messages before this position are acknowledged by the subscriber. |
+| readPosition | The latest position of the subscriber for reading messages. |
+| waitingReadOp | This is true when the subscription reads the latest message that is published to the topic and waits for new messages to be published. |
+| pendingReadOps | The count of outstanding read requests to the BookKeepers in progress. |
+| messagesConsumedCounter | The number of messages this cursor has acknowledged since this broker loads this topic. |
+| cursorLedger | The ledger used to persistently store the current `markDeletePosition`. |
+| cursorLedgerLastEntry | The last `entryid` used to persistently store the current `markDeletePosition`. |
+| individuallyDeletedMessages | The range of messages acknowledged between `markDeletePosition` and the `readPosition` when acknowledges are done out of order. |
+| lastLedgerSwitchTimestamp | The last time when the cursor ledger is rolled over. |
+| ledgers | The ordered list of all ledgers for this topic that holds messages. |
+| schemaLedgers | The ordered list of all ledgers for this topic schema. |
+| compactedLedger | The ledgers holding un-acked messages after topic compaction. |
+| ledgerId | The ID of this ledger. |
+| entries | The total number of entries that belong to this ledger. |
+| size | The size of messages written to this ledger (in bytes). |
+| offloaded | Whether this ledger is offloaded. The value is `false` for the compacted topic ledger. |
+| metadata | The ledger metadata. |
\ No newline at end of file
diff --git a/versioned_docs/version-2.11.0/administration-upgrade.md b/versioned_docs/version-2.11.0/administration-upgrade.md
new file mode 100644
index 00000000000..5ad06f04124
--- /dev/null
+++ b/versioned_docs/version-2.11.0/administration-upgrade.md
@@ -0,0 +1,203 @@
+---
+id: administration-upgrade
+title: Upgrade Guide
+sidebar_label: "Upgrade"
+---
+
+````mdx-code-block
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+````
+
+## Upgrade guidelines
+
+Apache Pulsar is comprised of multiple components, ZooKeeper, bookies, and brokers. These components are either stateful or stateless. You do not have to upgrade ZooKeeper nodes unless you have special requirements. While you upgrade, you need to pay attention to bookies (stateful), brokers, and proxies (stateless).
+
+Read the following guidelines before upgrading a Pulsar cluster.
+
+- Back up all your configuration files before upgrading.
+- Read the guide entirely, make a plan, and then execute the plan. When you make an upgrade plan, you need to take your specific requirements and environment into consideration.
+- Pay attention to the [upgrade sequence of components](#upgrade-sequence). In general, you do not need to upgrade your ZooKeeper or configuration store cluster (the global ZooKeeper cluster). You need to upgrade bookies first, and then upgrade brokers, proxies, and your clients.
+- If `autorecovery` is enabled, you need to disable `autorecovery` in the upgrade process, and re-enable it after completing the process.
+- Read the release notes carefully for each release. Release notes contain features and configuration changes that might impact your upgrade.
+- Upgrade a small subset of nodes of each type to canary test the new version before upgrading all nodes of that type in the cluster. When you have upgraded the canary nodes, run for a while to ensure that they work correctly.
+- Upgrade one data center to verify the new version before upgrading all data centers if your cluster runs in multi-cluster replicated mode.
+
+:::note
+
+Currently, Apache Pulsar is compatible between versions.
+
+:::
+
+## Upgrade sequence
+
+To upgrade an Apache Pulsar cluster, follow the upgrade sequence.
+
+1. Upgrade ZooKeeper (optional).
+ - Canary test: test an upgraded version in one or a small set of ZooKeeper nodes.
+ - Rolling upgrade: roll out the upgraded version to all ZooKeeper servers incrementally, one at a time. Monitor your dashboard during the whole rolling upgrade process.
+2. Upgrade bookies.
+ - Canary test: test an upgraded version in one or a small set of bookies.
+ - Rolling upgrade:
+ - a. Disable `autorecovery` with the following command.
+
+ ```shell
+ bin/bookkeeper shell autorecovery -disable
+ ```
+
+ - b. Roll out the upgraded version to all bookies in the cluster after you determine that a version is safe after canary.
+ - c. After you upgrade all bookies, re-enable `autorecovery` with the following command.
+
+ ```shell
+ bin/bookkeeper shell autorecovery -enable
+ ```
+
+3. Upgrade brokers.
+ - Canary test: test an upgraded version in one or a small set of brokers.
+ - Rolling upgrade: roll out the upgraded version to all brokers in the cluster after you determine that a version is safe after canary.
+4. Upgrade proxies.
+ - Canary test: test an upgraded version in one or a small set of proxies.
+ - Rolling upgrade: roll out the upgraded version to all proxies in the cluster after you determine that a version is safe after canary.
+
+## Upgrade ZooKeeper (optional)
+While you upgrade ZooKeeper servers, you can do a canary test first, and then upgrade all ZooKeeper servers in the cluster.
+
+### Canary test
+
+You can test an upgraded version in one of ZooKeeper servers before upgrading all ZooKeeper servers in your cluster.
+
+To upgrade a ZooKeeper server to a new version, complete the following steps:
+
+1. Stop the ZooKeeper server.
+2. Upgrade the binary and configuration files.
+3. Start the ZooKeeper server with the new binary files.
+4. Use `pulsar zookeeper-shell` to connect to the newly upgraded ZooKeeper server and run a few commands to verify if it works as expected.
+5. Run the ZooKeeper server for a few days, observe and make sure the ZooKeeper cluster runs well.
+
+:::tip
+
+If issues occur during the canary test, you can shut down the problematic ZooKeeper node, revert the binary and configuration, and restart the ZooKeeper with the reverted binary.
+
+:::
+
+### Upgrade all ZooKeeper servers
+
+After the canary test to upgrade one ZooKeeper in your cluster, you can upgrade all ZooKeeper servers in your cluster.
+
+You can upgrade all ZooKeeper servers one by one by following the steps in the canary test.
+
+## Upgrade bookies
+
+While you upgrade bookies, you can do a canary test first, and then upgrade all bookies in the cluster.
+For more details, you can read Apache BookKeeper [Upgrade guide](https://bookkeeper.apache.org/docs/next/admin/upgrade).
+
+### Canary test
+
+You can test an upgraded version in one or a small set of bookies before upgrading all bookies in your cluster.
+
+To upgrade a bookie to a new version, complete the following steps:
+
+1. Stop the bookie.
+2. Upgrade the binary and configuration files.
+3. Start the bookie in `ReadOnly` mode to verify if the bookie of this new version runs well for reading workload.
+
+ ```shell
+ bin/pulsar bookie --readOnly
+ ```
+
+4. When the bookie runs successfully in `ReadOnly` mode, stop the bookie and restart it in `Write/Read` mode.
+
+ ```shell
+ bin/pulsar bookie
+ ```
+
+5. Observe and make sure the cluster serves both write and read traffic.
+
+:::tip
+
+If issues occur during the canary test, you can shut down the problematic bookie node. Other bookies in the cluster replace this problematic bookie node with auto-recovery.
+
+:::
+
+### Upgrade all bookies
+
+After the canary test to upgrade some bookies in your cluster, you can upgrade all bookies in your cluster.
+
+Before upgrading, you have to decide whether to upgrade the whole cluster at once, including downtime and rolling upgrade scenarios.
+
+In a rolling upgrade scenario, upgrade one bookie at a time. In a downtime upgrade scenario, shut down the entire cluster, upgrade each bookie, and then start the cluster.
+
+While you upgrade in both scenarios, the procedure is the same for each bookie.
+
+1. Stop the bookie.
+2. Upgrade the software (either new binary or new configuration files).
+2. Start the bookie.
+
+:::tip
+
+When you upgrade a large BookKeeper cluster in a rolling upgrade scenario, upgrading one bookie at a time is slow. If you configure a rack-aware or region-aware placement policy, you can upgrade bookies rack by rack or region by region, which speeds up the whole upgrade process.
+
+:::
+
+## Upgrade brokers and proxies
+
+The upgrade procedure for brokers and proxies is the same. Brokers and proxies are `stateless`, so upgrading the two services is easy.
+
+### Canary test
+
+You can test an upgraded version in one or a small set of nodes before upgrading all nodes in your cluster.
+
+To upgrade a broker (or proxy) to a new version, complete the following steps:
+
+1. Stop a broker (or proxy).
+2. Upgrade the binary and configuration file.
+3. Start a broker (or proxy).
+
+:::tip
+
+If issues occur during the canary test, you can shut down the problematic broker (or proxy) node. Revert to the old version and restart the broker (or proxy).
+
+:::
+
+### Upgrade all brokers or proxies
+
+After the canary test to upgrade some brokers or proxies in your cluster, you can upgrade all brokers or proxies in your cluster.
+
+Before upgrading, you have to decide whether to upgrade the whole cluster at once, including downtime and rolling upgrade scenarios.
+
+In a rolling upgrade scenario, you can upgrade one broker or one proxy at a time if the size of the cluster is small. If your cluster is large, you can upgrade brokers or proxies in batches. When you upgrade a batch of brokers or proxies, make sure the remaining brokers and proxies in the cluster have enough capacity to handle the traffic during the upgrade.
+
+In a downtime upgrade scenario, shut down the entire cluster, upgrade each broker or proxy, and then start the cluster.
+
+While you upgrade in both scenarios, the procedure is the same for each broker or proxy.
+
+1. Stop the broker (or proxy).
+2. Upgrade the software (either new binary or new configuration files).
+3. Start the broker (or proxy).
+
+:::tip
+
+To check the health of the broker, you can use the following command or API.
+
+````mdx-code-block
+<Tabs groupId="api-choice"
+ defaultValue="Admin CLI"
+ values={[{"label":"Admin CLI","value":"Admin CLI"},{"label":"REST API","value":"REST API"}]}>
+
+<TabItem value="Admin CLI">
+
+```bash
+pulsar-admin brokers healthcheck
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+Send a `GET` request to this endpoint: {@inject: endpoint|GET|/admin/v2/brokers/health|operation/healthCheck?version=@pulsar:version_number@}
+
+</TabItem>
+
+</Tabs>
+````
+
+:::
\ No newline at end of file
diff --git a/versioned_docs/version-2.11.0/administration-zk-bk.md b/versioned_docs/version-2.11.0/administration-zk-bk.md
new file mode 100644
index 00000000000..a492fe6cc09
--- /dev/null
+++ b/versioned_docs/version-2.11.0/administration-zk-bk.md
@@ -0,0 +1,354 @@
+---
+id: administration-zk-bk
+title: ZooKeeper and BookKeeper administration
+sidebar_label: "ZooKeeper and BookKeeper"
+---
+
+Pulsar relies on two external systems for essential tasks:
+
+* [ZooKeeper](https://zookeeper.apache.org/) is responsible for a wide variety of configuration-related and coordination-related tasks.
+* [BookKeeper](http://bookkeeper.apache.org/) is responsible for [persistent storage](concepts-architecture-overview.md#persistent-storage) of message data.
+
+ZooKeeper and BookKeeper are both open-source [Apache](https://www.apache.org/) projects.
+This diagram illustrates the role of ZooKeeper and BookKeeper in a Pulsar cluster:
+
+
+
+Each Pulsar cluster consists of one or more message brokers. Each broker relies on an ensemble of bookies.
+
+
+## ZooKeeper
+
+Each Pulsar instance relies on two separate ZooKeeper quorums.
+
+* [Local ZooKeeper](#deploy-local-zookeeper) operates at the cluster level and provides cluster-specific configuration management and coordination. Each Pulsar cluster needs to have a dedicated ZooKeeper cluster.
+* [Configuration Store](#deploy-configuration-store) operates at the instance level and provides configuration management for the entire system (and thus across clusters). An independent cluster of machines or the same machines that local ZooKeeper uses can provide the configuration store quorum.
+
+### Deploy local ZooKeeper
+
+ZooKeeper manages a variety of essential coordination-related and configuration-related tasks for Pulsar.
+
+To deploy a Pulsar instance, you need to stand up one local ZooKeeper cluster *per Pulsar cluster*.
+
+To begin, add all ZooKeeper servers to the quorum configuration specified in the [`conf/zookeeper.conf`](reference-configuration.md#zookeeper) file. Add a `server.N` line for each node in the cluster to the configuration, where `N` is the number of the ZooKeeper node. The following is an example of a three-node cluster:
+
+```properties
+server.1=zk1.us-west.example.com:2888:3888
+server.2=zk2.us-west.example.com:2888:3888
+server.3=zk3.us-west.example.com:2888:3888
+```
+
+On each host, you need to specify the node ID in `myid` file of each node, which is in `data/zookeeper` folder of each server by default (you can change the file location via the [`dataDir`](reference-configuration.md#zookeeper-dataDir) parameter).
+
+For detailed information on `myid` and more, see the [Multi-server setup guide](https://zookeeper.apache.org/doc/r3.4.10/zookeeperAdmin.html#sc_zkMulitServerSetup) in the ZooKeeper documentation.
+
+
+On a ZooKeeper server at `zk1.us-west.example.com`, for example, you can set the `myid` value like this:
+
+```shell
+mkdir -p data/zookeeper
+echo 1 > data/zookeeper/myid
+```
+
+On `zk2.us-west.example.com` the command is `echo 2 > data/zookeeper/myid` and so on.
+
+Once you add each server to the `zookeeper.conf` configuration and each server has the appropriate `myid` entry, you can start ZooKeeper on all hosts (in the background, using nohup) with the [`pulsar-daemon`](reference-cli-tools.md) CLI tool:
+
+```shell
+bin/pulsar-daemon start zookeeper
+```
+
+### Deploy configuration store
+
+The ZooKeeper cluster configured and started up in the section above is a *local* ZooKeeper cluster that you can use to manage a single Pulsar cluster. In addition to a local cluster, however, a full Pulsar instance also requires a configuration store for handling some instance-level configuration and coordination tasks.
+
+If you deploy a [single-cluster](#single-cluster-pulsar-instance) instance, you do not need a separate cluster for the configuration store. If, however, you deploy a [multi-cluster](#multi-cluster-pulsar-instance) instance, you need to stand up a separate ZooKeeper cluster for configuration tasks.
+
+#### Single-cluster Pulsar instance
+
+If your Pulsar instance consists of just one cluster, then you can deploy a configuration store on the same machines as the local ZooKeeper quorum but run on different TCP ports.
+
+To deploy a ZooKeeper configuration store in a single-cluster instance, add the same ZooKeeper servers that the local quorum uses to the configuration file in [`conf/global_zookeeper.conf`](reference-configuration.md#configuration-store) using the same method for [local ZooKeeper](#deploy-local-zookeeper), but make sure to use a different port (2181 is the default for ZooKeeper). The following is an example that uses port 2184 for a three-node ZooKeeper cluster:
+
+```properties
+clientPort=2184
+server.1=zk1.us-west.example.com:2185:2186
+server.2=zk2.us-west.example.com:2185:2186
+server.3=zk3.us-west.example.com:2185:2186
+```
+
+As before, create the `myid` files for each server on `data/global-zookeeper/myid`.
+
+#### Multi-cluster Pulsar instance
+
+When you deploy a global Pulsar instance, with clusters distributed across different geographical regions, the configuration store serves as a highly available and strongly consistent metadata store that can tolerate failures and partitions spanning whole regions.
+
+The key here is to make sure the ZK quorum members are spread across at least 3 regions and that other regions run as observers.
+
+Again, given the very low expected load on the configuration store servers, you can share the same hosts used for the local ZooKeeper quorum.
+
+For example, you can assume a Pulsar instance with the following clusters `us-west`, `us-east`, `us-central`, `eu-central`, `ap-south`. Also you can assume, each cluster has its own local ZK servers named such as `zk[1-3].${CLUSTER}.example.com`.
+
+In this scenario, you want to pick the quorum participants from a few clusters and let all the others be ZK observers. For example, to form a 7 servers quorum, you can pick 3 servers from `us-west`, 2 from `us-central` and 2 from `us-east`.
+
+This guarantees writing to the configuration store is possible even if one of these regions is unreachable.
+
+The ZK configuration in all the servers looks like below:
+
+```properties
+clientPort=2184
+server.1=zk1.us-west.example.com:2185:2186
+server.2=zk2.us-west.example.com:2185:2186
+server.3=zk3.us-west.example.com:2185:2186
+server.4=zk1.us-central.example.com:2185:2186
+server.5=zk2.us-central.example.com:2185:2186
+server.6=zk3.us-central.example.com:2185:2186:observer
+server.7=zk1.us-east.example.com:2185:2186
+server.8=zk2.us-east.example.com:2185:2186
+server.9=zk3.us-east.example.com:2185:2186:observer
+server.10=zk1.eu-central.example.com:2185:2186:observer
+server.11=zk2.eu-central.example.com:2185:2186:observer
+server.12=zk3.eu-central.example.com:2185:2186:observer
+server.13=zk1.ap-south.example.com:2185:2186:observer
+server.14=zk2.ap-south.example.com:2185:2186:observer
+server.15=zk3.ap-south.example.com:2185:2186:observer
+```
+
+Additionally, ZK observers need to have:
+
+```properties
+peerType=observer
+```
+
... 39898 lines suppressed ...