You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pulsar.apache.org by li...@apache.org on 2021/11/25 02:06:09 UTC

[pulsar] branch master updated: [website][upgrade]feat: website upgrade / docs migration - 2.6.0 / helm/deploy/administration (#12933)

This is an automated email from the ASF dual-hosted git repository.

liuyu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pulsar.git


The following commit(s) were added to refs/heads/master by this push:
     new 9a994fe  [website][upgrade]feat: website upgrade / docs migration - 2.6.0 / helm/deploy/administration (#12933)
9a994fe is described below

commit 9a994fe239ba1b1399da456c0dae0e65a906e0f1
Author: Li Li <ur...@gmail.com>
AuthorDate: Thu Nov 25 10:05:12 2021 +0800

    [website][upgrade]feat: website upgrade / docs migration - 2.6.0 / helm/deploy/administration (#12933)
    
    * [website][upgrade]feat: website upgrade / docs migration - 2.6.0 / get started/concepts/schema
    
    Signed-off-by: LiLi <ur...@gmail.com>
    
    * [website][upgrade]feat: website upgrade / docs migration - 2.6.0 / functions/io/sql
    
    Signed-off-by: LiLi <ur...@gmail.com>
    
    * [website][upgrade]feat: website upgrade / docs migration - 2.6.0 / helm/deploy/administration
    
    Signed-off-by: LiLi <ur...@gmail.com>
    
    * [website][upgrade]feat: website upgrade / docs migration - 2.6.0 / client/performance/secrurity
    
    Signed-off-by: LiLi <ur...@gmail.com>
    
    Co-authored-by: Anonymitaet <50...@users.noreply.github.com>
---
 .../version-2.6.0/administration-geo.md            | 213 +++++
 .../version-2.6.0/administration-load-balance.md   | 200 +++++
 .../version-2.6.0/administration-proxy.md          | 116 +++
 .../version-2.6.0/administration-pulsar-manager.md | 205 +++++
 .../version-2.6.0/administration-stats.md          |  64 ++
 .../version-2.6.0/administration-upgrade.md        | 168 ++++
 .../version-2.6.0/administration-zk-bk.md          | 376 ++++++++
 .../version-2.6.0/client-libraries-cpp.md          | 297 +++++++
 .../version-2.6.0/client-libraries-dotnet.md       | 434 +++++++++
 .../version-2.6.0/client-libraries-go.md           | 699 +++++++++++++++
 .../version-2.6.0/client-libraries-java.md         | 980 +++++++++++++++++++++
 .../version-2.6.0/client-libraries-node.md         | 430 +++++++++
 .../version-2.6.0/client-libraries-python.md       | 323 +++++++
 .../version-2.6.0/client-libraries-websocket.md    | 491 +++++++++++
 .../versioned_docs/version-2.6.0/deploy-aws.md     | 268 ++++++
 .../deploy-bare-metal-multi-cluster.md             | 479 ++++++++++
 .../version-2.6.0/deploy-bare-metal.md             | 527 +++++++++++
 .../versioned_docs/version-2.6.0/deploy-dcos.md    | 200 +++++
 .../version-2.6.0/deploy-kubernetes.md             |  11 +
 .../version-2.6.0/deploy-monitoring.md             | 103 +++
 .../versioned_docs/version-2.6.0/helm-deploy.md    | 434 +++++++++
 .../versioned_docs/version-2.6.0/helm-install.md   |  44 +
 .../versioned_docs/version-2.6.0/helm-overview.md  | 105 +++
 .../versioned_docs/version-2.6.0/helm-prepare.md   |  92 ++
 .../versioned_docs/version-2.6.0/helm-tools.md     |  43 +
 .../versioned_docs/version-2.6.0/helm-upgrade.md   |  45 +
 .../version-2.6.0/performance-pulsar-perf.md       | 210 +++++
 .../version-2.6.0/security-athenz.md               |  98 +++
 .../version-2.6.0/security-authorization.md        | 113 +++
 .../version-2.6.0/security-bouncy-castle.md        | 133 +++
 .../version-2.6.0/security-encryption.md           | 190 ++++
 .../version-2.6.0/security-extending.md            | 205 +++++
 .../versioned_docs/version-2.6.0/security-jwt.md   | 323 +++++++
 .../version-2.6.0/security-kerberos.md             | 443 ++++++++++
 .../version-2.6.0/security-overview.md             |  31 +
 .../version-2.6.0/security-tls-authentication.md   | 220 +++++
 .../version-2.6.0/security-tls-keystore.md         | 322 +++++++
 .../version-2.6.0/security-tls-transport.md        | 290 ++++++
 .../versioned_sidebars/version-2.6.0-sidebars.json | 188 ++++
 39 files changed, 10113 insertions(+)

diff --git a/site2/website-next/versioned_docs/version-2.6.0/administration-geo.md b/site2/website-next/versioned_docs/version-2.6.0/administration-geo.md
new file mode 100644
index 0000000..cb2ba73
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.6.0/administration-geo.md
@@ -0,0 +1,213 @@
+---
+id: administration-geo
+title: Pulsar geo-replication
+sidebar_label: "Geo-replication"
+original_id: administration-geo
+---
+
+*Geo-replication* is the replication of persistently stored message data across multiple clusters of a Pulsar instance.
+
+## How geo-replication works
+
+The diagram below illustrates the process of geo-replication across Pulsar clusters:
+
+![Replication Diagram](/assets/geo-replication.png)
+
+In this diagram, whenever **P1**, **P2**, and **P3** producers publish messages to the **T1** topic on **Cluster-A**, **Cluster-B**, and **Cluster-C** clusters respectively, those messages are instantly replicated across clusters. Once the messages are replicated, **C1** and **C2** consumers can consume those messages from their respective clusters.
+
+Without geo-replication, **C1** and **C2** consumers are not able to consume messages that **P3** producer publishes.
+
+## Geo-replication and Pulsar properties
+
+You must enable geo-replication on a per-tenant basis in Pulsar. You can enable geo-replication between clusters only when a tenant is created that allows access to both clusters.
+
+Although geo-replication must be enabled between two clusters, actually geo-replication is managed at the namespace level. You must complete the following tasks to enable geo-replication for a namespace:
+
+* [Enable geo-replication namespaces](#enable-geo-replication-namespaces)
+* Configure that namespace to replicate across two or more provisioned 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 replicated subscription is enabled. Once replicated subscription is enabled, you can keep subscription state in synchronization. Therefore, a topic can be asynchronously replicated across multiple geographical regions. In case of failover [...]
+
+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
+
+As stated in [Geo-replication and Pulsar properties](#geo-replication-and-pulsar-properties) section, geo-replication in Pulsar is managed at the [tenant](reference-terminology.md#tenant) level.
+
+The following example connects three clusters: **us-east**, **us-west**, and **us-cent**.
+
+### 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`](https://pulsar.apache.org/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](https://pulsar.apache.org/tools/pulsar-admin/).
+
+:::
+
+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 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 namespaces
+
+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
+
+```
+
+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.
+
+### Use topics with geo-replication
+
+Once you create a geo-replication namespace, any topics that producers or consumers create within that namespace is replicated across clusters. Typically, each application uses the `serviceUrl` for the local cluster.
+
+#### 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 for the [Java API](client-libraries-java). 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
+
+Topic-specific statistics for geo-replication topics are available via the [`pulsar-admin`](reference-pulsar-admin) tool and {@inject: rest:REST:/} API:
+
+```shell
+
+$ bin/pulsar-admin persistent stats persistent://my-tenant/my-namespace/my-topic
+
+```
+
+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 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 subscription 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 subscription, 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.
diff --git a/site2/website-next/versioned_docs/version-2.6.0/administration-load-balance.md b/site2/website-next/versioned_docs/version-2.6.0/administration-load-balance.md
new file mode 100644
index 0000000..3efba60
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.6.0/administration-load-balance.md
@@ -0,0 +1,200 @@
+---
+id: administration-load-balance
+title: Pulsar load balance
+sidebar_label: "Load balance"
+original_id: administration-load-balance
+---
+
+## Load balance across Pulsar brokers
+
+Pulsar is an horizontally scalable messaging system, so the traffic
+in a logical cluster must be spread 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 require 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. 
+
+## Pulsar load manager architecture
+
+The following part introduces the basic architecture of the Pulsar load manager.
+
+### Assign topics to brokers dynamically
+
+Topics are dynamically assigned to brokers based on the load conditions of all brokers in the cluster.
+
+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. 
+
+In case of partitioned topics, different partitions are assigned to different brokers. Here "topic" means either a non-partitioned topic or one partition of a topic.
+
+The assignment is "dynamic" because the assignment changes quickly. For example, if the broker owning the topic crashes, the topic is reassigned immediately to another broker. Another scenario is that the broker owning the topic becomes overloaded. In this case, the topic is reassigned to a less loaded broker.
+
+The stateless nature of brokers makes the dynamic assignment possible, so you can quickly expand or shrink the cluster based on usage.
+
+#### Assignment granularity
+
+The assignment of topics or partitions to brokers is not done at the topics or partitions level, but done at the Bundle level (a higher level). The reason is to amortize the amount of information that you need to keep track. Based on CPU, memory, traffic load and other indexes, topics are assigned to a particular broker dynamically. 
+
+Instead of individual topic or partition assignment, 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.
+
+The namespace is the "administrative" unit: many config knobs or operations are done at the namespace level.
+
+For assignment, a namespaces is sharded into a list of "bundles", with each bundle comprising
+a portion of 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 into.
+
+Each bundle is independent of the others and thus is independently assigned to different brokers.
+
+### Create namespaces and bundles
+
+When you create a new namespace, the new namespace sets to use the default number of bundles. You can set this in `conf/broker.conf`:
+
+```properties
+
+# When a namespace is created without specifying the number of bundle, this
+# value will be used as the default
+defaultNumberOfNamespaceBundles=4
+
+```
+
+You can either change the system default, or override it when you create a new namespace:
+
+```shell
+
+$ bin/pulsar-admin namespaces create my-tenant/my-namespace --clusters us-west --bundles 16
+
+```
+
+With this command, you create a namespace with 16 initial bundles. Therefore the topics for this namespaces 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, because of 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.
+
+### Unload topics and bundles
+
+You can "unload" a topic in Pulsar with admin operation. Unloading means to close the topics,
+release ownership and reassign the topics to a new broker, based on 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
+
+```
+
+### Split namespace bundles 
+
+Since the load for the topics in a bundle might change over time, or predicting upfront might just be hard, brokers can split bundles into two. The new smaller bundles can be reassigned to different brokers.
+
+The splitting happens based on some tunable thresholds. Any existing bundle that exceeds any of the threshold is a candidate to be split. By default the newly split bundles are also immediately offloaded to other brokers, to facilitate the traffic distribution.
+
+```properties
+
+# enable/disable namespace bundle auto split
+loadBalancerAutoBundleSplitEnabled=true
+
+# enable/disable automatic unloading of split bundles
+loadBalancerAutoUnloadSplitBundlesEnabled=true
+
+# 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 offload is based on traffic (as a proxy measure for cpu, network
+and memory), broker unloads bundles for at least 15% of traffic.
+
+The automatic load shedding is enabled by default and you can disable the automatic load shedding with this setting:
+
+```properties
+
+# Enable/disable automatic bundle unloading for load-shedding
+loadBalancerSheddingEnabled=true
+
+```
+
+Additional settings that apply to shedding:
+
+```properties
+
+# 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 that once within this timeframe
+loadBalancerSheddingGracePeriodMinutes=30
+
+```
+
+#### Broker overload thresholds
+
+The determinations of when a broker is overloaded is based on threshold of CPU, network and memory usage. Whenever either of those metrics reaches the threshold, the system triggers the shedding (if enabled).
+
+By default, overload threshold is set at 85%:
+
+```properties
+
+# Usage threshold to determine a broker as over-loaded
+loadBalancerBrokerOverloadedThresholdPercentage=85
+
+```
+
+Pulsar gathers the usage stats from the system metrics.
+
+In case of network utilization, in some cases 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 Pulsar 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 use the following setting to correct the max NIC speed:
+
+```properties
+
+# Override the auto-detection of the network interfaces max speed.
+# This option is useful in some environments (eg: EC2 VMs) where the max speed
+# reported by Linux is not reflecting the real bandwidth available to the broker.
+# Since the network usage is employed by the load manager to decide when a broker
+# is overloaded, it is important to make sure the info is correct or override it
+# with the right value here. The configured value can be a double (eg: 0.8) and that
+# can be used to trigger load-shedding even before hitting on NIC limits.
+loadBalancerOverrideBrokerNicSpeedGbps=
+
+```
+
+When the value is empty, Pulsar uses the value that the OS reports.
+
diff --git a/site2/website-next/versioned_docs/version-2.6.0/administration-proxy.md b/site2/website-next/versioned_docs/version-2.6.0/administration-proxy.md
new file mode 100644
index 0000000..f8b70d2
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.6.0/administration-proxy.md
@@ -0,0 +1,116 @@
+---
+id: administration-proxy
+title: The Pulsar proxy
+sidebar_label: "Pulsar proxy"
+original_id: administration-proxy
+---
+
+The [Pulsar proxy](concepts-architecture-overview.md#pulsar-proxy) is an optional gateway that you can run in front of the brokers in a Pulsar cluster. You can run a Pulsar proxy in cases when direction connections between clients and Pulsar brokers are either infeasible, undesirable, or both, for example when you run Pulsar in a cloud environment or on [Kubernetes](https://kubernetes.io) or an analogous platform.
+
+## Configure the proxy
+
+The proxy must have some way to find the addresses of the brokers of the cluster. You can do this by either configuring the proxy to connect directly to service discovery or by specifying a broker URL in the configuration. 
+
+### Option 1: 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
+
+zookeeperServers=zk-0,zk-1,zk-2
+configurationStoreServers=zk-0:2184,zk-remote:2184
+
+```
+
+> If you use service discovery, the network ACL must allow the proxy to talk to the ZooKeeper nodes on the zookeeper client port, which is usually 2181, and on the configuration store client port, which is 2184 by default. Opening the network ACLs means that if someone compromises a proxy, they have full access to ZooKeeper. For this reason, using broker URLs to configure the proxy is more secure.
+
+### Option 2: Use broker URLs
+
+The more secure method of configuring the proxy is to specify a URL to connect to the brokers.
+
+> [Authorization](security-authorization#enable-authorization-and-assign-superusers) at the proxy requires access to ZooKeeper, so if you use these broker URLs to connect to the brokers, you should disable the Proxy level authorization. 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
+
+```
+
+Or if you use TLS:
+
+```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 which points to multiple brokers or a Virtual IP which is backed by multiple broker IP addresses so that the proxy does not lose connectivity to the 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, then you do not need to configure `functionWorkerWebServiceURL`.
+
+## Start the proxy
+
+To start the proxy:
+
+```bash
+
+$ cd /path/to/pulsar/directory
+$ bin/pulsar proxy
+
+```
+
+> You can run as many instances of the Pulsar proxy in a cluster as you want.
+
+
+## Stop the proxy
+
+The Pulsar proxy runs by default in the foreground. To stop the proxy, simply stop the process in which the proxy is running.
+
+## Proxy frontends
+
+You can run the 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, then the connection URL for clients is `pulsar://pulsar.cluster.default:6650`.
+
+## Proxy configuration
+
+You can configure the Pulsar proxy using the [`proxy.conf`](reference-configuration.md#proxy) configuration file. The following parameters are available in that file:
+
+|Name|Description|Default|
+|---|---|---|
+|zookeeperServers|  The ZooKeeper quorum connection string (as a comma-separated list)  ||
+|configurationStoreServers| Configuration store connection string (as a comma-separated list) ||
+|zookeeperSessionTimeoutMs| ZooKeeper session timeout (in milliseconds) |30000|
+|servicePort| The port to use for server binary Protobuf requests |6650|
+|servicePortTls|  The port to use to server binary Protobuf TLS requests  |6651|
+|statusFilePath | Path for the file used to determine the rotation status for the proxy instance when responding to service discovery health checks ||
+|advertisedAddress|Hostname or IP address the service advertises to the outside world.|`InetAddress.getLocalHost().getHostname()`|
+|authenticationEnabled| Whether authentication is enabled for the Pulsar proxy  |false|
+|authenticateMetricsEndpoint| Whether the '/metrics' endpoint requires authentication. Defaults to true. 'authenticationEnabled' must also be set for this to take effect. |true|
+|authenticationProviders| Authentication provider name list (a comma-separated list of class names) ||
+|authorizationEnabled|  Whether authorization is enforced by the Pulsar proxy |false|
+|authorizationProvider| Authorization provider as a fully qualified class name  |org.apache.pulsar.broker.authorization.PulsarAuthorizationProvider|
+|brokerClientAuthenticationPlugin|  The authentication plugin used by the Pulsar proxy to authenticate with Pulsar brokers  ||
+|brokerClientAuthenticationParameters|  The authentication parameters used by the Pulsar proxy to authenticate with Pulsar brokers  ||
+|brokerClientTrustCertsFilePath|  The path to trusted certificates used by the Pulsar proxy to authenticate with Pulsar brokers ||
+|superUserRoles|  Role names that are treated as “super-users,” meaning that they are able to perform all admin ||
+|forwardAuthorizationCredentials| Whether client authorization credentials are forwarded to the broker for re-authorization. Authentication must be enabled via authenticationEnabled=true for this to take effect.  |false|
+|maxConcurrentInboundConnections| Max concurrent inbound connections. The proxy rejects requests beyond that. |10000|
+|maxConcurrentLookupRequests| Max concurrent outbound connections. The proxy errors out requests beyond that. |50000|
+|tlsEnabledInProxy| Whether TLS is enabled for the proxy  |false|
+|tlsEnabledWithBroker|  Whether TLS is enabled when communicating with Pulsar brokers |false|
+|tlsCertificateFilePath|  Path for the TLS certificate file ||
+|tlsKeyFilePath|  Path for the TLS private key file ||
+|tlsTrustCertsFilePath| Path for the trusted TLS certificate pem file ||
+|tlsHostnameVerificationEnabled|  Whether the hostname is validated when the proxy creates a TLS connection with brokers  |false|
+|tlsRequireTrustedClientCertOnConnect|  Whether client certificates are required for TLS. Connections are rejected if the client certificate is not trusted. |false|
diff --git a/site2/website-next/versioned_docs/version-2.6.0/administration-pulsar-manager.md b/site2/website-next/versioned_docs/version-2.6.0/administration-pulsar-manager.md
new file mode 100644
index 0000000..12ec681
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.6.0/administration-pulsar-manager.md
@@ -0,0 +1,205 @@
+---
+id: administration-pulsar-manager
+title: Pulsar Manager
+sidebar_label: "Pulsar Manager"
+original_id: administration-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.
+
+:::note
+
+If you monitor your current stats with [Pulsar dashboard](administration-dashboard), you can try to use Pulsar Manager instead. Pulsar dashboard is deprecated.
+
+:::
+
+## 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.2.0
+docker run -it \
+    -p 9527:9527 -p 7750:7750 \
+    -e SPRING_CONFIGURATION_FILE=/pulsar-manager/pulsar-manager/application.properties \
+    apachepulsar/pulsar-manager:v0.2.0
+
+```
+
+* `SPRING_CONFIGURATION_FILE`: Default configuration file for spring.
+
+### Set administrator account and password
+
+ ```shell
+ 
+ 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"}'
+ 
+ ```
+
+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:
+
+```
+
+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 .
+
+```
+
+### Use custom databases
+
+If you have a large amount of data, you can use a custom database. The following is an example of PostgreSQL.   
+
+1. Initialize database and table structures using the [file](https://github.com/apache/pulsar-manager/tree/master/src/main/resources/META-INF/sql/postgresql-schema.sql).
+
+2. Modify the [configuration file](https://github.com/apache/pulsar-manager/blob/master/src/main/resources/application.properties) and add PostgreSQL configuration.
+
+```
+
+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. Compile to generate a new executable jar package.
+
+```
+
+./gradlew build -x test
+
+```
+
+### Enable JWT authentication
+
+If you want to turn on JWT authentication, configure the following parameters:
+
+* `backend.jwt.token`: token for the superuser. You need to configure this parameter during cluster initialization.
+* `jwt.broker.token.mode`: multiple modes of generating token, 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](http://pulsar.apache.org/docs/en/security-token-admin/).
+
+
+If you want to enable JWT authentication, use one of the following methods.
+
+
+* Method 1: use command-line tool
+
+```
+
+wget https://dist.apache.org/repos/dist/release/pulsar/pulsar-manager/apache-pulsar-manager-0.2.0/apache-pulsar-manager-0.2.0-bin.tar.gz
+tar -zxvf apache-pulsar-manager-0.2.0-bin.tar.gz
+cd pulsar-manager
+tar -zxvf pulsar-manager.tar
+cd pulsar-manager
+cp -r ../dist ui
+./bin/pulsar-manager --redirect.host=http://localhost --redirect.port=9527 insert.stats.interval=600000 --backend.jwt.token=token --jwt.broker.token.mode=PRIVATE --jwt.broker.private.key=file:///path/broker-private.key --jwt.broker.public.key=file:///path/broker-public.key
+
+```
+
+Firstly, [set the administrator account and password](#set-administrator-account-and-password)
+
+Secondly, log in to Pulsar manager through http://localhost:7750/ui/index.html.
+
+* Method 2: configure the application.properties file
+
+```
+
+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
+
+```
+
+* Method 3: use Docker and enable token authentication.
+
+```
+
+export JWT_TOKEN="your-token"
+docker run -it -p 9527:9527 -p 7750:7750 -e REDIRECT_HOST=http://localhost -e REDIRECT_PORT=9527 -e DRIVER_CLASS_NAME=org.postgresql.Driver -e URL='jdbc:postgresql://127.0.0.1:5432/pulsar_manager' -e USERNAME=pulsar -e PASSWORD=pulsar -e LOG_LEVEL=DEBUG -e JWT_TOKEN=$JWT_TOKEN -v $PWD:/data apachepulsar/pulsar-manager:v0.2.0 /bin/sh
+
+```
+
+* `JWT_TOKEN`: the token of superuser configured for the broker. It is generated by the `bin/pulsar tokens create --secret-key` or `bin/pulsar tokens create --private-key` command.
+* `REDIRECT_HOST`: the IP address of the front-end server.
+* `REDIRECT_PORT`: the port of the front-end server.
+* `DRIVER_CLASS_NAME`: the driver class name of the PostgreSQL database.
+* `URL`: the JDBC URL of your PostgreSQL database, such as jdbc:postgresql://127.0.0.1:5432/pulsar_manager. The docker image automatically start a local instance of the PostgreSQL database.
+* `USERNAME`: the username of PostgreSQL.
+* `PASSWORD`: the password of PostgreSQL.
+* `LOG_LEVEL`: the level of log.
+
+* Method 4: use Docker and turn on **token authentication** and **token management** by private key and public key.
+
+```
+
+export JWT_TOKEN="your-token"
+export PRIVATE_KEY="file:///pulsar-manager/secret/my-private.key"
+export PUBLIC_KEY="file:///pulsar-manager/secret/my-public.key"
+docker run -it -p 9527:9527 -p 7750:7750 -e REDIRECT_HOST=http://localhost -e REDIRECT_PORT=9527 -e DRIVER_CLASS_NAME=org.postgresql.Driver -e URL='jdbc:postgresql://127.0.0.1:5432/pulsar_manager' -e USERNAME=pulsar -e PASSWORD=pulsar -e LOG_LEVEL=DEBUG -e JWT_TOKEN=$JWT_TOKEN -e PRIVATE_KEY=$PRIVATE_KEY -e PUBLIC_KEY=$PUBLIC_KEY -v $PWD:/data -v $PWD/secret:/pulsar-manager/secret apachepulsar/pulsar-manager:v0.2.0 /bin/sh
+
+```
+
+* `JWT_TOKEN`: the token of superuser configured for the broker. It is generated by the `bin/pulsar tokens create --private-key` command.
+* `PRIVATE_KEY`: private key path mounted in container, generated by `bin/pulsar tokens create-key-pair` command.
+* `PUBLIC_KEY`: public key path mounted in container, generated by `bin/pulsar tokens create-key-pair` command.
+* `$PWD/secret`: The folder where the private key and public key generated by the `bin/pulsar tokens create-key-pair` command are placed locally
+* `REDIRECT_HOST`: the IP address of the front-end server.
+* `REDIRECT_PORT`: the port of the front-end server.
+* `DRIVER_CLASS_NAME`: the driver class name of the PostgreSQL database.
+* `URL`: the JDBC URL of your PostgreSQL database, such as jdbc:postgresql://127.0.0.1:5432/pulsar_manager. The docker image automatically start a local instance of the PostgreSQL database.
+* `USERNAME`: the username of PostgreSQL.
+* `PASSWORD`: the password of PostgreSQL.
+* `LOG_LEVEL`: the level of log.
+
+* Method 5: use Docker and turn on **token authentication** and **token management** by secret key.
+
+```
+
+export JWT_TOKEN="your-token"
+export SECRET_KEY="file:///pulsar-manager/secret/my-secret.key"
+docker run -it -p 9527:9527 -p 7750:7750 -e REDIRECT_HOST=http://localhost -e REDIRECT_PORT=9527 -e DRIVER_CLASS_NAME=org.postgresql.Driver -e URL='jdbc:postgresql://127.0.0.1:5432/pulsar_manager' -e USERNAME=pulsar -e PASSWORD=pulsar -e LOG_LEVEL=DEBUG -e JWT_TOKEN=$JWT_TOKEN -e SECRET_KEY=$SECRET_KEY -v $PWD:/data -v $PWD/secret:/pulsar-manager/secret apachepulsar/pulsar-manager:v0.2.0 /bin/sh
+
+```
+
+* `JWT_TOKEN`: the token of superuser configured for the broker. It is generated by the `bin/pulsar tokens create --secret-key` command.
+* `SECRET_KEY`: secret key path mounted in container, generated by `bin/pulsar tokens create-secret-key` command.
+* `$PWD/secret`: the folder where the secret key generated by the `bin/pulsar tokens create-secret-key` command are placed locally
+* `REDIRECT_HOST`: the IP address of the front-end server.
+* `REDIRECT_PORT`: the port of the front-end server.
+* `DRIVER_CLASS_NAME`: the driver class name of the PostgreSQL database.
+* `URL`: the JDBC URL of your PostgreSQL database, such as jdbc:postgresql://127.0.0.1:5432/pulsar_manager. The docker image automatically start a local instance of the PostgreSQL database.
+* `USERNAME`: the username of PostgreSQL.
+* `PASSWORD`: the password of PostgreSQL.
+* `LOG_LEVEL`: the level of log.
+
+* 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).
+
+## Log in
+
+[Set the administrator account and password](#set-administrator-account-and-password).
+
+Visit http://localhost:9527 to log in.
diff --git a/site2/website-next/versioned_docs/version-2.6.0/administration-stats.md b/site2/website-next/versioned_docs/version-2.6.0/administration-stats.md
new file mode 100644
index 0000000..ac0c036
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.6.0/administration-stats.md
@@ -0,0 +1,64 @@
+---
+id: administration-stats
+title: Pulsar stats
+sidebar_label: "Pulsar statistics"
+original_id: administration-stats
+---
+
+## Partitioned topics
+
+|Stat|Description|
+|---|---|
+|msgRateIn| The sum of publish rates of all local and replication publishers in messages per second.|
+|msgThroughputIn| Same as msgRateIn but in bytes per second instead of messages per second.|
+|msgRateOut| The sum of dispatch rates of all local and replication consumers in messages per second.|
+|msgThroughputOut| Same as msgRateOut but in bytes per second instead of messages per second.|
+|averageMsgSize| Average message size, in bytes, from this publisher within the last interval.|
+|storageSize| The sum of storage size of the ledgers for this topic.|
+|publishers| The list of all local publishers into the topic. Publishers can be anywhere from zero to thousands.|
+|producerId| Internal identifier for this producer on this topic.|
+|producerName|  Internal identifier for this producer, generated by the client library.|
+|address| IP address and source port for the connection of this producer.|
+|connectedSince| Timestamp this producer is created or last reconnected.|
+|subscriptions| The list of all local subscriptions to the topic.|
+|my-subscription| The name of this subscription (client defined).|
+|msgBacklog| The count of messages in backlog for this subscription.|
+|type| This subscription type.|
+|msgRateExpired| The rate at which messages are discarded instead of dispatched from this subscription due to TTL.|
+|consumers| The list of connected consumers for this subscription.|
+|consumerName| Internal identifier for this consumer, generated by the client library.|
+|availablePermits| The number of messages this consumer has space for in the listen queue of client library. A value of 0 means the queue of client library is full and receive() is not being called. A nonzero value means this consumer is ready to be dispatched messages.|
+|replication| This section gives the stats for cross-colo replication of this topic.|
+|replicationBacklog| The outbound replication backlog in messages.|
+|connected| Whether the outbound replicator is connected.|
+|replicationDelayInSeconds| How long the oldest message has been waiting to be sent through the connection, if connected is true.|
+|inboundConnection| The IP and port of the broker in the publisher connection of remote cluster to this broker. |
+|inboundConnectedSince| The TCP connection being used to publish messages to the remote cluster. If no local publishers are connected, this connection is automatically closed after a minute.|
+
+
+## Topics
+
+|Stat|Description|
+|---|---|
+|entriesAddedCounter| Messages published since this broker loads this topic.|
+|numberOfEntries| Total number of messages being tracked.|
+|totalSize| Total storage size in bytes of all messages.|
+|currentLedgerEntries| Count of messages written to the ledger currently open for writing.|
+|currentLedgerSize| Size in bytes of messages written to ledger currently open for writing.|
+|lastLedgerCreatedTimestamp| Time when last ledger is created.|
+|lastLedgerCreationFailureTimestamp| Time when last ledger is failed.|
+|waitingCursorsCount| How many cursors are caught up and waiting for a new message to be published.|
+|pendingAddEntriesCount| How many messages have (asynchronous) write requests you are waiting on completion.|
+|lastConfirmedEntry| The ledgerid:entryid of the last message successfully written. If the entryid is -1, then the ledger is opened or is being currently opened but has no entries written yet.|
+|state| The state of the cursor ledger. Open means you have a cursor ledger for saving updates of the markDeletePosition.|
+|ledgers| The ordered list of all ledgers for this topic holding its messages.|
+|cursors| The list of all cursors on this topic. Every subscription you saw in the topic stats has one.|
+|markDeletePosition| The ack position: the last message the subscriber acknowledges receiving.|
+|readPosition| The latest position of subscriber for reading message.|
+|waitingReadOp| This is true when the subscription reads the latest message that is published to the topic and waits on new messages to be published.|
+|pendingReadOps| The counter for how many outstanding read requests to the BookKeepers you have in progress.|
+|messagesConsumedCounter| Number of messages this cursor acks 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| If Acks are done out of order, shows the ranges of messages Acked between the markDeletePosition and the read-position.|
+|lastLedgerSwitchTimestamp| The last time the cursor ledger is rolled over.|
diff --git a/site2/website-next/versioned_docs/version-2.6.0/administration-upgrade.md b/site2/website-next/versioned_docs/version-2.6.0/administration-upgrade.md
new file mode 100644
index 0000000..72d136b
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.6.0/administration-upgrade.md
@@ -0,0 +1,168 @@
+---
+id: administration-upgrade
+title: Upgrade Guide
+sidebar_label: "Upgrade"
+original_id: administration-upgrade
+---
+
+## 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 requirement. While you upgrade, you need to pay attention to bookies (stateful), brokers and proxies (stateless).
+
+The following are some guidelines on upgrading a Pulsar cluster. Read the guidelines before upgrading.
+
+- Backup all your configuration files before upgrading.
+- Read guide entirely, make a plan, and then execute the plan. When you make upgrade plan, you need to take your specific requirements and environment into consideration.   
+- Pay attention to the upgrading order of components. 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, 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 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: rollout 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. Rollout 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: rollout 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: rollout 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 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 ZooKeeper server to a new version, complete the following steps:
+
+1. Stop a 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.
+
+#### Canary rollback
+
+If issues occur during 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 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 steps in canary test.
+
+## Upgrade bookies
+
+While you upgrade bookies, you can do canary test first, and then upgrade all bookies in the cluster.
+For more details, you can read Apache BookKeeper [Upgrade guide](http://bookkeeper.apache.org/docs/latest/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 bookie to a new version, complete the following steps:
+
+1. Stop a 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 read 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.
+
+#### Canary rollback
+
+If issues occur during the canary test, you can shut down the problematic bookie node. Other bookies in the cluster replaces this problematic bookie node with autorecovery. 
+
+### Upgrade all bookies
+
+After 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.
+
+> **Advanced operations**   
+> When you upgrade a large BookKeeper cluster in a rolling upgrade scenario, upgrading one bookie at a time is slow. If you configure 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 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).
+
+#### Canary rollback
+
+If issues occur during 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 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 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.
diff --git a/site2/website-next/versioned_docs/version-2.6.0/administration-zk-bk.md b/site2/website-next/versioned_docs/version-2.6.0/administration-zk-bk.md
new file mode 100644
index 0000000..e63be45
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.6.0/administration-zk-bk.md
@@ -0,0 +1,376 @@
+---
+id: administration-zk-bk
+title: ZooKeeper and BookKeeper administration
+sidebar_label: "ZooKeeper and BookKeeper"
+original_id: administration-zk-bk
+---
+
+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.
+
+> Skip to the [How Pulsar uses ZooKeeper and BookKeeper](#how-pulsar-uses-zookeeper-and-bookkeeper) section below for a more schematic explanation of the role of these two systems in Pulsar.
+
+
+## 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 for 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).
+
+> See the [Multi-server setup guide](https://zookeeper.apache.org/doc/r3.4.10/zookeeperAdmin.html#sc_zkMulitServerSetup) in the ZooKeeper documentation for detailed information on `myid` and more.
+
+
+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#pulsar-daemon) 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](#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 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 that writes to configuration store is possible even if one of these regions is unreachable.
+
+The ZK configuration in all the servers looks like:
+
+```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
+
+```
+
+##### Start the service
+
+Once your configuration store configuration is in place, you can start up the service using [`pulsar-daemon`](reference-cli-tools.md#pulsar-daemon)
+
+```shell
+
+$ bin/pulsar-daemon start configuration-store
+
+```
+
+### ZooKeeper configuration
+
+In Pulsar, ZooKeeper configuration is handled by two separate configuration files in the `conf` directory of your Pulsar installation: `conf/zookeeper.conf` for [local ZooKeeper](#local-zookeeper) and `conf/global-zookeeper.conf` for [configuration store](#configuration-store).
+
+#### Local ZooKeeper
+
+The [`conf/zookeeper.conf`](reference-configuration.md#zookeeper) file handles the configuration for local ZooKeeper. The table below shows the available parameters:
+
+|Name|Description|Default|
+|---|---|---|
+|tickTime|  The tick is the basic unit of time in ZooKeeper, measured in milliseconds and used to regulate things like heartbeats and timeouts. tickTime is the length of a single tick.  |2000|
+|initLimit| The maximum time, in ticks, that the leader ZooKeeper server allows follower ZooKeeper servers to successfully connect and sync. The tick time is set in milliseconds using the tickTime parameter. |10|
+|syncLimit| The maximum time, in ticks, that a follower ZooKeeper server is allowed to sync with other ZooKeeper servers. The tick time is set in milliseconds using the tickTime parameter.  |5|
+|dataDir| The location where ZooKeeper stores in-memory database snapshots as well as the transaction log of updates to the database. |data/zookeeper|
+|clientPort|  The port on which the ZooKeeper server listens for connections. |2181|
+|autopurge.snapRetainCount| In ZooKeeper, auto purge determines how many recent snapshots of the database stored in dataDir to retain within the time interval specified by autopurge.purgeInterval (while deleting the rest).  |3|
+|autopurge.purgeInterval| The time interval, in hours, which triggers the ZooKeeper database purge task. Setting to a non-zero number enables auto purge; setting to 0 disables. Read this guide before enabling auto purge. |1|
+|maxClientCnxns|  The maximum number of client connections. Increase this if you need to handle more ZooKeeper clients. |60|
+
+
+#### Configuration Store
+
+The [`conf/global-zookeeper.conf`](reference-configuration.md#configuration-store) file handles the configuration for configuration store. The table below shows the available parameters:
+
+## BookKeeper
+
+BookKeeper stores all durable message in Pulsar. BookKeeper is a distributed [write-ahead log](https://en.wikipedia.org/wiki/Write-ahead_logging) WAL system that guarantees read consistency of independent message logs calls ledgers. Individual BookKeeper servers are also called *bookies*.
+
+> To manage message persistence, retention, and expiry in Pulsar, refer to [cookbook](cookbooks-retention-expiry).
+
+### Hardware requirements
+
+Bookie hosts store message data on disk. To provide optimal performance, ensure that the bookies have a suitable hardware configuration. The following are two key dimensions of bookie hardware capacity:
+
+- Disk I/O capacity read/write
+- Storage capacity
+
+Message entries written to bookies are always synced to disk before returning an acknowledgement to the Pulsar broker by default. To ensure low write latency, BookKeeper is designed to use multiple devices:
+
+- A **journal** to ensure durability. For sequential writes, it is critical to have fast [fsync](https://linux.die.net/man/2/fsync) operations on bookie hosts. Typically, small and fast [solid-state drives](https://en.wikipedia.org/wiki/Solid-state_drive) (SSDs) should suffice, or [hard disk drives](https://en.wikipedia.org/wiki/Hard_disk_drive) (HDDs) with a [RAID](https://en.wikipedia.org/wiki/RAID) controller and a battery-backed write cache. Both solutions can reach fsync latency of  [...]
+- A **ledger storage device** stores data. Writes happen in the background, so write I/O is not a big concern. Reads happen sequentially most of the time and the backlog is drained only in case of consumer drain. To store large amounts of data, a typical configuration involves multiple HDDs with a RAID controller.
+
+### Configure BookKeeper
+
+You can configure BookKeeper bookies using the [`conf/bookkeeper.conf`](reference-configuration.md#bookkeeper) configuration file. When you configure each bookie, ensure that the [`zkServers`](reference-configuration.md#bookkeeper-zkServers) parameter is set to the connection string for local ZooKeeper of the Pulsar cluster.
+
+The minimum configuration changes required in `conf/bookkeeper.conf` are as follows:
+
+```properties
+
+# Change to point to journal disk mount point
+journalDirectory=data/bookkeeper/journal
+
+# Point to ledger storage disk mount point
+ledgerDirectories=data/bookkeeper/ledgers
+
+# Point to local ZK quorum
+zkServers=zk1.example.com:2181,zk2.example.com:2181,zk3.example.com:2181
+
+```
+
+To change the ZooKeeper root path that BookKeeper uses, use `zkLedgersRootPath=/MY-PREFIX/ledgers` instead of `zkServers=localhost:2181/MY-PREFIX`.
+
+> For more information about BookKeeper, refer to the official [BookKeeper docs](http://bookkeeper.apache.org).
+
+### Deploy BookKeeper
+
+BookKeeper provides [persistent message storage](concepts-architecture-overview.md#persistent-storage) for Pulsar. Each Pulsar broker has its own cluster of bookies. The BookKeeper cluster shares a local ZooKeeper quorum with the Pulsar cluster.
+
+### Start bookies manually
+
+You can start a bookie in the foreground or as a background daemon.
+
+To start a bookie in the foreground, use the [`bookkeeper`](reference-cli-tools.md#bookkeeper) CLI tool:
+
+```bash
+
+$ bin/bookkeeper bookie
+
+```
+
+To start a bookie in the background, use the [`pulsar-daemon`](reference-cli-tools.md#pulsar-daemon) CLI tool:
+
+```bash
+
+$ bin/pulsar-daemon start bookie
+
+```
+
+You can verify whether the bookie works properly with the `bookiesanity` command for the [BookKeeper shell](reference-cli-tools.md#bookkeeper-shell):
+
+```shell
+
+$ bin/bookkeeper shell bookiesanity
+
+```
+
+When you use this command, you create a new ledger on the local bookie, write a few entries, read them back and finally delete the ledger.
+
+### Decommission bookies cleanly
+
+Before you decommission a bookie, you need to check your environment and meet the following requirements.
+
+1. Ensure the state of your cluster supports decommissioning the target bookie. Check if `EnsembleSize >= Write Quorum >= Ack Quorum` is `true` with one less bookie.
+
+2. Ensure the target bookie is listed after using the `listbookies` command.
+
+3. Ensure that no other process is ongoing (upgrade etc).
+
+And then you can decommission bookies safely. To decommission bookies, complete the following steps.
+
+1. Log in to the bookie node, check if there are underreplicated ledgers. The decommission command force to replicate the underreplicated ledgers.
+`$ bin/bookkeeper shell listunderreplicated`
+
+2. Stop the bookie by killing the bookie process. Make sure that no liveness/readiness probes setup for the bookies to spin them back up if you deploy it in a Kubernetes environment.
+
+3. Run the decommission command.
+   - If you have logged in to the node to be decommissioned, you do not need to provide `-bookieid`.
+   - If you are running the decommission command for the target bookie node from another bookie node, you should mention the target bookie ID in the arguments for `-bookieid`
+   `$ bin/bookkeeper shell decommissionbookie`
+   or
+   `$ bin/bookkeeper shell decommissionbookie -bookieid <target bookieid>`
+
+4. Validate that no ledgers are on the decommissioned bookie.   
+`$ bin/bookkeeper shell listledgers -bookieid <target bookieid>`
+
+You can run the following command to check if the bookie you have decommissioned is listed in the bookies list:
+
+```bash
+
+./bookkeeper shell listbookies -rw -h
+./bookkeeper shell listbookies -ro -h
+
+```
+
+## BookKeeper persistence policies
+
+In Pulsar, you can set *persistence policies* at the namespace level, which determines how BookKeeper handles persistent storage of messages. Policies determine four things:
+
+* The number of acks (guaranteed copies) to wait for each ledger entry.
+* The number of bookies to use for a topic.
+* The number of writes to make for each ledger entry.
+* The throttling rate for mark-delete operations.
+
+### Set persistence policies
+
+You can set persistence policies for BookKeeper at the [namespace](reference-terminology.md#namespace) level.
+
+#### Pulsar-admin
+
+Use the [`set-persistence`](reference-pulsar-admin.md#namespaces-set-persistence) subcommand and specify a namespace as well as any policies that you want to apply. The available flags are:
+
+Flag | Description | Default
+:----|:------------|:-------
+`-a`, `--bookkeeper-ack-quorum` | The number of acks (guaranteed copies) to wait on for each entry | 0
+`-e`, `--bookkeeper-ensemble` | The number of [bookies](reference-terminology.md#bookie) to use for topics in the namespace | 0
+`-w`, `--bookkeeper-write-quorum` | The number of writes to make for each entry | 0
+`-r`, `--ml-mark-delete-max-rate` | Throttling rate for mark-delete operations (0 means no throttle) | 0
+
+The following is an example:
+
+```shell
+
+$ pulsar-admin namespaces set-persistence my-tenant/my-ns \
+  --bookkeeper-ack-quorum 3 \
+  --bookkeeper-ensemble 2
+
+```
+
+#### REST API
+
+{@inject: endpoint|POST|/admin/v2/namespaces/:tenant/:namespace/persistence|operation/setPersistence?version=@pulsar:version_number@}
+
+#### Java
+
+```java
+
+int bkEnsemble = 2;
+int bkQuorum = 3;
+int bkAckQuorum = 2;
+double markDeleteRate = 0.7;
+PersistencePolicies policies =
+  new PersistencePolicies(ensemble, quorum, ackQuorum, markDeleteRate);
+admin.namespaces().setPersistence(namespace, policies);
+
+```
+
+### List persistence policies
+
+You can see which persistence policy currently applies to a namespace.
+
+#### Pulsar-admin
+
+Use the [`get-persistence`](reference-pulsar-admin.md#namespaces-get-persistence) subcommand and specify the namespace.
+
+The following is an example:
+
+```shell
+
+$ pulsar-admin namespaces get-persistence my-tenant/my-ns
+{
+  "bookkeeperEnsemble": 1,
+  "bookkeeperWriteQuorum": 1,
+  "bookkeeperAckQuorum", 1,
+  "managedLedgerMaxMarkDeleteRate": 0
+}
+
+```
+
+#### REST API
+
+{@inject: endpoint|GET|/admin/v2/namespaces/:tenant/:namespace/persistence|operation/getPersistence?version=@pulsar:version_number@}
+
+#### Java
+
+```java
+
+PersistencePolicies policies = admin.namespaces().getPersistence(namespace);
+
+```
+
+## How Pulsar uses ZooKeeper and BookKeeper
+
+This diagram illustrates the role of ZooKeeper and BookKeeper in a Pulsar cluster:
+
+![ZooKeeper and BookKeeper](/assets/pulsar-system-architecture.png)
+
+Each Pulsar cluster consists of one or more message brokers. Each broker relies on an ensemble of bookies.
diff --git a/site2/website-next/versioned_docs/version-2.6.0/client-libraries-cpp.md b/site2/website-next/versioned_docs/version-2.6.0/client-libraries-cpp.md
new file mode 100644
index 0000000..bb52d9e
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.6.0/client-libraries-cpp.md
@@ -0,0 +1,297 @@
+---
+id: client-libraries-cpp
+title: Pulsar C++ client
+sidebar_label: "C++"
+original_id: client-libraries-cpp
+---
+
+You can use Pulsar C++ client to create Pulsar producers and consumers in C++.
+
+All the methods in producer, consumer, and reader of a C++ client are thread-safe.
+
+## Supported platforms
+
+Pulsar C++ client is supported on **Linux** and **MacOS** platforms.
+
+[Doxygen](http://www.doxygen.nl/)-generated API docs for the C++ client are available [here](/api/cpp).
+
+## Linux
+
+> Since 2.1.0 release, Pulsar ships pre-built RPM and Debian packages. You can download and install those packages directly.
+
+Four kind of libraries `libpulsar.so` / `libpulsarnossl.so` / `libpulsar.a` / `libpulsarwithdeps.a` are included in your `/usr/lib` after rpm/deb download and install.
+By default, they are build under code path `${PULSAR_HOME}/pulsar-client-cpp`, using command
+ `cmake . -DBUILD_TESTS=OFF -DLINK_STATIC=ON && make pulsarShared pulsarSharedNossl pulsarStatic pulsarStaticWithDeps -j 3`
+These libraries rely on some other libraries, if you want to get detailed version of dependencies libraries, please reference [these](https://github.com/apache/pulsar/blob/master/pulsar-client-cpp/pkg/rpm/Dockerfile) [files](https://github.com/apache/pulsar/blob/master/pulsar-client-cpp/pkg/deb/Dockerfile).
+
+1. `libpulsar.so` is the Shared library, it contains statically linked `boost` and `openssl`, and will also dynamically link all other needed libraries.
+The command the when use this pulsar library is like this:
+
+```bash
+
+ g++ --std=c++11  PulsarTest.cpp -o test /usr/lib/libpulsar.so -I/usr/local/ssl/include
+
+```
+
+2. `libpulsarnossl.so` is the Shared library that similar to `libpulsar.so` except that the library `openssl` and `crypto` are dynamically linked.
+The command the when use this pulsar library is like this:
+
+```bash
+
+ g++ --std=c++11  PulsarTest.cpp -o test /usr/lib/libpulsarnossl.so -lssl -lcrypto -I/usr/local/ssl/include -L/usr/local/ssl/lib
+
+```
+
+3. `libpulsar.a` is the Static library, it need to load some dependencies library when using it. 
+The command the when use this pulsar library is like this:
+
+```bash
+
+ g++ --std=c++11  PulsarTest.cpp -o test /usr/lib/libpulsar.a -lssl -lcrypto -ldl -lpthread  -I/usr/local/ssl/include -L/usr/local/ssl/lib -lboost_system -lboost_regex -lcurl -lprotobuf -lzstd -lz
+
+```
+
+4. `libpulsarwithdeps.a` is the Static library, base on `libpulsar.a`, and archived in the dependencies libraries of `libboost_regex`,  `libboost_system`, `libcurl`, `libprotobuf`, `libzstd` and `libz`, 
+The command the when use this pulsar library is like this:
+
+```bash
+
+ g++ --std=c++11  PulsarTest.cpp -o test /usr/lib/libpulsarwithdeps.a -lssl -lcrypto -ldl -lpthread  -I/usr/local/ssl/include -L/usr/local/ssl/lib
+
+```
+
+`libpulsarwithdeps.a` does not include library openssl related libraries: `libssl` and `libcrypto`, because these 2 library is related to security, 
+by using user local system provided version is more reasonable, and more easy for user to handling security issue and library upgrade.
+
+### Install RPM
+
+1. Download a RPM package from the links in the table. 
+
+| Link | Crypto files |
+|------|--------------|
+| [client](@pulsar:dist_rpm:client@) | [asc](@pulsar:dist_rpm:client@.asc), [sha512](@pulsar:dist_rpm:client@.sha512) |
+| [client-debuginfo](@pulsar:dist_rpm:client-debuginfo@) | [asc](@pulsar:dist_rpm:client-debuginfo@.asc),  [sha512](@pulsar:dist_rpm:client-debuginfo@.sha512) |
+| [client-devel](@pulsar:dist_rpm:client-devel@) | [asc](@pulsar:dist_rpm:client-devel@.asc),  [sha512](@pulsar:dist_rpm:client-devel@.sha512) |
+
+2. Install the package using the following command.
+
+```bash
+
+$ rpm -ivh apache-pulsar-client*.rpm
+
+```
+
+After install, Pulsar libraries will be placed under `/usr/lib`.
+
+### Install Debian
+
+1. Download a Debian package from the links in the table. 
+
+| Link | Crypto files |
+|------|--------------|
+| [client](@pulsar:deb:client@) | [asc](@pulsar:dist_deb:client@.asc), [sha512](@pulsar:dist_deb:client@.sha512) |
+| [client-devel](@pulsar:deb:client-devel@) | [asc](@pulsar:dist_deb:client-devel@.asc),  [sha512](@pulsar:dist_deb:client-devel@.sha512) |
+
+2. Install the package using the following command:
+
+```bash
+
+$ apt install ./apache-pulsar-client*.deb
+
+```
+
+After install, Pulsar libraries will be placed under `/usr/lib`.
+
+### Build
+
+> If you want to build RPM and Debian packages from the latest master, follow the instructions below. All the instructions are run at the root directory of your cloned Pulsar repository.
+
+There are recipes that build RPM and Debian packages containing a
+statically linked `libpulsar.so` / `libpulsarnossl.so` / `libpulsar.a` / `libpulsarwithdeps.a` with all the required
+dependencies.
+
+To build the C++ library packages, build the Java packages first.
+
+```shell
+
+mvn install -DskipTests
+
+```
+
+#### RPM
+
+```shell
+
+pulsar-client-cpp/pkg/rpm/docker-build-rpm.sh
+
+```
+
+This builds the RPM inside a Docker container and it leaves the RPMs in `pulsar-client-cpp/pkg/rpm/RPMS/x86_64/`.
+
+| Package name | Content |
+|-----|-----|
+| pulsar-client | Shared library `libpulsar.so` and `libpulsarnossl.so` |
+| pulsar-client-devel | Static library `libpulsar.a`, `libpulsarwithdeps.a`and C++ and C headers |
+| pulsar-client-debuginfo | Debug symbols for `libpulsar.so` |
+
+#### Debian
+
+To build Debian packages, enter the following command.
+
+```shell
+
+pulsar-client-cpp/pkg/deb/docker-build-deb.sh
+
+```
+
+Debian packages are created at `pulsar-client-cpp/pkg/deb/BUILD/DEB/`.
+
+| Package name | Content |
+|-----|-----|
+| pulsar-client | Shared library `libpulsar.so` and `libpulsarnossl.so` |
+| pulsar-client-dev | Static library `libpulsar.a`, `libpulsarwithdeps.a` and C++ and C headers |
+
+## MacOS
+
+Pulsar releases are available in the [Homebrew](https://brew.sh/) core repository. You can install the C++ client library with the following command. The package is installed with the library and headers.
+
+```shell
+
+brew install libpulsar
+
+```
+
+## Connection URLs
+
+To connect to Pulsar using client libraries, you need to specify a Pulsar protocol URL.
+
+Pulsar protocol URLs are assigned to specific clusters, you can use the Pulsar URI scheme. The default port is `6650`. The following is an example for localhost.
+
+```http
+
+pulsar://localhost:6650
+
+```
+
+In a Pulsar cluster in production, the URL looks as follows: 
+
+```http
+
+pulsar://pulsar.us-west.example.com:6650
+
+```
+
+If you use TLS authentication, you need to add `ssl`, and the default port is `6651`. The following is an example.
+
+```http
+
+pulsar+ssl://pulsar.us-west.example.com:6651
+
+```
+
+## Create a consumer
+To connect to Pulsar as a consumer, you need to create a consumer on the C++ client. The following is an example. 
+
+```c++
+
+Client client("pulsar://localhost:6650");
+
+Consumer consumer;
+Result result = client.subscribe("my-topic", "my-subscription-name", consumer);
+if (result != ResultOk) {
+    LOG_ERROR("Failed to subscribe: " << result);
+    return -1;
+}
+
+Message msg;
+
+while (true) {
+    consumer.receive(msg);
+    LOG_INFO("Received: " << msg
+            << "  with payload '" << msg.getDataAsString() << "'");
+
+    consumer.acknowledge(msg);
+}
+
+client.close();
+
+```
+
+## Create a producer
+To connect to Pulsar as a producer, you need to create a producer on the C++ client. The following is an example. 
+
+```c++
+
+Client client("pulsar://localhost:6650");
+
+Producer producer;
+Result result = client.createProducer("my-topic", producer);
+if (result != ResultOk) {
+    LOG_ERROR("Error creating producer: " << result);
+    return -1;
+}
+
+// Publish 10 messages to the topic
+for (int i = 0; i < 10; i++){
+    Message msg = MessageBuilder().setContent("my-message").build();
+    Result res = producer.send(msg);
+    LOG_INFO("Message sent: " << res);
+}
+client.close();
+
+```
+
+## Enable authentication in connection URLs
+If you use TLS authentication when connecting to Pulsar, you need to add `ssl` in the connection URLs, and the default port is `6651`. The following is an example.
+
+```cpp
+
+ClientConfiguration config = ClientConfiguration();
+config.setUseTls(true);
+config.setTlsTrustCertsFilePath("/path/to/cacert.pem");
+config.setTlsAllowInsecureConnection(false);
+config.setAuth(pulsar::AuthTls::create(
+            "/path/to/client-cert.pem", "/path/to/client-key.pem"););
+
+Client client("pulsar+ssl://my-broker.com:6651", config);
+
+```
+
+For complete examples, refer to [C++ client examples](https://github.com/apache/pulsar/tree/master/pulsar-client-cpp/examples).
+
+## Schema
+
+This section describes some examples about schema. For more information about schema, see [Pulsar schema](schema-get-started).
+
+### Create producer with Avro schema
+
+The following example shows how to create a producer with an Avro schema.
+
+```cpp
+
+static const std::string exampleSchema =
+    "{\"type\":\"record\",\"name\":\"Example\",\"namespace\":\"test\","
+    "\"fields\":[{\"name\":\"a\",\"type\":\"int\"},{\"name\":\"b\",\"type\":\"int\"}]}";
+Producer producer;
+ProducerConfiguration producerConf;
+producerConf.setSchema(SchemaInfo(AVRO, "Avro", exampleSchema));
+client.createProducer("topic-avro", producerConf, producer);
+
+```
+
+### Create consumer with Avro schema
+
+The following example shows how to create a consumer with an Avro schema.
+
+```cpp
+
+static const std::string exampleSchema =
+    "{\"type\":\"record\",\"name\":\"Example\",\"namespace\":\"test\","
+    "\"fields\":[{\"name\":\"a\",\"type\":\"int\"},{\"name\":\"b\",\"type\":\"int\"}]}";
+ConsumerConfiguration consumerConf;
+Consumer consumer;
+consumerConf.setSchema(SchemaInfo(AVRO, "Avro", exampleSchema));
+client.subscribe("topic-avro", "sub-2", consumerConf, consumer)
+
+```
+
diff --git a/site2/website-next/versioned_docs/version-2.6.0/client-libraries-dotnet.md b/site2/website-next/versioned_docs/version-2.6.0/client-libraries-dotnet.md
new file mode 100644
index 0000000..ade664c
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.6.0/client-libraries-dotnet.md
@@ -0,0 +1,434 @@
+---
+id: client-libraries-dotnet
+title: Pulsar C# client
+sidebar_label: "C#"
+original_id: client-libraries-dotnet
+---
+
+You can use the Pulsar C# client (DotPulsar) to create Pulsar producers and consumers in C#. All the methods in the producer, consumer, and reader of a C# client are thread-safe. The official documentation for DotPulsar is available [here](https://github.com/apache/pulsar-dotpulsar/wiki).
+
+## Installation
+
+You can install the Pulsar C# client library either through the dotnet CLI or through the Visual Studio. This section describes how to install the Pulsar C# client library through the dotnet CLI. For information about how to install the Pulsar C# client library through the Visual Studio , see [here](https://docs.microsoft.com/en-us/visualstudio/mac/nuget-walkthrough?view=vsmac-2019).
+
+### Prerequisites
+
+Install the [.NET Core SDK](https://dotnet.microsoft.com/download/), which provides the dotnet command-line tool. Starting in Visual Studio 2017, the dotnet CLI is automatically installed with any .NET Core related workloads.
+
+### Procedures
+
+To install the Pulsar C# client library, following these steps:
+
+1. Create a project.
+
+   1. Create a folder for the project.
+
+   2. Open a terminal window and switch to the new folder.
+
+   3. Create the project using the following command.
+
+       ```
+       
+       dotnet new console
+       
+       ```
+
+   4. Use `dotnet run` to test that the app has been created properly.
+
+2. Add the DotPulsar NuGet package.
+
+   1. Use the following command to install the `DotPulsar` package.
+
+       ```
+       
+       dotnet add package DotPulsar
+       
+       ```
+
+   2. After the command completes, open the `.csproj` file to see the added reference.
+
+       ```xml
+       
+       <ItemGroup>
+         <PackageReference Include="DotPulsar" Version="0.11.0" />
+       </ItemGroup>
+       
+       ```
+
+## Client
+
+This section describes some configuration examples for the Pulsar C# client.
+
+### Create client
+
+This example shows how to create a Pulsar C# client connected to localhost.
+
+```c#
+
+var client = PulsarClient.Builder().Build();
+
+```
+
+To create a Pulsar C# client by using the builder, you can specify the following options.
+
+| Option | Description | Default |
+| ---- | ---- | ---- |
+| ServiceUrl | Set the service URL for the Pulsar cluster. | pulsar://localhost:6650 |
+| RetryInterval | Set the time to wait before retrying an operation or a reconnection. | 3s |
+
+### Create producer
+
+This section describes how to create a producer.
+
+- Create a producer by using the builder.
+
+  ```c#
+  
+  var producer = client.NewProducer()
+                       .Topic("persistent://public/default/mytopic")
+                       .Create();
+  
+  ```
+
+- Create a producer without using the builder.
+
+  ```c#
+  
+  var options = new ProducerOptions("persistent://public/default/mytopic");
+  var producer = client.CreateProducer(options);
+  
+  ```
+
+### Create consumer
+
+This section describes how to create a consumer.
+
+- Create a consumer by using the builder.
+
+  ```c#
+  
+  var consumer = client.NewConsumer()
+                       .SubscriptionName("MySubscription")
+                       .Topic("persistent://public/default/mytopic")
+                       .Create();
+  
+  ```
+
+- Create a consumer without using the builder.
+
+  ```c#
+  
+  var options = new ConsumerOptions("MySubscription", "persistent://public/default/mytopic");
+  var consumer = client.CreateConsumer(options);
+  
+  ```
+
+### Create reader
+
+This section describes how to create a reader.
+
+- Create a reader by using the builder.
+
+  ```c#
+  
+  var reader = client.NewReader()
+                     .StartMessageId(MessageId.Earliest)
+                     .Topic("persistent://public/default/mytopic")
+                     .Create();
+  
+  ```
+
+- Create a reader without using the builder.
+
+  ```c#
+  
+  var options = new ReaderOptions(MessageId.Earliest, "persistent://public/default/mytopic");
+  var reader = client.CreateReader(options);
+  
+  ```
+
+### Configure encryption policies
+
+The Pulsar C# client supports four kinds of encryption policies:
+
+- `EnforceUnencrypted`: always use unencrypted connections.
+- `EnforceEncrypted`: always use encrypted connections)
+- `PreferUnencrypted`: use unencrypted connections, if possible.
+- `PreferEncrypted`: use encrypted connections, if possible.
+
+This example shows how to set the `EnforceUnencrypted` encryption policy.
+
+```c#
+
+var client = PulsarClient.Builder()
+                         .ConnectionSecurity(EncryptionPolicy.EnforceEncrypted)
+                         .Build();
+
+```
+
+### Configure authentication
+
+Currently, the Pulsar C# client supports the TLS (Transport Layer Security) and JWT (JSON Web Token) authentication.
+
+If you have followed [Authentication using TLS](security-tls-authentication), you get a certificate and a key. To use them from the Pulsar C# client, follow these steps:
+
+1. Create an unencrypted and password-less pfx file.
+
+   ```c#
+   
+   openssl pkcs12 -export -keypbe NONE -certpbe NONE -out admin.pfx -inkey admin.key.pem -in admin.cert.pem -passout pass:
+   
+   ```
+
+2. Use the admin.pfx file to create an X509Certificate2 and pass it to the Pulsar C# client.
+
+   ```c#
+   
+   var clientCertificate = new X509Certificate2("admin.pfx");
+   var client = PulsarClient.Builder()
+                            .AuthenticateUsingClientCertificate(clientCertificate)
+                            .Build();
+   
+   ```
+
+## Producer
+
+A producer is a process that attaches to a topic and publishes messages to a Pulsar broker for processing. This section describes some configuration examples about the producer.
+
+## Send data
+
+This example shows how to send data.
+
+```c#
+
+var data = Encoding.UTF8.GetBytes("Hello World");
+await producer.Send(data);
+
+```
+
+### Send messages with customized metadata
+
+- Send messages with customized metadata by using the builder.
+
+  ```c#
+  
+  var data = Encoding.UTF8.GetBytes("Hello World");
+  var messageId = await producer.NewMessage()
+                                .Property("SomeKey", "SomeValue")
+                                .Send(data);
+  
+  ```
+
+- Send messages with customized metadata without using the builder.
+
+  ```c#
+  
+  var data = Encoding.UTF8.GetBytes("Hello World");
+  var metadata = new MessageMetadata();
+  metadata["SomeKey"] = "SomeValue";
+  var messageId = await producer.Send(metadata, data));
+  
+  ```
+
+## Consumer
+
+A consumer is a process that attaches to a topic through a subscription and then receives messages. This section describes some configuration examples about the consumer.
+
+### Receive messages
+
+This example shows how a consumer receives messages from a topic.
+
+```c#
+
+await foreach (var message in consumer.Messages())
+{
+    Console.WriteLine("Received: " + Encoding.UTF8.GetString(message.Data.ToArray()));
+}
+
+```
+
+### Acknowledge messages
+
+Messages can be acknowledged individually or cumulatively. For details about message acknowledgement, see [acknowledgement](concepts-messaging.md#acknowledgement).
+
+- Acknowledge messages individually.
+
+  ```c#
+  
+  await foreach (var message in consumer.Messages())
+  {
+      Console.WriteLine("Received: " + Encoding.UTF8.GetString(message.Data.ToArray()));
+  }
+  
+  ```
+
+- Acknowledge messages cumulatively.
+
+  ```c#
+  
+  await consumer.AcknowledgeCumulative(message);
+  
+  ```
+
+### Unsubscribe from topics
+
+This example shows how a consumer unsubscribes from a topic.
+
+```c#
+
+await consumer.Unsubscribe();
+
+```
+
+#### Note
+
+> A consumer cannot be used and is disposed once the consumer unsubscribes from a topic.
+
+## Reader
+
+A reader is actually just a consumer without a cursor. This means that Pulsar does not keep track of your progress and there is no need to acknowledge messages.
+
+This example shows how a reader receives messages.
+
+```c#
+
+await foreach (var message in reader.Messages())
+{
+    Console.WriteLine("Received: " + Encoding.UTF8.GetString(message.Data.ToArray()));
+}
+
+```
+
+## Monitoring
+
+This section describes how to monitor the producer, consumer, and reader state.
+
+### Monitor producer
+
+The following table lists states available for the producer.
+
+| State | Description |
+| ---- | ----|
+| Closed | The producer or the Pulsar client has been disposed. |
+| Connected | All is well. |
+| Disconnected | The connection is lost and attempts are being made to reconnect. |
+| Faulted | An unrecoverable error has occurred. |
+
+This example shows how to monitor the producer state.
+
+```c#
+
+private static async ValueTask Monitor(IProducer producer, CancellationToken cancellationToken)
+{
+    var state = ProducerState.Disconnected;
+
+    while (!cancellationToken.IsCancellationRequested)
+    {
+        state = await producer.StateChangedFrom(state, cancellationToken);
+
+        var stateMessage = state switch
+        {
+            ProducerState.Connected => $"The producer is connected",
+            ProducerState.Disconnected => $"The producer is disconnected",
+            ProducerState.Closed => $"The producer has closed",
+            ProducerState.Faulted => $"The producer has faulted",
+            _ => $"The producer has an unknown state '{state}'"
+        };
+
+        Console.WriteLine(stateMessage);
+
+        if (producer.IsFinalState(state))
+            return;
+    }
+}
+
+```
+
+### Monitor consumer state
+
+The following table lists states available for the consumer.
+
+| State | Description |
+| ---- | ----|
+| Active | All is well. |
+| Inactive | All is well. The subscription type is `Failover` and you are not the active consumer. |
+| Closed | The consumer or the Pulsar client has been disposed. |
+| Disconnected | The connection is lost and attempts are being made to reconnect. |
+| Faulted | An unrecoverable error has occurred. |
+| ReachedEndOfTopic | No more messages are delivered. |
+
+This example shows how to monitor the consumer state.
+
+```c#
+
+private static async ValueTask Monitor(IConsumer consumer, CancellationToken cancellationToken)
+{
+    var state = ConsumerState.Disconnected;
+
+    while (!cancellationToken.IsCancellationRequested)
+    {
+        state = await consumer.StateChangedFrom(state, cancellationToken);
+
+        var stateMessage = state switch
+        {
+            ConsumerState.Active => "The consumer is active",
+            ConsumerState.Inactive => "The consumer is inactive",
+            ConsumerState.Disconnected => "The consumer is disconnected",
+            ConsumerState.Closed => "The consumer has closed",
+            ConsumerState.ReachedEndOfTopic => "The consumer has reached end of topic",
+            ConsumerState.Faulted => "The consumer has faulted",
+            _ => $"The consumer has an unknown state '{state}'"
+        };
+
+        Console.WriteLine(stateMessage);
+
+        if (consumer.IsFinalState(state))
+            return;
+    }
+}
+
+```
+
+### Monitor reader state
+
+The following table lists states available for the reader.
+
+| State | Description |
+| ---- | ----|
+| Closed | The reader or the Pulsar client has been disposed. |
+| Connected | All is well. |
+| Disconnected | The connection is lost and attempts are being made to reconnect.
+| Faulted | An unrecoverable error has occurred. |
+| ReachedEndOfTopic | No more messages are delivered. |
+
+This example shows how to monitor the reader state.
+
+```c#
+
+private static async ValueTask Monitor(IReader reader, CancellationToken cancellationToken)
+{
+    var state = ReaderState.Disconnected;
+
+    while (!cancellationToken.IsCancellationRequested)
+    {
+        state = await reader.StateChangedFrom(state, cancellationToken);
+
+        var stateMessage = state switch
+        {
+            ReaderState.Connected => "The reader is connected",
+            ReaderState.Disconnected => "The reader is disconnected",
+            ReaderState.Closed => "The reader has closed",
+            ReaderState.ReachedEndOfTopic => "The reader has reached end of topic",
+            ReaderState.Faulted => "The reader has faulted",
+            _ => $"The reader has an unknown state '{state}'"
+        };
+
+        Console.WriteLine(stateMessage);
+
+        if (reader.IsFinalState(state))
+            return;
+    }
+}
+
+```
+
diff --git a/site2/website-next/versioned_docs/version-2.6.0/client-libraries-go.md b/site2/website-next/versioned_docs/version-2.6.0/client-libraries-go.md
new file mode 100644
index 0000000..46f6342
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.6.0/client-libraries-go.md
@@ -0,0 +1,699 @@
+---
+id: client-libraries-go
+title: Pulsar Go client
+sidebar_label: "Go"
+original_id: client-libraries-go
+---
+
+> Tips: Currently, the CGo client will be deprecated, if you want to know more about the CGo client, please refer to [CGo client docs](client-libraries-cgo)
+
+You can use Pulsar [Go client](https://github.com/apache/pulsar-client-go) to create Pulsar [producers](#producers), [consumers](#consumers), and [readers](#readers) in Go (aka Golang).
+
+> **API docs available as well**  
+> For standard API docs, consult the [Godoc](https://godoc.org/github.com/apache/pulsar-client-go/pulsar).
+
+
+## Installation
+
+### Install go package
+
+You can install the `pulsar` library locally using `go get`.  
+
+```bash
+
+$ go get -u "github.com/apache/pulsar-client-go/pulsar"
+
+```
+
+Once installed locally, you can import it into your project:
+
+```go
+
+import "github.com/apache/pulsar-client-go/pulsar"
+
+```
+
+## Connection URLs
+
+To connect to Pulsar using client libraries, you need to specify a [Pulsar protocol](developing-binary-protocol) URL.
+
+Pulsar protocol URLs are assigned to specific clusters, use the `pulsar` scheme and have a default port of 6650. Here's an example for `localhost`:
+
+```http
+
+pulsar://localhost:6650
+
+```
+
+A URL for a production Pulsar cluster may look something like this:
+
+```http
+
+pulsar://pulsar.us-west.example.com:6650
+
+```
+
+If you're using [TLS](security-tls-authentication) authentication, the URL will look like something like this:
+
+```http
+
+pulsar+ssl://pulsar.us-west.example.com:6651
+
+```
+
+## Create a client
+
+In order to interact with Pulsar, you'll first need a `Client` object. You can create a client object using the `NewClient` function, passing in a `ClientOptions` object (more on configuration [below](#client-configuration)). Here's an example:
+
+```go
+
+import (
+	"log"
+	"time"
+
+	"github.com/apache/pulsar-client-go/pulsar"
+)
+
+func main() {
+	client, err := pulsar.NewClient(pulsar.ClientOptions{
+		URL:               "pulsar://localhost:6650",
+		OperationTimeout:  30 * time.Second,
+		ConnectionTimeout: 30 * time.Second,
+	})
+	if err != nil {
+		log.Fatalf("Could not instantiate Pulsar client: %v", err)
+	}
+
+	defer client.Close()
+}
+
+```
+
+The following configurable parameters are available for Pulsar clients:
+
+ Name | Description | Default
+| :-------- | :---------- |:---------- |
+| URL | Configure the service URL for the Pulsar service. This parameter is required | |
+| ConnectionTimeout | Timeout for the establishment of a TCP connection | 30s |
+| OperationTimeout| Set the operation timeout. Producer-create, subscribe and unsubscribe operations will be retried until this interval, after which the operation will be marked as failed| 30s|
+| Authentication | Configure the authentication provider. Example: `Authentication: NewAuthenticationTLS("my-cert.pem", "my-key.pem")` | no authentication |
+| TLSTrustCertsFilePath | Set the path to the trusted TLS certificate file | |
+| TLSAllowInsecureConnection | Configure whether the Pulsar client accept untrusted TLS certificate from broker | false |
+| TLSValidateHostname | Configure whether the Pulsar client verify the validity of the host name from broker | false |
+
+## Producers
+
+Pulsar producers publish messages to Pulsar topics. You can [configure](#producer-configuration) Go producers using a `ProducerOptions` object. Here's an example:
+
+```go
+
+producer, err := client.CreateProducer(pulsar.ProducerOptions{
+	Topic: "my-topic",
+})
+
+_, err = producer.Send(context.Background(), &pulsar.ProducerMessage{
+	Payload: []byte("hello"),
+})
+
+defer producer.Close()
+
+if err != nil {
+	fmt.Println("Failed to publish message", err)
+}
+fmt.Println("Published message")
+
+```
+
+### Producer operations
+
+Pulsar Go producers have the following methods available:
+
+Method | Description | Return type
+:------|:------------|:-----------
+`Topic()` | Fetches the producer's [topic](reference-terminology.md#topic)| `string`
+`Name()` | Fetches the producer's name | `string`
+`Send(context.Context, *ProducerMessage)` | Publishes a [message](#messages) to the producer's topic. This call will block until the message is successfully acknowledged by the Pulsar broker, or an error will be thrown if the timeout set using the `SendTimeout` in the producer's [configuration](#producer-configuration) is exceeded. | (MessageID, error)
+`SendAsync(context.Context, *ProducerMessage, func(MessageID, *ProducerMessage, error))`| Send a message, this call will be blocking until is successfully acknowledged by the Pulsar broker. | 
+`LastSequenceID()` | Get the last sequence id that was published by this producer. his represent either the automatically assigned or custom sequence id (set on the ProducerMessage) that was published and acknowledged by the broker. | int64
+`Flush()`| Flush all the messages buffered in the client and wait until all messages have been successfully persisted. | error
+`Close()` | Closes the producer and releases all resources allocated to it. If `Close()` is called then no more messages will be accepted from the publisher. This method will block until all pending publish requests have been persisted by Pulsar. If an error is thrown, no pending writes will be retried. | 
+
+### Producer Example
+
+#### How to use message router in producer
+
+```go
+
+client, err := NewClient(ClientOptions{
+	URL: serviceURL,
+})
+
+if err != nil {
+	log.Fatal(err)
+}
+defer client.Close()
+
+// Only subscribe on the specific partition
+consumer, err := client.Subscribe(ConsumerOptions{
+	Topic:            "my-partitioned-topic-partition-2",
+	SubscriptionName: "my-sub",
+})
+
+if err != nil {
+	log.Fatal(err)
+}
+defer consumer.Close()
+
+producer, err := client.CreateProducer(ProducerOptions{
+	Topic: "my-partitioned-topic",
+	MessageRouter: func(msg *ProducerMessage, tm TopicMetadata) int {
+		fmt.Println("Routing message ", msg, " -- Partitions: ", tm.NumPartitions())
+		return 2
+	},
+})
+
+if err != nil {
+	log.Fatal(err)
+}
+defer producer.Close()
+
+```
+
+#### How to use delay relative in producer
+
+```go
+
+client, err := NewClient(ClientOptions{
+	URL: "pulsar://localhost:6650",
+})
+if err != nil {
+	log.Fatal(err)
+}
+defer client.Close()
+
+topicName := newTopicName()
+producer, err := client.CreateProducer(ProducerOptions{
+	Topic: topicName,
+})
+if err != nil {
+	log.Fatal(err)
+}
+defer producer.Close()
+
+consumer, err := client.Subscribe(ConsumerOptions{
+	Topic:            topicName,
+	SubscriptionName: "subName",
+	Type:             Shared,
+})
+if err != nil {
+	log.Fatal(err)
+}
+defer consumer.Close()
+
+ID, err := producer.Send(context.Background(), &ProducerMessage{
+	Payload:      []byte(fmt.Sprintf("test")),
+	DeliverAfter: 3 * time.Second,
+})
+if err != nil {
+	log.Fatal(err)
+}
+fmt.Println(ID)
+
+ctx, canc := context.WithTimeout(context.Background(), 1*time.Second)
+msg, err := consumer.Receive(ctx)
+if err != nil {
+	log.Fatal(err)
+}
+fmt.Println(msg.Payload())
+canc()
+
+ctx, canc = context.WithTimeout(context.Background(), 5*time.Second)
+msg, err = consumer.Receive(ctx)
+if err != nil {
+	log.Fatal(err)
+}
+fmt.Println(msg.Payload())
+canc()
+
+```
+
+### Producer configuration
+
+ Name | Description | Default
+| :-------- | :---------- |:---------- |
+| Topic | Topic specify the topic this consumer will subscribe to. This argument is required when constructing the reader. | |
+| Name | Name specify a name for the producer. If not assigned, the system will generate a globally unique name which can be access with Producer.ProducerName(). | | 
+| Properties | Properties attach a set of application defined properties to the producer This properties will be visible in the topic stats | |
+| MaxPendingMessages| MaxPendingMessages set the max size of the queue holding the messages pending to receive an acknowledgment from the broker. | |
+| HashingScheme | HashingScheme change the `HashingScheme` used to chose the partition on where to publish a particular message. | JavaStringHash |
+| CompressionType | CompressionType set the compression type for the producer. | not compressed | 
+| MessageRouter | MessageRouter set a custom message routing policy by passing an implementation of MessageRouter | |
+| DisableBatching | DisableBatching control whether automatic batching of messages is enabled for the producer. | false |
+| BatchingMaxPublishDelay | BatchingMaxPublishDelay set the time period within which the messages sent will be batched | 1ms |
+| BatchingMaxMessages | BatchingMaxMessages set the maximum number of messages permitted in a batch. | 1000 | 
+
+## Consumers
+
+Pulsar consumers subscribe to one or more Pulsar topics and listen for incoming messages produced on that topic/those topics. You can [configure](#consumer-configuration) Go consumers using a `ConsumerOptions` object. Here's a basic example that uses channels:
+
+```go
+
+consumer, err := client.Subscribe(pulsar.ConsumerOptions{
+	Topic:            "topic-1",
+	SubscriptionName: "my-sub",
+	Type:             pulsar.Shared,
+})
+if err != nil {
+	log.Fatal(err)
+}
+defer consumer.Close()
+
+for i := 0; i < 10; i++ {
+	msg, err := consumer.Receive(context.Background())
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	fmt.Printf("Received message msgId: %#v -- content: '%s'\n",
+		msg.ID(), string(msg.Payload()))
+
+	consumer.Ack(msg)
+}
+
+if err := consumer.Unsubscribe(); err != nil {
+	log.Fatal(err)
+}
+
+```
+
+### Consumer operations
+
+Pulsar Go consumers have the following methods available:
+
+Method | Description | Return type
+:------|:------------|:-----------
+`Subscription()` | Returns the consumer's subscription name | `string`
+`Unsubcribe()` | Unsubscribes the consumer from the assigned topic. Throws an error if the unsubscribe operation is somehow unsuccessful. | `error`
+`Receive(context.Context)` | Receives a single message from the topic. This method blocks until a message is available. | `(Message, error)`
+`Ack(Message)` | [Acknowledges](reference-terminology.md#acknowledgment-ack) a message to the Pulsar [broker](reference-terminology.md#broker) | 
+`AckID(MessageID)` | [Acknowledges](reference-terminology.md#acknowledgment-ack) a message to the Pulsar [broker](reference-terminology.md#broker) by message ID | 
+`Nack(Message)` | Acknowledge the failure to process a single message. | 
+`NackID(MessageID)` | Acknowledge the failure to process a single message. | 
+`Seek(msgID MessageID)` | Reset the subscription associated with this consumer to a specific message id. The message id can either be a specific message or represent the first or last messages in the topic. | `error`
+`SeekByTime(time time.Time)` | Reset the subscription associated with this consumer to a specific message publish time. | `error`
+`Close()` | Closes the consumer, disabling its ability to receive messages from the broker | 
+
+### Receive example
+
+#### How to use regx consumer
+
+```go
+
+client, err := pulsar.NewClient(pulsar.ClientOptions{
+    URL: "pulsar://localhost:6650",
+})
+
+defer client.Close()
+
+p, err := client.CreateProducer(ProducerOptions{
+	Topic:           topicInRegex,
+	DisableBatching: true,
+})
+if err != nil {
+	log.Fatal(err)
+}
+defer p.Close()
+
+topicsPattern := fmt.Sprintf("persistent://%s/foo.*", namespace)
+opts := ConsumerOptions{
+	TopicsPattern:    topicsPattern,
+	SubscriptionName: "regex-sub",
+}
+consumer, err := client.Subscribe(opts)
+if err != nil {
+	log.Fatal(err)
+}
+defer consumer.Close()
+
+```
+
+#### How to use multi topics Consumer
+
+```go
+
+func newTopicName() string {
+	return fmt.Sprintf("my-topic-%v", time.Now().Nanosecond())
+}
+
+
+topic1 := "topic-1"
+topic2 := "topic-2"
+
+client, err := NewClient(ClientOptions{
+	URL: "pulsar://localhost:6650",
+})
+if err != nil {
+	log.Fatal(err)
+}
+topics := []string{topic1, topic2}
+consumer, err := client.Subscribe(ConsumerOptions{
+	Topics:           topics,
+	SubscriptionName: "multi-topic-sub",
+})
+if err != nil {
+	log.Fatal(err)
+}
+defer consumer.Close()
+
+```
+
+#### How to use consumer listener
+
+```go
+
+import (
+	"fmt"
+	"log"
+
+	"github.com/apache/pulsar-client-go/pulsar"
+)
+
+func main() {
+	client, err := pulsar.NewClient(pulsar.ClientOptions{URL: "pulsar://localhost:6650"})
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	defer client.Close()
+
+	channel := make(chan pulsar.ConsumerMessage, 100)
+
+	options := pulsar.ConsumerOptions{
+		Topic:            "topic-1",
+		SubscriptionName: "my-subscription",
+		Type:             pulsar.Shared,
+	}
+
+	options.MessageChannel = channel
+
+	consumer, err := client.Subscribe(options)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	defer consumer.Close()
+
+	// Receive messages from channel. The channel returns a struct which contains message and the consumer from where
+	// the message was received. It's not necessary here since we have 1 single consumer, but the channel could be
+	// shared across multiple consumers as well
+	for cm := range channel {
+		msg := cm.Message
+		fmt.Printf("Received message  msgId: %v -- content: '%s'\n",
+			msg.ID(), string(msg.Payload()))
+
+		consumer.Ack(msg)
+	}
+}
+
+```
+
+#### How to use consumer receive timeout
+
+```go
+
+client, err := NewClient(ClientOptions{
+	URL: "pulsar://localhost:6650",
+})
+if err != nil {
+	log.Fatal(err)
+}
+defer client.Close()
+
+topic := "test-topic-with-no-messages"
+ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
+defer cancel()
+
+// create consumer
+consumer, err := client.Subscribe(ConsumerOptions{
+	Topic:            topic,
+	SubscriptionName: "my-sub1",
+	Type:             Shared,
+})
+if err != nil {
+	log.Fatal(err)
+}
+defer consumer.Close()
+
+msg, err := consumer.Receive(ctx)
+fmt.Println(msg.Payload())
+if err != nil {
+	log.Fatal(err)
+}
+
+```
+
+### Consumer configuration
+
+ Name | Description | Default
+| :-------- | :---------- |:---------- |
+| Topic | Topic specify the topic this consumer will subscribe to. This argument is required when constructing the reader. | |
+| Topics | Specify a list of topics this consumer will subscribe on. Either a topic, a list of topics or a topics pattern are required when subscribing| |
+| TopicsPattern | Specify a regular expression to subscribe to multiple topics under the same namespace. Either a topic, a list of topics or a topics pattern are required when subscribing | |
+| AutoDiscoveryPeriod | Specify the interval in which to poll for new partitions or new topics if using a TopicsPattern. | |
+| SubscriptionName | Specify the subscription name for this consumer. This argument is required when subscribing | |
+| Name | Set the consumer name | | 
+| Properties | Properties attach a set of application defined properties to the producer This properties will be visible in the topic stats | |
+| Type | Select the subscription type to be used when subscribing to the topic. | Exclusive |
+| SubscriptionInitialPosition | InitialPosition at which the cursor will be set when subscribe | Latest |
+| DLQ | Configuration for Dead Letter Queue consumer policy. | no DLQ | 
+| MessageChannel | Sets a `MessageChannel` for the consumer. When a message is received, it will be pushed to the channel for consumption | | 
+| ReceiverQueueSize | Sets the size of the consumer receive queue. | 1000| 
+| NackRedeliveryDelay | The delay after which to redeliver the messages that failed to be processed | 1min |
+| ReadCompacted | If enabled, the consumer will read messages from the compacted topic rather than reading the full message backlog of the topic | false |
+| ReplicateSubscriptionState | Mark the subscription as replicated to keep it in sync across clusters | false |
+
+## Readers
+
+Pulsar readers process messages from Pulsar topics. Readers are different from consumers because with readers you need to explicitly specify which message in the stream you want to begin with (consumers, on the other hand, automatically begin with the most recent unacked message). You can [configure](#reader-configuration) Go readers using a `ReaderOptions` object. Here's an example:
+
+```go
+
+reader, err := client.CreateReader(pulsar.ReaderOptions{
+	Topic:          "topic-1",
+	StartMessageID: pulsar.EarliestMessageID(),
+})
+if err != nil {
+	log.Fatal(err)
+}
+defer reader.Close()
+
+```
+
+### Reader operations
+
+Pulsar Go readers have the following methods available:
+
+Method | Description | Return type
+:------|:------------|:-----------
+`Topic()` | Returns the reader's [topic](reference-terminology.md#topic) | `string`
+`Next(context.Context)` | Receives the next message on the topic (analogous to the `Receive` method for [consumers](#consumer-operations)). This method blocks until a message is available. | `(Message, error)`
+`HasNext()` | Check if there is any message available to read from the current position| (bool, error)
+`Close()` | Closes the reader, disabling its ability to receive messages from the broker | `error`
+
+### Reader example
+
+#### How to use reader to read 'next' message
+
+Here's an example usage of a Go reader that uses the `Next()` method to process incoming messages:
+
+```go
+
+import (
+	"context"
+	"fmt"
+	"log"
+
+	"github.com/apache/pulsar-client-go/pulsar"
+)
+
+func main() {
+	client, err := pulsar.NewClient(pulsar.ClientOptions{URL: "pulsar://localhost:6650"})
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	defer client.Close()
+
+	reader, err := client.CreateReader(pulsar.ReaderOptions{
+		Topic:          "topic-1",
+		StartMessageID: pulsar.EarliestMessageID(),
+	})
+	if err != nil {
+		log.Fatal(err)
+	}
+	defer reader.Close()
+
+	for reader.HasNext() {
+		msg, err := reader.Next(context.Background())
+		if err != nil {
+			log.Fatal(err)
+		}
+
+		fmt.Printf("Received message msgId: %#v -- content: '%s'\n",
+			msg.ID(), string(msg.Payload()))
+	}
+}
+
+```
+
+In the example above, the reader begins reading from the earliest available message (specified by `pulsar.EarliestMessage`). The reader can also begin reading from the latest message (`pulsar.LatestMessage`) or some other message ID specified by bytes using the `DeserializeMessageID` function, which takes a byte array and returns a `MessageID` object. Here's an example:
+
+```go
+
+lastSavedId := // Read last saved message id from external store as byte[]
+
+reader, err := client.CreateReader(pulsar.ReaderOptions{
+    Topic:          "my-golang-topic",
+    StartMessageID: pulsar.DeserializeMessageID(lastSavedId),
+})
+
+```
+
+#### How to use reader to read specific message
+
+```go
+
+client, err := NewClient(ClientOptions{
+	URL: lookupURL,
+})
+
+if err != nil {
+	log.Fatal(err)
+}
+defer client.Close()
+
+topic := "topic-1"
+ctx := context.Background()
+
+// create producer
+producer, err := client.CreateProducer(ProducerOptions{
+	Topic:           topic,
+	DisableBatching: true,
+})
+if err != nil {
+	log.Fatal(err)
+}
+defer producer.Close()
+
+// send 10 messages
+msgIDs := [10]MessageID{}
+for i := 0; i < 10; i++ {
+	msgID, err := producer.Send(ctx, &ProducerMessage{
+		Payload: []byte(fmt.Sprintf("hello-%d", i)),
+	})
+	assert.NoError(t, err)
+	assert.NotNil(t, msgID)
+	msgIDs[i] = msgID
+}
+
+// create reader on 5th message (not included)
+reader, err := client.CreateReader(ReaderOptions{
+	Topic:          topic,
+	StartMessageID: msgIDs[4],
+})
+
+if err != nil {
+	log.Fatal(err)
+}
+defer reader.Close()
+
+// receive the remaining 5 messages
+for i := 5; i < 10; i++ {
+	msg, err := reader.Next(context.Background())
+	if err != nil {
+	log.Fatal(err)
+}
+
+// create reader on 5th message (included)
+readerInclusive, err := client.CreateReader(ReaderOptions{
+	Topic:                   topic,
+	StartMessageID:          msgIDs[4],
+	StartMessageIDInclusive: true,
+})
+
+if err != nil {
+	log.Fatal(err)
+}
+defer readerInclusive.Close()
+
+```
+
+### Reader configuration
+
+ Name | Description | Default
+| :-------- | :---------- |:---------- |
+| Topic | Topic specify the topic this consumer will subscribe to. This argument is required when constructing the reader. | |
+| Name | Name set the reader name. | | 
+| Properties | Attach a set of application defined properties to the reader. This properties will be visible in the topic stats | |
+| StartMessageID | StartMessageID initial reader positioning is done by specifying a message id. | |
+| StartMessageIDInclusive | If true, the reader will start at the `StartMessageID`, included. Default is `false` and the reader will start from the "next" message | false |
+| MessageChannel | MessageChannel sets a `MessageChannel` for the consumer When a message is received, it will be pushed to the channel for consumption| |
+| ReceiverQueueSize | ReceiverQueueSize sets the size of the consumer receive queue. | 1000 |
+| SubscriptionRolePrefix| SubscriptionRolePrefix set the subscription role prefix. | “reader” | 
+| ReadCompacted | If enabled, the reader will read messages from the compacted topic rather than reading the full message backlog of the topic.  ReadCompacted can only be enabled when reading from a persistent topic. | false|
+
+## Messages
+
+The Pulsar Go client provides a `ProducerMessage` interface that you can use to construct messages to producer on Pulsar topics. Here's an example message:
+
+```go
+
+msg := pulsar.ProducerMessage{
+    Payload: []byte("Here is some message data"),
+    Key: "message-key",
+    Properties: map[string]string{
+        "foo": "bar",
+    },
+    EventTime: time.Now(),
+    ReplicationClusters: []string{"cluster1", "cluster3"},
+}
+
+if _, err := producer.send(msg); err != nil {
+    log.Fatalf("Could not publish message due to: %v", err)
+}
+
+```
+
+The following methods parameters are available for `ProducerMessage` objects:
+
+Parameter | Description
+:---------|:-----------
+`Payload` | The actual data payload of the message
+`Key` | The optional key associated with the message (particularly useful for things like topic compaction)
+`Properties` | A key-value map (both keys and values must be strings) for any application-specific metadata attached to the message
+`EventTime` | The timestamp associated with the message
+`ReplicationClusters` | The clusters to which this message will be replicated. Pulsar brokers handle message replication automatically; you should only change this setting if you want to override the broker default.
+`SequenceID` | Set the sequence id to assign to the current message
+`DeliverAfter` | Request to deliver the message only after the specified relative delay
+`DeliverAt` | Deliver the message only at or after the specified absolute timestamp
+
+## TLS encryption and authentication
+
+In order to use [TLS encryption](security-tls-transport), you'll need to configure your client to do so:
+
+ * Use `pulsar+ssl` URL type
+ * Set `TLSTrustCertsFilePath` to the path to the TLS certs used by your client and the Pulsar broker
+ * Configure `Authentication` option
+
+Here's an example:
+
+```go
+
+opts := pulsar.ClientOptions{
+    URL: "pulsar+ssl://my-cluster.com:6651",
+    TLSTrustCertsFilePath: "/path/to/certs/my-cert.csr",
+    Authentication: NewAuthenticationTLS("my-cert.pem", "my-key.pem"),
+}
+
+```
+
diff --git a/site2/website-next/versioned_docs/version-2.6.0/client-libraries-java.md b/site2/website-next/versioned_docs/version-2.6.0/client-libraries-java.md
new file mode 100644
index 0000000..1b55652
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.6.0/client-libraries-java.md
@@ -0,0 +1,980 @@
+---
+id: client-libraries-java
+title: Pulsar Java client
+sidebar_label: "Java"
+original_id: client-libraries-java
+---
+
+You can use Pulsar Java client to create Java [producer](#producer), [consumer](#consumer), and [readers](#reader-interface) of messages and to perform [administrative tasks](admin-api-overview). The current version of the Java client is **@pulsar:version@**.
+
+All the methods in [producer](#producer), [consumer](#consumer), and [reader](#reader) of a Java client are thread-safe.
+
+Javadoc for the Pulsar client is divided into two domains by package as follows.
+
+Package | Description | Maven Artifact
+:-------|:------------|:--------------
+[`org.apache.pulsar.client.api`](/api/client) | The producer and consumer API | [org.apache.pulsar:pulsar-client:@pulsar:version@](http://search.maven.org/#artifactdetails%7Corg.apache.pulsar%7Cpulsar-client%7C@pulsar:version@%7Cjar)
+[`org.apache.pulsar.client.admin`](/api/admin) | The Java [admin API](admin-api-overview) | [org.apache.pulsar:pulsar-client-admin:@pulsar:version@](http://search.maven.org/#artifactdetails%7Corg.apache.pulsar%7Cpulsar-client-admin%7C@pulsar:version@%7Cjar)
+`org.apache.pulsar.client.all` |Includes both `pulsar-client` and `pulsar-client-admin`<br /><br /> Both `pulsar-client` and `pulsar-client-admin` are shaded packages and they shade dependencies independently. Consequently, the applications using both `pulsar-client` and `pulsar-client-admin` have redundant shaded classes. It would be troublesome if you introduce new dependencies but forget to update shading rules. <br /><br /> In this case, you can use `pulsar-client-all`, which shades  [...]
+
+This document focuses only on the client API for producing and consuming messages on Pulsar topics. For how to use the Java admin client, see [Pulsar admin interface](admin-api-overview).
+
+## Installation
+
+The latest version of the Pulsar Java client library is available via [Maven Central](http://search.maven.org/#artifactdetails%7Corg.apache.pulsar%7Cpulsar-client%7C@pulsar:version@%7Cjar). To use the latest version, add the `pulsar-client` library to your build configuration.
+
+### Maven
+
+If you use Maven, add the following information to the `pom.xml` file.
+
+```xml
+
+<!-- in your <properties> block -->
+<pulsar.version>@pulsar:version@</pulsar.version>
+
+<!-- in your <dependencies> block -->
+<dependency>
+  <groupId>org.apache.pulsar</groupId>
+  <artifactId>pulsar-client</artifactId>
+  <version>${pulsar.version}</version>
+</dependency>
+
+```
+
+### Gradle
+
+If you use Gradle, add the following information to the `build.gradle` file.
+
+```groovy
+
+def pulsarVersion = '@pulsar:version@'
+
+dependencies {
+    compile group: 'org.apache.pulsar', name: 'pulsar-client', version: pulsarVersion
+}
+
+```
+
+## Connection URLs
+
+To connect to Pulsar using client libraries, you need to specify a [Pulsar protocol](developing-binary-protocol) URL.
+
+You can assign Pulsar protocol URLs to specific clusters and use the `pulsar` scheme. The default port is `6650`. The following is an example of `localhost`.
+
+```http
+
+pulsar://localhost:6650
+
+```
+
+If you have multiple brokers, the URL is as follows.
+
+```http
+
+pulsar://localhost:6550,localhost:6651,localhost:6652
+
+```
+
+A URL for a production Pulsar cluster is as follows.
+
+```http
+
+pulsar://pulsar.us-west.example.com:6650
+
+```
+
+If you use [TLS](security-tls-authentication) authentication, the URL is as follows. 
+
+```http
+
+pulsar+ssl://pulsar.us-west.example.com:6651
+
+```
+
+## Client 
+
+You can instantiate a {@inject: javadoc:PulsarClient:/client/org/apache/pulsar/client/api/PulsarClient} object using just a URL for the target Pulsar [cluster](reference-terminology.md#cluster) like this:
+
+```java
+
+PulsarClient client = PulsarClient.builder()
+        .serviceUrl("pulsar://localhost:6650")
+        .build();
+
+```
+
+If you have multiple brokers, you can initiate a PulsarClient like this:
+
+```java
+
+PulsarClient client = PulsarClient.builder()
+        .serviceUrl("pulsar://localhost:6650,localhost:6651,localhost:6652")
+        .build();
+
+```
+
+> ### Default broker URLs for standalone clusters
+> If you run a cluster in [standalone mode](getting-started-standalone), the broker is available at the `pulsar://localhost:6650` URL by default.
+
+If you create a client, you can use the `loadConf` configuration. The following parameters are available in `loadConf`.
+
+| Type | Name | <div>Description</div> | Default
+|---|---|---|---
+String | `serviceUrl` |Service URL provider for Pulsar service | None
+String | `authPluginClassName` | Name of the authentication plugin | None
+String | `authParams` | String represents parameters for the authentication plugin <br /><br />**Example**<br /> key1:val1,key2:val2|None
+long|`operationTimeoutMs`|Operation timeout |30000
+long|`statsIntervalSeconds`|Interval between each stats info<br /><br />Stats is activated with positive `statsInterval`<br /><br />Set `statsIntervalSeconds` to 1 second at least |60
+int|`numIoThreads`| The number of threads used for handling connections to brokers | 1 
+int|`numListenerThreads`|The number of threads used for handling message listeners | 1 
+boolean|`useTcpNoDelay`|Whether to use TCP no-delay flag on the connection to disable Nagle algorithm |true
+boolean |`useTls` |Whether to use TLS encryption on the connection| false
+string | `tlsTrustCertsFilePath` |Path to the trusted TLS certificate file|None
+boolean|`tlsAllowInsecureConnection`|Whether the Pulsar client accepts untrusted TLS certificate from broker | false
+boolean | `tlsHostnameVerificationEnable` | Whether to enable TLS hostname verification|false
+int|`concurrentLookupRequest`|The number of concurrent lookup requests allowed to send on each broker connection to prevent overload on broker|5000
+int|`maxLookupRequest`|The maximum number of lookup requests allowed on each broker connection to prevent overload on broker | 50000
+int|`maxNumberOfRejectedRequestPerConnection`|The maximum number of rejected requests of a broker in a certain time frame (30 seconds) after the current connection is closed and the client creates a new connection to connect to a different broker|50
+int|`keepAliveIntervalSeconds`|Seconds of keeping alive interval for each client broker connection|30
+int|`connectionTimeoutMs`|Duration of waiting for a connection to a broker to be established <br /><br />If the duration passes without a response from a broker, the connection attempt is dropped|10000
+int|`requestTimeoutMs`|Maximum duration for completing a request |60000
+int|`defaultBackoffIntervalNanos`| Default duration for a backoff interval | TimeUnit.MILLISECONDS.toNanos(100);
+long|`maxBackoffIntervalNanos`|Maximum duration for a backoff interval|TimeUnit.SECONDS.toNanos(30)
+
+Check out the Javadoc for the {@inject: javadoc:PulsarClient:/client/org/apache/pulsar/client/api/PulsarClient} class for a full list of configurable parameters.
+
+> In addition to client-level configuration, you can also apply [producer](#configuring-producers) and [consumer](#configuring-consumers) specific configuration as described in sections below.
+
+## Producer
+
+In Pulsar, producers write messages to topics. Once you've instantiated a {@inject: javadoc:PulsarClient:/client/org/apache/pulsar/client/api/PulsarClient} object (as in the section [above](#client-configuration)), you can create a {@inject: javadoc:Producer:/client/org/apache/pulsar/client/api/Producer} for a specific Pulsar [topic](reference-terminology.md#topic).
+
+```java
+
+Producer<byte[]> producer = client.newProducer()
+        .topic("my-topic")
+        .create();
+
+// You can then send messages to the broker and topic you specified:
+producer.send("My message".getBytes());
+
+```
+
+By default, producers produce messages that consist of byte arrays. You can produce different types by specifying a message [schema](#schemas).
+
+```java
+
+Producer<String> stringProducer = client.newProducer(Schema.STRING)
+        .topic("my-topic")
+        .create();
+stringProducer.send("My message");
+
+```
+
+> Make sure that you close your producers, consumers, and clients when you do not need them.
+
+> ```java
+> 
+> producer.close();
+> consumer.close();
+> client.close();
+>
+> 
+> ```
+
+>
+> Close operations can also be asynchronous:
+
+> ```java
+> 
+> producer.closeAsync()
+>    .thenRun(() -> System.out.println("Producer closed"))
+>    .exceptionally((ex) -> {
+>        System.err.println("Failed to close producer: " + ex);
+>        return null;
+>    });
+>
+> 
+> ```
+
+
+### Configure producer
+
+If you instantiate a `Producer` object by specifying only a topic name as the example above, use the default configuration for producer. 
+
+If you create a producer, you can use the `loadConf` configuration. The following parameters are available in `loadConf`.
+
+Type | Name| <div>Description</div>|  Default
+|---|---|---|---
+String|	`topicName`|	Topic name| null|
+String|`producerName`|Producer name| null
+long|`sendTimeoutMs`|Message send timeout in ms.<br /><br />If a message is not acknowledged by a server before the `sendTimeout` expires, an error occurs.|30000
+boolean|`blockIfQueueFull`|If it is set to `true`, when the outgoing message queue is full, the `Send` and `SendAsync` methods of producer block, rather than failing and throwing errors. <br /><br />If it is set to `false`, when the outgoing message queue is full, the `Send` and `SendAsync` methods of producer fail and `ProducerQueueIsFullError` exceptions occur.<br /><br />The `MaxPendingMessages` parameter determines the size of the outgoing message queue.|false
+int|`maxPendingMessages`|The maximum size of a queue holding pending messages.<br /><br />For example, a message waiting to receive an acknowledgment from a [broker](reference-terminology.md#broker). <br /><br />By default, when the queue is full, all calls to the `Send` and `SendAsync` methods fail **unless** you set `BlockIfQueueFull` to `true`.|1000
+int|`maxPendingMessagesAcrossPartitions`|The maximum number of pending messages across partitions. <br /><br />Use the setting to lower the max pending messages for each partition ({@link #setMaxPendingMessages(int)}) if the total number exceeds the configured value.|50000
+MessageRoutingMode|`messageRoutingMode`|Message routing logic for producers on [partitioned topics](concepts-architecture-overview.md#partitioned-topics).<br /><br /> Apply the logic only when setting no key on messages. <br /><br />Available options are as follows: <br /><br /><li>`pulsar.RoundRobinDistribution`: round robin<br /><br /> </li><li>`pulsar.UseSinglePartition`: publish all messages to a single partition<br /><br /></li><li>`pulsar.CustomPartition`: a custom partitioning sch [...]
+HashingScheme|`hashingScheme`|Hashing function determining the partition where you publish a particular message (**partitioned topics only**).<br /><br />Available options are as follows:<br /><br /><li> `pulsar.JavaStringHash`: the equivalent of `String.hashCode()` in Java<br /><br /></li><li> `pulsar.Murmur3_32Hash`: applies the [Murmur3](https://en.wikipedia.org/wiki/MurmurHash) hashing function<br /><br /></li><li>`pulsar.BoostHash`: applies the hashing function from C++'s [Boost](ht [...]
+ProducerCryptoFailureAction|`cryptoFailureAction`|Producer should take action when encryption fails.<br /><br /><li>**FAIL**: if encryption fails, unencrypted messages fail to send.</li><br /><li> **SEND**: if encryption fails, unencrypted messages are sent. </li>|`ProducerCryptoFailureAction.FAIL`
+long|`batchingMaxPublishDelayMicros`|Batching time period of sending messages.|TimeUnit.MILLISECONDS.toMicros(1)
+int|batchingMaxMessages|The maximum number of messages permitted in a batch.|1000
+boolean|`batchingEnabled`|Enable batching of messages. |true
+CompressionType|`compressionType`|Message data compression type used by a producer. <br /><br />Available options:<li>[`LZ4`](https://github.com/lz4/lz4)<br /></li><li>[`ZLIB`](https://zlib.net/)<br /></li><li>[`ZSTD`](https://facebook.github.io/zstd/)<br /></li><li>[`SNAPPY`](https://google.github.io/snappy/)</li>| No compression
+
+You can configure parameters if you do not want to use the default configuration.
+
+For a full list, see the Javadoc for the {@inject: javadoc:ProducerBuilder:/client/org/apache/pulsar/client/api/ProducerBuilder} class. The following is an example.
+
+```java
+
+Producer<byte[]> producer = client.newProducer()
+    .topic("my-topic")
+    .batchingMaxPublishDelay(10, TimeUnit.MILLISECONDS)
+    .sendTimeout(10, TimeUnit.SECONDS)
+    .blockIfQueueFull(true)
+    .create();
+
+```
+
+### Message routing
+
+When using partitioned topics, you can specify the routing mode whenever you publish messages using a producer. For more information on specifying a routing mode using the Java client, see the [Partitioned Topics](cookbooks-partitioned) cookbook.
+
+### Async send
+
+You can publish messages [asynchronously](concepts-messaging.md#send-modes) using the Java client. With async send, the producer puts the message in a blocking queue and returns it immediately. Then the client library sends the message to the broker in the background. If the queue is full (max size configurable), the producer is blocked or fails immediately when calling the API, depending on arguments passed to the producer.
+
+The following is an example.
+
+```java
+
+producer.sendAsync("my-async-message".getBytes()).thenAccept(msgId -> {
+    System.out.printf("Message with ID %s successfully sent", msgId);
+});
+
+```
+
+As you can see from the example above, async send operations return a {@inject: javadoc:MessageId:/client/org/apache/pulsar/client/api/MessageId} wrapped in a [`CompletableFuture`](http://www.baeldung.com/java-completablefuture).
+
+### Configure messages
+
+In addition to a value, you can set additional items on a given message:
+
+```java
+
+producer.newMessage()
+    .key("my-message-key")
+    .value("my-async-message".getBytes())
+    .property("my-key", "my-value")
+    .property("my-other-key", "my-other-value")
+    .send();
+
+```
+
+You can terminate the builder chain with `sendAsync()` and get a future return.
+
+## Consumer
+
+In Pulsar, consumers subscribe to topics and handle messages that producers publish to those topics. You can instantiate a new [consumer](reference-terminology.md#consumer) by first instantiating a {@inject: javadoc:PulsarClient:/client/org/apache/pulsar/client/api/PulsarClient} object and passing it a URL for a Pulsar broker (as [above](#client-configuration)).
+
+Once you've instantiated a {@inject: javadoc:PulsarClient:/client/org/apache/pulsar/client/api/PulsarClient} object, you can create a {@inject: javadoc:Consumer:/client/org/apache/pulsar/client/api/Consumer} by specifying a [topic](reference-terminology.md#topic) and a [subscription](concepts-messaging.md#subscription-modes).
+
+```java
+
+Consumer consumer = client.newConsumer()
+        .topic("my-topic")
+        .subscriptionName("my-subscription")
+        .subscribe();
+
+```
+
+The `subscribe` method will auto subscribe the consumer to the specified topic and subscription. One way to make the consumer listen on the topic is to set up a `while` loop. In this example loop, the consumer listens for messages, prints the contents of any received message, and then [acknowledges](reference-terminology.md#acknowledgment-ack) that the message has been processed. If the processing logic fails, you can use [negative acknowledgement](reference-terminology.md#acknowledgment [...]
+
+```java
+
+while (true) {
+  // Wait for a message
+  Message msg = consumer.receive();
+
+  try {
+      // Do something with the message
+      System.out.printf("Message received: %s", new String(msg.getData()));
+
+      // Acknowledge the message so that it can be deleted by the message broker
+      consumer.acknowledge(msg);
+  } catch (Exception e) {
+      // Message failed to process, redeliver later
+      consumer.negativeAcknowledge(msg);
+  }
+}
+
+```
+
+### Configure consumer
+
+If you instantiate a `Consumer` object by specifying only a topic and subscription name as in the example above, the consumer uses the default configuration. 
+
+When you create a consumer, you can use the `loadConf` configuration. The following parameters are available in `loadConf`.
+
+Type | Name| <div>Description</div>|  Default
+|---|---|---|---
+Set&lt;String&gt;|	`topicNames`|	Topic name|	Sets.newTreeSet()
+Pattern|   `topicsPattern`|	Topic pattern	|None
+String|	`subscriptionName`|	Subscription name|	None
+SubscriptionType| `subscriptionType`|	Subscription type <br /><br />Four subscription types are available:<li>Exclusive</li><li>Failover</li><li>Shared</li><li>Key_Shared</li>|SubscriptionType.Exclusive
+int | `receiverQueueSize` | Size of a consumer's receiver queue. <br /><br />For example, the number of messages accumulated by a consumer before an application calls `Receive`. <br /><br />A value higher than the default value increases consumer throughput, though at the expense of more memory utilization.| 1000
+long|`acknowledgementsGroupTimeMicros`|Group a consumer acknowledgment for a specified time.<br /><br />By default, a consumer uses 100ms grouping time to send out acknowledgments to a broker.<br /><br />Setting a group time of 0 sends out acknowledgments immediately. <br /><br />A longer ack group time is more efficient at the expense of a slight increase in message re-deliveries after a failure.|TimeUnit.MILLISECONDS.toMicros(100)
+long|`negativeAckRedeliveryDelayMicros`|Delay to wait before redelivering messages that failed to be processed.<br /><br /> When an application uses {@link Consumer#negativeAcknowledge(Message)}, failed messages are redelivered after a fixed timeout. |TimeUnit.MINUTES.toMicros(1)
+int |`maxTotalReceiverQueueSizeAcrossPartitions`|The max total receiver queue size across partitions.<br /><br />This setting reduces the receiver queue size for individual partitions if the total receiver queue size exceeds this value.|50000
+String|`consumerName`|Consumer name|null
+long|`ackTimeoutMillis`|Timeout of unacked messages|0
+long|`tickDurationMillis`|Granularity of the ack-timeout redelivery.<br /><br />Using an higher `tickDurationMillis` reduces the memory overhead to track messages when setting ack-timeout to a bigger value (for example, 1 hour).|1000
+int|`priorityLevel`|Priority level for a consumer to which a broker gives more priority while dispatching messages in Shared subscription type. <br /><br />The broker follows descending priorities. For example, 0=max-priority, 1, 2,...<br /><br />In shared subscription type, the broker **first dispatches messages to the max priority level consumers if they have permits**. Otherwise, the broker considers next priority level consumers.<br /><br /> **Example 1**<br /><br />If a subscription [...]
+ConsumerCryptoFailureAction|`cryptoFailureAction`|Consumer should take action when it receives a message that can not be decrypted.<br /><br /><li>**FAIL**: this is the default option to fail messages until crypto succeeds.</li><br /><li> **DISCARD**:silently acknowledge and not deliver message to an application.</li><br /><li>**CONSUME**: deliver encrypted messages to applications. It is the application's responsibility to decrypt the message.<br /><br />The decompression of message fai [...]
+SortedMap<String, String>|`properties`|A name or value property of this consumer.<br /><br />`properties` is application defined metadata attached to a consumer. <br /><br />When getting a topic stats, associate this metadata with the consumer stats for easier identification.|new TreeMap()
+boolean|`readCompacted`|If enabling `readCompacted`, a consumer reads messages from a compacted topic rather than reading a full message backlog of a topic.<br /><br /> A consumer only sees the latest value for each key in the compacted topic, up until reaching the point in the topic message when compacting backlog. Beyond that point, send messages as normal.<br /><br />Only enabling `readCompacted` on subscriptions to persistent topics, which have a single active consumer (like failure  [...]
+SubscriptionInitialPosition|`subscriptionInitialPosition`|Initial position at which to set cursor when subscribing to a topic at first time.|SubscriptionInitialPosition.Latest
+int|`patternAutoDiscoveryPeriod`|Topic auto discovery period when using a pattern for topic's consumer.<br /><br />The default and minimum value is 1 minute.|1
+RegexSubscriptionMode|`regexSubscriptionMode`|When subscribing to a topic using a regular expression, you can pick a certain type of topics.<br /><br /><li>**PersistentOnly**: only subscribe to persistent topics.</li><br /><li>**NonPersistentOnly**: only subscribe to non-persistent topics.</li><br /><li>**AllTopics**: subscribe to both persistent and non-persistent topics.</li>|RegexSubscriptionMode.PersistentOnly
+DeadLetterPolicy|`deadLetterPolicy`|Dead letter policy for consumers.<br /><br />By default, some messages are probably redelivered many times, even to the extent that it never stops.<br /><br />By using the dead letter mechanism, messages have the max redelivery count. **When exceeding the maximum number of redeliveries, messages are sent to the Dead Letter Topic and acknowledged automatically**.<br /><br />You can enable the dead letter mechanism by setting `deadLetterPolicy`.<br /><br [...]
+boolean|`autoUpdatePartitions`|If `autoUpdatePartitions` is enabled, a consumer subscribes to partition increasement automatically.<br /><br />**Note**: this is only for partitioned consumers.|true
+boolean|`replicateSubscriptionState`|If `replicateSubscriptionState` is enabled, a subscription state is replicated to geo-replicated clusters.|false
+
+You can configure parameters if you do not want to use the default configuration. For a full list, see the Javadoc for the {@inject: javadoc:ConsumerBuilder:/client/org/apache/pulsar/client/api/ConsumerBuilder} class. 
+
+The following is an example.
+
+```java
+
+Consumer consumer = client.newConsumer()
+        .topic("my-topic")
+        .subscriptionName("my-subscription")
+        .ackTimeout(10, TimeUnit.SECONDS)
+        .subscriptionType(SubscriptionType.Exclusive)
+        .subscribe();
+
+```
+
+### Async receive
+
+The `receive` method receives messages synchronously (the consumer process is blocked until a message is available). You can also use [async receive](concepts-messaging.md#receive-modes), which returns a [`CompletableFuture`](http://www.baeldung.com/java-completablefuture) object immediately once a new message is available.
+
+The following is an example.
+
+```java
+
+CompletableFuture<Message> asyncMessage = consumer.receiveAsync();
+
+```
+
+Async receive operations return a {@inject: javadoc:Message:/client/org/apache/pulsar/client/api/Message} wrapped inside of a [`CompletableFuture`](http://www.baeldung.com/java-completablefuture).
+
+### Batch receive
+
+Use `batchReceive` to receive multiple messages for each call. 
+
+The following is an example.
+
+```java
+
+Messages messages = consumer.batchReceive();
+for (Object message : messages) {
+  // do something
+}
+consumer.acknowledge(messages)
+
+```
+
+:::note
+
+Batch receive policy limits the number and bytes of messages in a single batch. You can specify a timeout to wait for enough messages.
+The batch receive is completed if any of the following condition is met: enough number of messages, bytes of messages, wait timeout.
+
+```java
+
+Consumer consumer = client.newConsumer()
+.topic("my-topic")
+.subscriptionName("my-subscription")
+.batchReceivePolicy(BatchReceivePolicy.builder()
+.maxNumMessages(100)
+.maxNumBytes(1024 * 1024)
+.timeout(200, TimeUnit.MILLISECONDS)
+.build())
+.subscribe();
+
+```
+
+The default batch receive policy is:
+
+```java
+
+BatchReceivePolicy.builder()
+.maxNumMessage(-1)
+.maxNumBytes(10 * 1024 * 1024)
+.timeout(100, TimeUnit.MILLISECONDS)
+.build();
+
+```
+
+:::
+
+### Multi-topic subscriptions
+
+In addition to subscribing a consumer to a single Pulsar topic, you can also subscribe to multiple topics simultaneously using [multi-topic subscriptions](concepts-messaging.md#multi-topic-subscriptions). To use multi-topic subscriptions you can supply either a regular expression (regex) or a `List` of topics. If you select topics via regex, all topics must be within the same Pulsar namespace.
+
+The followings are some examples.
+
+```java
+
+import org.apache.pulsar.client.api.Consumer;
+import org.apache.pulsar.client.api.PulsarClient;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.regex.Pattern;
+
+ConsumerBuilder consumerBuilder = pulsarClient.newConsumer()
+        .subscriptionName(subscription);
+
+// Subscribe to all topics in a namespace
+Pattern allTopicsInNamespace = Pattern.compile("public/default/.*");
+Consumer allTopicsConsumer = consumerBuilder
+        .topicsPattern(allTopicsInNamespace)
+        .subscribe();
+
+// Subscribe to a subsets of topics in a namespace, based on regex
+Pattern someTopicsInNamespace = Pattern.compile("public/default/foo.*");
+Consumer allTopicsConsumer = consumerBuilder
+        .topicsPattern(someTopicsInNamespace)
+        .subscribe();
+
+```
+
+In the above example, the consumer subscribes to the `persistent` topics that can match the topic name pattern. If you want the consumer subscribes to all `persistent` and `non-persistent` topics that can match the topic name pattern, set `subscriptionTopicsMode` to `RegexSubscriptionMode.AllTopics`.
+
+```java
+
+Pattern pattern = Pattern.compile("public/default/.*");
+pulsarClient.newConsumer()
+        .subscriptionName("my-sub")
+        .topicsPattern(pattern)
+        .subscriptionTopicsMode(RegexSubscriptionMode.AllTopics)
+        .subscribe();
+
+```
+
+:::note
+
+By default, the `subscriptionTopicsMode` of the consumer is `PersistentOnly`. Available options of `subscriptionTopicsMode` are `PersistentOnly`, `NonPersistentOnly`, and `AllTopics`.
+
+:::
+
+You can also subscribe to an explicit list of topics (across namespaces if you wish):
+
+```java
+
+List<String> topics = Arrays.asList(
+        "topic-1",
+        "topic-2",
+        "topic-3"
+);
+
+Consumer multiTopicConsumer = consumerBuilder
+        .topics(topics)
+        .subscribe();
+
+// Alternatively:
+Consumer multiTopicConsumer = consumerBuilder
+        .topic(
+            "topic-1",
+            "topic-2",
+            "topic-3"
+        )
+        .subscribe();
+
+```
+
+You can also subscribe to multiple topics asynchronously using the `subscribeAsync` method rather than the synchronous `subscribe` method. The following is an example.
+
+```java
+
+Pattern allTopicsInNamespace = Pattern.compile("persistent://public/default.*");
+consumerBuilder
+        .topics(topics)
+        .subscribeAsync()
+        .thenAccept(this::receiveMessageFromConsumer);
+
+private void receiveMessageFromConsumer(Object consumer) {
+    ((Consumer)consumer).receiveAsync().thenAccept(message -> {
+                // Do something with the received message
+                receiveMessageFromConsumer(consumer);
+            });
+}
+
+```
+
+### Subscription types
+
+Pulsar has various [subscription types](concepts-messaging#subscription-types) to match different scenarios. A topic can have multiple subscriptions with different subscription types. However, a subscription can only have one subscription type at a time.
+
+A subscription is identical with the subscription name; a subscription name can specify only one subscription type at a time. To change the subscription type, you should first stop all consumers of this subscription.
+
+Different subscription types have different message distribution modes. This section describes the differences of subscription types and how to use them.
+
+In order to better describe their differences, assuming you have a topic named "my-topic", and the producer has published 10 messages.
+
+```java
+
+Producer<String> producer = client.newProducer(Schema.STRING)
+        .topic("my-topic")
+        .enableBatching(false)
+        .create();
+// 3 messages with "key-1", 3 messages with "key-2", 2 messages with "key-3" and 2 messages with "key-4"
+producer.newMessage().key("key-1").value("message-1-1").send();
+producer.newMessage().key("key-1").value("message-1-2").send();
+producer.newMessage().key("key-1").value("message-1-3").send();
+producer.newMessage().key("key-2").value("message-2-1").send();
+producer.newMessage().key("key-2").value("message-2-2").send();
+producer.newMessage().key("key-2").value("message-2-3").send();
+producer.newMessage().key("key-3").value("message-3-1").send();
+producer.newMessage().key("key-3").value("message-3-2").send();
+producer.newMessage().key("key-4").value("message-4-1").send();
+producer.newMessage().key("key-4").value("message-4-2").send();
+
+```
+
+#### Exclusive
+
+Create a new consumer and subscribe with the `Exclusive` subscription type.
+
+```java
+
+Consumer consumer = client.newConsumer()
+        .topic("my-topic")
+        .subscriptionName("my-subscription")
+        .subscriptionType(SubscriptionType.Exclusive)
+        .subscribe()
+
+```
+
+Only the first consumer is allowed to the subscription, other consumers receive an error. The first consumer receives all 10 messages, and the consuming order is the same as the producing order.
+
+:::note
+
+If topic is a partitioned topic, the first consumer subscribes to all partitioned topics, other consumers are not assigned with partitions and receive an error. 
+
+:::
+
+#### Failover
+
+Create new consumers and subscribe with the`Failover` subscription type.
+
+```java
+
+Consumer consumer1 = client.newConsumer()
+        .topic("my-topic")
+        .subscriptionName("my-subscription")
+        .subscriptionType(SubscriptionType.Failover)
+        .subscribe()
+Consumer consumer2 = client.newConsumer()
+        .topic("my-topic")
+        .subscriptionName("my-subscription")
+        .subscriptionType(SubscriptionType.Failover)
+        .subscribe()
+//conumser1 is the active consumer, consumer2 is the standby consumer.
+//consumer1 receives 5 messages and then crashes, consumer2 takes over as an  active consumer.
+
+```
+
+Multiple consumers can attach to the same subscription, yet only the first consumer is active, and others are standby. When the active consumer is disconnected, messages will be dispatched to one of standby consumers, and the standby consumer then becomes active consumer. 
+
+If the first active consumer is disconnected after receiving 5 messages, the standby consumer becomes active consumer. Consumer1 will receive:
+
+```
+
+("key-1", "message-1-1")
+("key-1", "message-1-2")
+("key-1", "message-1-3")
+("key-2", "message-2-1")
+("key-2", "message-2-2")
+
+```
+
+consumer2 will receive:
+
+```
+
+("key-2", "message-2-3")
+("key-3", "message-3-1")
+("key-3", "message-3-2")
+("key-4", "message-4-1")
+("key-4", "message-4-2")
+
+```
+
+:::note
+
+If a topic is a partitioned topic, each partition has only one active consumer, messages of one partition are distributed to only one consumer, and messages of multiple partitions are distributed to multiple consumers. 
+
+:::
+
+#### Shared
+
+Create new consumers and subscribe with `Shared` subscription type.
+
+```java
+
+Consumer consumer1 = client.newConsumer()
+        .topic("my-topic")
+        .subscriptionName("my-subscription")
+        .subscriptionType(SubscriptionType.Shared)
+        .subscribe()
+  
+Consumer consumer2 = client.newConsumer()
+        .topic("my-topic")
+        .subscriptionName("my-subscription")
+        .subscriptionType(SubscriptionType.Shared)
+        .subscribe()
+//Both consumer1 and consumer 2 is active consumers.
+
+```
+
+In shared subscription type, multiple consumers can attach to the same subscription and messages are delivered in a round robin distribution across consumers.
+
+If a broker dispatches only one message at a time, consumer1 receives the following information.
+
+```
+
+("key-1", "message-1-1")
+("key-1", "message-1-3")
+("key-2", "message-2-2")
+("key-3", "message-3-1")
+("key-4", "message-4-1")
+
+```
+
+consumer2 receives the following information.
+
+```
+
+("key-1", "message-1-2")
+("key-2", "message-2-1")
+("key-2", "message-2-3")
+("key-3", "message-3-2")
+("key-4", "message-4-2")
+
+```
+
+`Shared` subscription is different from `Exclusive` and `Failover` subscription types. `Shared` subscription has better flexibility, but cannot provide order guarantee.
+
+#### Key_shared
+
+This is a new subscription type since 2.4.0 release. Create new consumers and subscribe with `Key_Shared` subscription type.
+
+```java
+
+Consumer consumer1 = client.newConsumer()
+        .topic("my-topic")
+        .subscriptionName("my-subscription")
+        .subscriptionType(SubscriptionType.Key_Shared)
+        .subscribe()
+  
+Consumer consumer2 = client.newConsumer()
+        .topic("my-topic")
+        .subscriptionName("my-subscription")
+        .subscriptionType(SubscriptionType.Key_Shared)
+        .subscribe()
+//Both consumer1 and consumer2 are active consumers.
+
+```
+
+`Key_Shared` subscription is like `Shared` subscription, all consumers can attach to the same subscription. But it is different from `Key_Shared` subscription, messages with the same key are delivered to only one consumer in order. The possible distribution of messages between different consumers (by default we do not know in advance which keys will be assigned to a consumer, but a key will only be assigned to a consumer at the same time).
+
+consumer1 receives the following information.
+
+```
+
+("key-1", "message-1-1")
+("key-1", "message-1-2")
+("key-1", "message-1-3")
+("key-3", "message-3-1")
+("key-3", "message-3-2")
+
+```
+
+consumer2 receives the following information.
+
+```
+
+("key-2", "message-2-1")
+("key-2", "message-2-2")
+("key-2", "message-2-3")
+("key-4", "message-4-1")
+("key-4", "message-4-2")
+
+```
+
+If batching is enabled at the producer side, messages with different keys are added to a batch by default. The broker will dispatch the batch to the consumer, so the default batch mechanism may break the Key_Shared subscription guaranteed message distribution semantics. The producer needs to use the `KeyBasedBatcher`.
+
+```java
+
+Producer producer = client.newProducer()
+        .topic("my-topic")
+        .batcherBuilder(BatcherBuilder.KEY_BASED)
+        .create();
+
+```
+
+Or the producer can disable batching.
+
+```java
+
+Producer producer = client.newProducer()
+        .topic("my-topic")
+        .enableBatching(false)
+        .create();
+
+```
+
+:::note
+
+If the message key is not specified, messages without key are dispatched to one consumer in order by default.
+
+:::
+
+## Reader 
+
+With the [reader interface](concepts-clients.md#reader-interface), Pulsar clients can "manually position" themselves within a topic and reading all messages from a specified message onward. The Pulsar API for Java enables you to create {@inject: javadoc:Reader:/client/org/apache/pulsar/client/api/Reader} objects by specifying a topic and a {@inject: javadoc:MessageId:/client/org/apache/pulsar/client/api/MessageId}.
+
+The following is an example.
+
+```java
+
+byte[] msgIdBytes = // Some message ID byte array
+MessageId id = MessageId.fromByteArray(msgIdBytes);
+Reader reader = pulsarClient.newReader()
+        .topic(topic)
+        .startMessageId(id)
+        .create();
+
+while (true) {
+    Message message = reader.readNext();
+    // Process message
+}
+
+```
+
+In the example above, a `Reader` object is instantiated for a specific topic and message (by ID); the reader iterates over each message in the topic after the message is identified by `msgIdBytes` (how that value is obtained depends on the application).
+
+The code sample above shows pointing the `Reader` object to a specific message (by ID), but you can also use `MessageId.earliest` to point to the earliest available message on the topic of `MessageId.latest` to point to the most recent available message.
+
+When you create a reader, you can use the `loadConf` configuration. The following parameters are available in `loadConf`.
+
+| Type | Name | <div>Description</div> | Default
+|---|---|---|---
+String|`topicName`|Topic name. |None
+int|`receiverQueueSize`|Size of a consumer's receiver queue.<br /><br />For example, the number of messages that can be accumulated by a consumer before an application calls `Receive`.<br /><br />A value higher than the default value increases consumer throughput, though at the expense of more memory utilization.|1000
+ReaderListener&lt;T&gt;|`readerListener`|A listener that is called for message received.|None
+String|`readerName`|Reader name.|null
+String|`subscriptionRolePrefix`|Prefix of subscription role. |null
+CryptoKeyReader|`cryptoKeyReader`|Interface that abstracts the access to a key store.|null
+ConsumerCryptoFailureAction|`cryptoFailureAction`|Consumer should take action when it receives a message that can not be decrypted.<br /><br /><li>**FAIL**: this is the default option to fail messages until crypto succeeds.</li><br /><li> **DISCARD**: silently acknowledge and not deliver message to an application.</li><br /><li>**CONSUME**: deliver encrypted messages to applications. It is the application's responsibility to decrypt the message.<br /><br />The message decompression fails [...]
+boolean|`readCompacted`|If enabling `readCompacted`, a consumer reads messages from a compacted topic rather than a full message backlog of a topic.<br /><br /> A consumer only sees the latest value for each key in the compacted topic, up until reaching the point in the topic message when compacting backlog. Beyond that point, send messages as normal.<br /><br />`readCompacted` can only be enabled on subscriptions to persistent topics, which have a single active consumer (for example, fa [...]
+boolean|`resetIncludeHead`|If set to true, the first message to be returned is the one specified by `messageId`.<br /><br />If set to false, the first message to be returned is the one next to the message specified by `messageId`.|false
+
+### Sticky key range reader
+
+In sticky key range reader, broker will only dispatch messages which hash of the message key contains by the specified key hash range. Multiple key hash ranges can be specified on a reader.
+
+The following is an example to create a sticky key range reader.
+
+```java
+
+pulsarClient.newReader()
+        .topic(topic)
+        .startMessageId(MessageId.earliest)
+        .keyHashRange(Range.of(0, 10000), Range.of(20001, 30000))
+        .create();
+
+```
+
+Total hash range size is 65536, so the max end of the range should be less than or equal to 65535.
+
+## Schema
+
+In Pulsar, all message data consists of byte arrays "under the hood." [Message schemas](schema-get-started) enable you to use other types of data when constructing and handling messages (from simple types like strings to more complex, application-specific types). If you construct, say, a [producer](#producers) without specifying a schema, then the producer can only produce messages of type `byte[]`. The following is an example.
+
+```java
+
+Producer<byte[]> producer = client.newProducer()
+        .topic(topic)
+        .create();
+
+```
+
+The producer above is equivalent to a `Producer<byte[]>` (in fact, you should *always* explicitly specify the type). If you'd like to use a producer for a different type of data, you'll need to specify a **schema** that informs Pulsar which data type will be transmitted over the [topic](reference-terminology.md#topic).
+
+### Schema example
+
+Let's say that you have a `SensorReading` class that you'd like to transmit over a Pulsar topic:
+
+```java
+
+public class SensorReading {
+    public float temperature;
+
+    public SensorReading(float temperature) {
+        this.temperature = temperature;
+    }
+
+    // A no-arg constructor is required
+    public SensorReading() {
+    }
+
+    public float getTemperature() {
+        return temperature;
+    }
+
+    public void setTemperature(float temperature) {
+        this.temperature = temperature;
+    }
+}
+
+```
+
+You could then create a `Producer<SensorReading>` (or `Consumer<SensorReading>`) like this:
+
+```java
+
+Producer<SensorReading> producer = client.newProducer(JSONSchema.of(SensorReading.class))
+        .topic("sensor-readings")
+        .create();
+
+```
+
+The following schema formats are currently available for Java:
+
+* No schema or the byte array schema (which can be applied using `Schema.BYTES`):
+
+  ```java
+  
+  Producer<byte[]> bytesProducer = client.newProducer(Schema.BYTES)
+      .topic("some-raw-bytes-topic")
+      .create();
+  
+  ```
+
+  Or, equivalently:
+
+  ```java
+  
+  Producer<byte[]> bytesProducer = client.newProducer()
+      .topic("some-raw-bytes-topic")
+      .create();
+  
+  ```
+
+* `String` for normal UTF-8-encoded string data. Apply the schema using `Schema.STRING`:
+
+  ```java
+  
+  Producer<String> stringProducer = client.newProducer(Schema.STRING)
+      .topic("some-string-topic")
+      .create();
+  
+  ```
+
+* Create JSON schemas for POJOs using `Schema.JSON`. The following is an example.
+
+  ```java
+  
+  Producer<MyPojo> pojoProducer = client.newProducer(Schema.JSON(MyPojo.class))
+      .topic("some-pojo-topic")
+      .create();
+  
+  ```
+
+* Generate Protobuf schemas using `Schema.PROTOBUF`. The following example shows how to create the Protobuf schema and use it to instantiate a new producer:
+
+  ```java
+  
+  Producer<MyProtobuf> protobufProducer = client.newProducer(Schema.PROTOBUF(MyProtobuf.class))
+      .topic("some-protobuf-topic")
+      .create();
+  
+  ```
+
+* Define Avro schemas with `Schema.AVRO`. The following code snippet demonstrates how to create and use Avro schema.
+
+  ```java
+  
+  Producer<MyAvro> avroProducer = client.newProducer(Schema.AVRO(MyAvro.class))
+      .topic("some-avro-topic")
+      .create();
+  
+  ```
+
+## Authentication
+
+Pulsar currently supports two authentication schemes: [TLS](security-tls-authentication.md) and [Athenz](security-athenz). You can use the Pulsar Java client with both.
+
+### TLS Authentication
+
+To use [TLS](security-tls-authentication), you need to set TLS to `true` using the `setUseTls` method, point your Pulsar client to a TLS cert path, and provide paths to cert and key files.
+
+The following is an example.
+
+```java
+
+Map<String, String> authParams = new HashMap();
+authParams.put("tlsCertFile", "/path/to/client-cert.pem");
+authParams.put("tlsKeyFile", "/path/to/client-key.pem");
+
+Authentication tlsAuth = AuthenticationFactory
+        .create(AuthenticationTls.class.getName(), authParams);
+
+PulsarClient client = PulsarClient.builder()
+        .serviceUrl("pulsar+ssl://my-broker.com:6651")
+        .enableTls(true)
+        .tlsTrustCertsFilePath("/path/to/cacert.pem")
+        .authentication(tlsAuth)
+        .build();
+
+```
+
+### Athenz
+
+To use [Athenz](security-athenz) as an authentication provider, you need to [use TLS](#tls-authentication) and provide values for four parameters in a hash:
+
+* `tenantDomain`
+* `tenantService`
+* `providerDomain`
+* `privateKey`
+
+You can also set an optional `keyId`. The following is an example.
+
+```java
+
+Map<String, String> authParams = new HashMap();
+authParams.put("tenantDomain", "shopping"); // Tenant domain name
+authParams.put("tenantService", "some_app"); // Tenant service name
+authParams.put("providerDomain", "pulsar"); // Provider domain name
+authParams.put("privateKey", "file:///path/to/private.pem"); // Tenant private key path
+authParams.put("keyId", "v1"); // Key id for the tenant private key (optional, default: "0")
+
+Authentication athenzAuth = AuthenticationFactory
+        .create(AuthenticationAthenz.class.getName(), authParams);
+
+PulsarClient client = PulsarClient.builder()
+        .serviceUrl("pulsar+ssl://my-broker.com:6651")
+        .enableTls(true)
+        .tlsTrustCertsFilePath("/path/to/cacert.pem")
+        .authentication(athenzAuth)
+        .build();
+
+```
+
+> #### Supported pattern formats
+> The `privateKey` parameter supports the following three pattern formats:
+> * `file:///path/to/file`
+> * `file:/path/to/file`
+> * `data:application/x-pem-file;base64,<base64-encoded value>`
diff --git a/site2/website-next/versioned_docs/version-2.6.0/client-libraries-node.md b/site2/website-next/versioned_docs/version-2.6.0/client-libraries-node.md
new file mode 100644
index 0000000..8d7376d
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.6.0/client-libraries-node.md
@@ -0,0 +1,430 @@
+---
+id: client-libraries-node
+title: The Pulsar Node.js client
+sidebar_label: "Node.js"
+original_id: client-libraries-node
+---
+
+The Pulsar Node.js client can be used to create Pulsar [producers](#producers), [consumers](#consumers), and [readers](#readers) in Node.js.
+
+All the methods in [producers](#producers), [consumers](#consumers), and [readers](#readers) of a Node.js client are thread-safe.
+
+## Installation
+
+You can install the [`pulsar-client`](https://www.npmjs.com/package/pulsar-client) library via [npm](https://www.npmjs.com/).
+
+### Requirements
+Pulsar Node.js client library is based on the C++ client library.
+Follow [these instructions](client-libraries-cpp.md#compilation) and install the Pulsar C++ client library.
+
+### Compatibility
+
+Compatibility between each version of the Node.js client and the C++ client is as follows:
+
+| Node.js client | C++ client     |
+| :------------- | :------------- |
+| 1.0.0          | 2.3.0 or later |
+
+If an incompatible version of the C++ client is installed, you may fail to build or run this library.
+
+### Installation using npm
+
+Install the `pulsar-client` library via [npm](https://www.npmjs.com/):
+
+```shell
+
+$ npm install pulsar-client
+
+```
+
+:::note
+
+Also, this library works only in Node.js 10.x or later because it uses the [`node-addon-api`](https://github.com/nodejs/node-addon-api) module to wrap the C++ library.
+
+:::
+
+## Connection URLs
+To connect to Pulsar using client libraries, you need to specify a [Pulsar protocol](developing-binary-protocol) URL.
+
+Pulsar protocol URLs are assigned to specific clusters, use the `pulsar` scheme and have a default port of 6650. Here is an example for `localhost`:
+
+```http
+
+pulsar://localhost:6650
+
+```
+
+A URL for a production Pulsar cluster may look something like this:
+
+```http
+
+pulsar://pulsar.us-west.example.com:6650
+
+```
+
+If you are using [TLS encryption](security-tls-transport.md) or [TLS Authentication](security-tls-authentication), the URL will look like something like this:
+
+```http
+
+pulsar+ssl://pulsar.us-west.example.com:6651
+
+```
+
+## Create a client
+
+In order to interact with Pulsar, you will first need a client object. You can create a client instance using a `new` operator and the `Client` method, passing in a client options object (more on configuration [below](#client-configuration)).
+
+Here is an example:
+
+```JavaScript
+
+const Pulsar = require('pulsar-client');
+
+(async () => {
+  const client = new Pulsar.Client({
+    serviceUrl: 'pulsar://localhost:6650',
+  });
+  
+  await client.close();
+})();
+
+```
+
+### Client configuration
+
+The following configurable parameters are available for Pulsar clients:
+
+| Parameter | Description | Default |
+| :-------- | :---------- | :------ |
+| `serviceUrl` | The connection URL for the Pulsar cluster. See [above](#connection-urls) for more info. |  |
+| `authentication` | Configure the authentication provider. (default: no authentication). See [TLS Authentication](security-tls-authentication) for more info. | |
+| `operationTimeoutSeconds` | The timeout for Node.js client operations (creating producers, subscribing to and unsubscribing from [topics](reference-terminology.md#topic)). Retries will occur until this threshold is reached, at which point the operation will fail. | 30 |
+| `ioThreads` | The number of threads to use for handling connections to Pulsar [brokers](reference-terminology.md#broker). | 1 |
+| `messageListenerThreads` | The number of threads used by message listeners ([consumers](#consumers) and [readers](#readers)). | 1 |
+| `concurrentLookupRequest` | The number of concurrent lookup requests that can be sent on each broker connection. Setting a maximum helps to keep from overloading brokers. You should set values over the default of 50000 only if the client needs to produce and/or subscribe to thousands of Pulsar topics. | 50000 |
+| `tlsTrustCertsFilePath` | The file path for the trusted TLS certificate. | |
+| `tlsValidateHostname` | The boolean value of setup whether to enable TLS hostname verification. | `false` |
+| `tlsAllowInsecureConnection` | The boolean value of setup whether the Pulsar client accepts untrusted TLS certificate from broker. | `false` |
+| `statsIntervalInSeconds` | Interval between each stat info. Stats is activated with positive statsInterval. The value should be set to 1 second at least | 600 |
+
+## Producers
+
+Pulsar producers publish messages to Pulsar topics. You can [configure](#producer-configuration) Node.js producers using a producer configuration object.
+
+Here is an example:
+
+```JavaScript
+
+const producer = await client.createProducer({
+  topic: 'my-topic', // or 'my-tenant/my-namespace/my-topic' to specify topic's tenant and namespace
+});
+
+await producer.send({
+  data: Buffer.from("Hello, Pulsar"),
+});
+
+await producer.close();
+
+```
+
+> #### Promise operation
+> When you create a new Pulsar producer, the operation will return `Promise` object and get producer instance or an error through executor function.  
+> In this example, using await operator instead of executor function.
+
+### Producer operations
+
+Pulsar Node.js producers have the following methods available:
+
+| Method | Description | Return type |
+| :----- | :---------- | :---------- |
+| `send(Object)` | Publishes a [message](#messages) to the producer's topic. When the message is successfully acknowledged by the Pulsar broker, or an error will be thrown, the Promise object run executor function. | `Promise<null>` |
+| `flush()` | Sends message from send queue to Pulsar broker. When the message is successfully acknowledged by the Pulsar broker, or an error will be thrown, the Promise object run executor function. | `Promise<null>` |
+| `close()` | Closes the producer and releases all resources allocated to it. If `close()` is called then no more messages will be accepted from the publisher. This method will return Promise object, and when all pending publish requests have been persisted by Pulsar then run executor function. If an error is thrown, no pending writes will be retried. | `Promise<null>` |
+
+### Producer configuration
+
+| Parameter | Description | Default |
+| :-------- | :---------- | :------ |
+| `topic` | The Pulsar [topic](reference-terminology.md#topic) to which the producer publishes messages. The topic format is `<topic-name>` or `<tenant-name>/<namespace-name>/<topic-name>`. For example, `sample/ns1/my-topic`. | |
+| `producerName` | A name for the producer. If you do not explicitly assign a name, Pulsar will automatically generate a globally unique name.  If you choose to explicitly assign a name, it will need to be unique across *all* Pulsar clusters, otherwise the creation operation will throw an error. | |
+| `sendTimeoutMs` | When publishing a message to a topic, the producer will wait for an acknowledgment from the responsible Pulsar [broker](reference-terminology.md#broker). If a message is not acknowledged within the threshold set by this parameter, an error will be thrown. If you set `sendTimeoutMs` to -1, the timeout will be set to infinity (and thus removed). Removing the send timeout is recommended when using Pulsar's [message de-duplication](cookbooks-deduplication) feature. | 30000 |
+| `initialSequenceId` | The initial sequence ID of the message. When producer send message, add sequence ID to message. The ID is increased each time to send. | |
+| `maxPendingMessages` | The maximum size of the queue holding pending messages (i.e. messages waiting to receive an acknowledgment from the [broker](reference-terminology.md#broker)). By default, when the queue is full all calls to the `send` method will fail *unless* `blockIfQueueFull` is set to `true`. | 1000 |
+| `maxPendingMessagesAcrossPartitions` | The maximum size of the sum of partition's  pending queue. | 50000 |
+| `blockIfQueueFull` | If set to `true`, the producer's `send` method will wait when the outgoing message queue is full rather than failing and throwing an error (the size of that queue is dictated by the `maxPendingMessages` parameter); if set to `false` (the default), `send` operations will fail and throw a error when the queue is full. | `false` |
+| `messageRoutingMode` | The message routing logic (for producers on [partitioned topics](concepts-messaging.md#partitioned-topics)). This logic is applied only when no key is set on messages. The available options are: round robin (`RoundRobinDistribution`), or publishing all messages to a single partition (`UseSinglePartition`, the default). | `UseSinglePartition` |
+| `hashingScheme` | The hashing function that determines the partition on which a particular message is published (partitioned topics only). The available options are: `JavaStringHash` (the equivalent of `String.hashCode()` in Java), `Murmur3_32Hash` (applies the [Murmur3](https://en.wikipedia.org/wiki/MurmurHash) hashing function), or `BoostHash` (applies the hashing function from C++'s [Boost](https://www.boost.org/doc/libs/1_62_0/doc/html/hash.html) library). | `BoostHash` |
+| `compressionType` | The message data compression type used by the producer. The available options are [`LZ4`](https://github.com/lz4/lz4), and [`Zlib`](https://zlib.net/). | Compression None |
+| `batchingEnabled` | If set to `true`, the producer send message as batch. | `true` |
+| `batchingMaxPublishDelayMs` | The maximum time of delay sending message in batching. | 10 |
+| `batchingMaxMessages` | The maximum size of sending message in each time of batching. | 1000 |
+| `properties` | The metadata of producer. | |
+
+### Producer example
+
+This example creates a Node.js producer for the `my-topic` topic and sends 10 messages to that topic:
+
+```JavaScript
+
+const Pulsar = require('pulsar-client');
+
+(async () => {
+  // Create a client
+  const client = new Pulsar.Client({
+    serviceUrl: 'pulsar://localhost:6650',
+  });
+
+  // Create a producer
+  const producer = await client.createProducer({
+    topic: 'my-topic',
+  });
+
+  // Send messages
+  for (let i = 0; i < 10; i += 1) {
+    const msg = `my-message-${i}`;
+    producer.send({
+      data: Buffer.from(msg),
+    });
+    console.log(`Sent message: ${msg}`);
+  }
+  await producer.flush();
+
+  await producer.close();
+  await client.close();
+})();
+
+```
+
+## Consumers
+
+Pulsar consumers subscribe to one or more Pulsar topics and listen for incoming messages produced on that topic/those topics. You can [configure](#consumer-configuration) Node.js consumers using a consumer configuration object.
+
+Here is an example:
+
+```JavaScript
+
+const consumer = await client.subscribe({
+  topic: 'my-topic',
+  subscription: 'my-subscription',
+});
+
+const msg = await consumer.receive();
+console.log(msg.getData().toString());
+consumer.acknowledge(msg);
+
+await consumer.close();
+
+```
+
+> #### Promise operation
+> When you create a new Pulsar consumer, the operation will return `Promise` object and get consumer instance or an error through executor function.  
+> In this example, using await operator instead of executor function.
+
+### Consumer operations
+
+Pulsar Node.js consumers have the following methods available:
+
+| Method | Description | Return type |
+| :----- | :---------- | :---------- |
+| `receive()` | Receives a single message from the topic. When the message is available, the Promise object run executor function and get message object. | `Promise<Object>` |
+| `receive(Number)` | Receives a single message from the topic with specific timeout in milliseconds. | `Promise<Object>` |
+| `acknowledge(Object)` | [Acknowledges](reference-terminology.md#acknowledgment-ack) a message to the Pulsar [broker](reference-terminology.md#broker) by message object. | `void` |
+| `acknowledgeId(Object)` | [Acknowledges](reference-terminology.md#acknowledgment-ack) a message to the Pulsar [broker](reference-terminology.md#broker) by message ID object. | `void` |
+| `acknowledgeCumulative(Object)` | [Acknowledges](reference-terminology.md#acknowledgment-ack) *all* the messages in the stream, up to and including the specified message. The `acknowledgeCumulative` method will return void, and send the ack to the broker asynchronously. After that, the messages will *not* be redelivered to the consumer. Cumulative acking can not be used with a [shared](concepts-messaging.md#shared) subscription type. | `void` |
+| `acknowledgeCumulativeId(Object)` | [Acknowledges](reference-terminology.md#acknowledgment-ack) *all* the messages in the stream, up to and including the specified message ID. | `void` |
+| `close()` | Closes the consumer, disabling its ability to receive messages from the broker. | `Promise<null>` |
+
+### Consumer configuration
+
+| Parameter | Description | Default |
+| :-------- | :---------- | :------ |
+| `topic` | The Pulsar [topic](reference-terminology.md#topic) on which the consumer will establish a subscription and listen for messages. | |
+| `subscription` | The subscription name for this consumer. | |
+| `subscriptionType` | Available options are `Exclusive`, `Shared`, `Key_Shared`, and `Failover`. | `Exclusive` |
+| `ackTimeoutMs` | Acknowledge timeout in milliseconds. | 0 |
+| `receiverQueueSize` | Sets the size of the consumer's receiver queue, i.e. the number of messages that can be accumulated by the consumer before the application calls `receive`. A value higher than the default of 1000 could increase consumer throughput, though at the expense of more memory utilization. | 1000 |
+| `receiverQueueSizeAcrossPartitions` | Set the max total receiver queue size across partitions. This setting will be used to reduce the receiver queue size for individual partitions if the total exceeds this value. | 50000 |
+| `consumerName` | The name of consumer. Currently(v2.4.1), [failover](concepts-messaging.md#failover) mode use consumer name in ordering. | |
+| `properties` | The metadata of consumer. | |
+
+### Consumer example
+
+This example creates a Node.js consumer with the `my-subscription` subscription on the `my-topic` topic, receives messages, prints the content that arrive, and acknowledges each message to the Pulsar broker for 10 times:
+
+```JavaScript
+
+const Pulsar = require('pulsar-client');
+
+(async () => {
+  // Create a client
+  const client = new Pulsar.Client({
+    serviceUrl: 'pulsar://localhost:6650',
+  });
+
+  // Create a consumer
+  const consumer = await client.subscribe({
+    topic: 'my-topic',
+    subscription: 'my-subscription',
+    subscriptionType: 'Exclusive',
+  });
+
+  // Receive messages
+  for (let i = 0; i < 10; i += 1) {
+    const msg = await consumer.receive();
+    console.log(msg.getData().toString());
+    consumer.acknowledge(msg);
+  }
+
+  await consumer.close();
+  await client.close();
+})();
+
+```
+
+## Readers
+
+Pulsar readers process messages from Pulsar topics. Readers are different from consumers because with readers you need to explicitly specify which message in the stream you want to begin with (consumers, on the other hand, automatically begin with the most recently unacked message). You can [configure](#reader-configuration) Node.js readers using a reader configuration object.
+
+Here is an example:
+
+```JavaScript
+
+const reader = await client.createReader({
+  topic: 'my-topic',
+  startMessageId: Pulsar.MessageId.earliest(),
+});
+
+const msg = await reader.readNext();
+console.log(msg.getData().toString());
+
+await reader.close();
+
+```
+
+### Reader operations
+
+Pulsar Node.js readers have the following methods available:
+
+| Method | Description | Return type |
+| :----- | :---------- | :---------- |
+| `readNext()` | Receives the next message on the topic (analogous to the `receive` method for [consumers](#consumer-operations)). When the message is available, the Promise object run executor function and get message object. | `Promise<Object>` |
+| `readNext(Number)` | Receives a single message from the topic with specific timeout in milliseconds. | `Promise<Object>` |
+| `hasNext()` | Return whether the broker has next message in target topic. | `Boolean` |
+| `close()` | Closes the reader, disabling its ability to receive messages from the broker. | `Promise<null>` |
+
+### Reader configuration
+
+| Parameter | Description | Default |
+| :-------- | :---------- | :------ |
+| `topic` | The Pulsar [topic](reference-terminology.md#topic) on which the reader will establish a subscription and listen for messages. | |
+| `startMessageId` | The initial reader position, i.e. the message at which the reader begins processing messages. The options are `Pulsar.MessageId.earliest` (the earliest available message on the topic), `Pulsar.MessageId.latest` (the latest available message on the topic), or a message ID object for a position that is not earliest or latest. | |
+| `receiverQueueSize` | Sets the size of the reader's receiver queue, i.e. the number of messages that can be accumulated by the reader before the application calls `readNext`. A value higher than the default of 1000 could increase reader throughput, though at the expense of more memory utilization. | 1000 |
+| `readerName` | The name of the reader. |  |
+| `subscriptionRolePrefix` | The subscription role prefix. | |
+
+### Reader example
+
+This example creates a Node.js reader with the `my-topic` topic, reads messages, and prints the content that arrive for 10 times:
+
+```JavaScript
+
+const Pulsar = require('pulsar-client');
+
+(async () => {
+  // Create a client
+  const client = new Pulsar.Client({
+    serviceUrl: 'pulsar://localhost:6650',
+    operationTimeoutSeconds: 30,
+  });
+
+  // Create a reader
+  const reader = await client.createReader({
+    topic: 'my-topic',
+    startMessageId: Pulsar.MessageId.earliest(),
+  });
+
+  // read messages
+  for (let i = 0; i < 10; i += 1) {
+    const msg = await reader.readNext();
+    console.log(msg.getData().toString());
+  }
+
+  await reader.close();
+  await client.close();
+})();
+
+```
+
+## Messages
+
+In Pulsar Node.js client, you have to construct producer message object for producer.
+
+Here is an example message:
+
+```JavaScript
+
+const msg = {
+  data: Buffer.from('Hello, Pulsar'),
+  partitionKey: 'key1',
+  properties: {
+    'foo': 'bar',
+  },
+  eventTimestamp: Date.now(),
+  replicationClusters: [
+    'cluster1',
+    'cluster2',
+  ],
+}
+
+await producer.send(msg);
+
+```
+
+The following keys are available for producer message objects:
+
+| Parameter | Description |
+| :-------- | :---------- |
+| `data` | The actual data payload of the message. |
+| `properties` | A Object for any application-specific metadata attached to the message. |
+| `eventTimestamp` | The timestamp associated with the message. |
+| `sequenceId` | The sequence ID of the message. |
+| `partitionKey` | The optional key associated with the message (particularly useful for things like topic compaction). |
+| `replicationClusters` | The clusters to which this message will be replicated. Pulsar brokers handle message replication automatically; you should only change this setting if you want to override the broker default. |
+
+### Message object operations
+
+In Pulsar Node.js client, you can receive (or read) message object as consumer (or reader).
+
+The message object have the following methods available:
+
+| Method | Description | Return type |
+| :----- | :---------- | :---------- |
+| `getTopicName()` | Getter method of topic name. | `String` |
+| `getProperties()` | Getter method of properties. | `Array<Object>` |
+| `getData()` | Getter method of message data. | `Buffer` |
+| `getMessageId()` | Getter method of [message id object](#message-id-object-operations). | `Object` |
+| `getPublishTimestamp()` | Getter method of publish timestamp. | `Number` |
+| `getEventTimestamp()` | Getter method of event timestamp. | `Number` |
+| `getPartitionKey()` | Getter method of partition key. | `String` |
+
+### Message ID object operations
+
+In Pulsar Node.js client, you can get message id object from message object.
+
+The message id object have the following methods available:
+
+| Method | Description | Return type |
+| :----- | :---------- | :---------- |
+| `serialize()` | Serialize the message id into a Buffer for storing. | `Buffer` |
+| `toString()` | Get message id as String. | `String` |
+
+The client has static method of message id object. You can access it as `Pulsar.MessageId.someStaticMethod` too.
+
+The following static methods are available for the message id object:
+
+| Method | Description | Return type |
+| :----- | :---------- | :---------- |
+| `earliest()` | MessageId representing the earliest, or oldest available message stored in the topic. | `Object` |
+| `latest()` | MessageId representing the latest, or last published message in the topic. | `Object` |
+| `deserialize(Buffer)` | Deserialize a message id object from a Buffer. | `Object` |
+
diff --git a/site2/website-next/versioned_docs/version-2.6.0/client-libraries-python.md b/site2/website-next/versioned_docs/version-2.6.0/client-libraries-python.md
new file mode 100644
index 0000000..f9f9392
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.6.0/client-libraries-python.md
@@ -0,0 +1,323 @@
+---
+id: client-libraries-python
+title: Pulsar Python client
+sidebar_label: "Python"
+original_id: client-libraries-python
+---
+
+Pulsar Python client library is a wrapper over the existing [C++ client library](client-libraries-cpp) and exposes all of the [same features](/api/cpp). You can find the code in the [`python` subdirectory](https://github.com/apache/pulsar/tree/master/pulsar-client-cpp/python) of the C++ client code.
+
+All the methods in producer, consumer, and reader of a Python client are thread-safe.
+
+[pdoc](https://github.com/BurntSushi/pdoc)-generated API docs for the Python client are available [here](/api/python).
+
+## Install
+
+You can install the [`pulsar-client`](https://pypi.python.org/pypi/pulsar-client) library either via [PyPi](https://pypi.python.org/pypi), using [pip](#installation-using-pip), or by building the library from source.
+
+### Install using pip
+
+To install the `pulsar-client` library as a pre-built package using the [pip](https://pip.pypa.io/en/stable/) package manager:
+
+```shell
+
+$ pip install pulsar-client==@pulsar:version_number@
+
+```
+
+Installation via PyPi is available for the following Python versions:
+
+Platform | Supported Python versions
+:--------|:-------------------------
+MacOS <br />  10.13 (High Sierra), 10.14 (Mojave) <br /> | 2.7, 3.7
+Linux | 2.7, 3.4, 3.5, 3.6, 3.7
+
+### Install from source
+
+To install the `pulsar-client` library by building from source, follow [instructions](client-libraries-cpp.md#compilation) and compile the Pulsar C++ client library. That builds the Python binding for the library.
+
+To install the built Python bindings:
+
+```shell
+
+$ git clone https://github.com/apache/pulsar
+$ cd pulsar/pulsar-client-cpp/python
+$ sudo python setup.py install
+
+```
+
+## API Reference
+
+The complete Python API reference is available at [api/python](/api/python).
+
+## Examples
+
+You can find a variety of Python code examples for the `pulsar-client` library.
+
+### Producer example
+
+The following example creates a Python producer for the `my-topic` topic and sends 10 messages on that topic:
+
+```python
+
+import pulsar
+
+client = pulsar.Client('pulsar://localhost:6650')
+
+producer = client.create_producer('my-topic')
+
+for i in range(10):
+    producer.send(('Hello-%d' % i).encode('utf-8'))
+
+client.close()
+
+```
+
+### Consumer example
+
+The following example creates a consumer with the `my-subscription` subscription name on the `my-topic` topic, receives incoming messages, prints the content and ID of messages that arrive, and acknowledges each message to the Pulsar broker.
+
+```python
+
+import pulsar
+
+client = pulsar.Client('pulsar://localhost:6650')
+
+consumer = client.subscribe('my-topic', 'my-subscription')
+
+while True:
+    msg = consumer.receive()
+    try:
+        print("Received message '{}' id='{}'".format(msg.data(), msg.message_id()))
+        # Acknowledge successful processing of the message
+        consumer.acknowledge(msg)
+    except:
+        # Message failed to be processed
+        consumer.negative_acknowledge(msg)
+
+client.close()
+
+```
+
+This example shows how to configure negative acknowledgement.
+
+```python
+
+from pulsar import Client, schema
+client = Client('pulsar://localhost:6650')
+consumer = client.subscribe('negative_acks','test',schema=schema.StringSchema())
+producer = client.create_producer('negative_acks',schema=schema.StringSchema())
+for i in range(10):
+    print('send msg "hello-%d"' % i)
+    producer.send_async('hello-%d' % i, callback=None)
+producer.flush()
+for i in range(10):
+    msg = consumer.receive()
+    consumer.negative_acknowledge(msg)
+    print('receive and nack msg "%s"' % msg.data())
+for i in range(10):
+    msg = consumer.receive()
+    consumer.acknowledge(msg)
+    print('receive and ack msg "%s"' % msg.data())
+try:
+    # No more messages expected
+    msg = consumer.receive(100)
+except:
+    print("no more msg")
+    pass
+
+```
+
+### Reader interface example
+
+You can use the Pulsar Python API to use the Pulsar [reader interface](concepts-clients.md#reader-interface). Here's an example:
+
+```python
+
+# MessageId taken from a previously fetched message
+msg_id = msg.message_id()
+
+reader = client.create_reader('my-topic', msg_id)
+
+while True:
+    msg = reader.read_next()
+    print("Received message '{}' id='{}'".format(msg.data(), msg.message_id()))
+    # No acknowledgment
+
+```
+
+### Multi-topic subscriptions
+
+In addition to subscribing a consumer to a single Pulsar topic, you can also subscribe to multiple topics simultaneously. To use multi-topic subscriptions, you can supply a regular expression (regex) or a `List` of topics. If you select topics via regex, all topics must be within the same Pulsar namespace.
+
+The following is an example. 
+
+```python
+
+import re
+consumer = client.subscribe(re.compile('persistent://public/default/topic-*'), 'my-subscription')
+while True:
+    msg = consumer.receive()
+    try:
+        print("Received message '{}' id='{}'".format(msg.data(), msg.message_id()))
+        # Acknowledge successful processing of the message
+        consumer.acknowledge(msg)
+    except:
+        # Message failed to be processed
+        consumer.negative_acknowledge(msg)
+client.close()
+
+```
+
+## Schema
+
+### Declare and validate schema
+
+You can declare a schema by passing a class that inherits
+from `pulsar.schema.Record` and defines the fields as
+class variables. For example:
+
+```python
+
+from pulsar.schema import *
+
+class Example(Record):
+    a = String()
+    b = Integer()
+    c = Boolean()
+
+```
+
+With this simple schema definition, you can create producers, consumers and readers instances that refer to that.
+
+```python
+
+producer = client.create_producer(
+                    topic='my-topic',
+                    schema=AvroSchema(Example) )
+
+producer.send(Example(a='Hello', b=1))
+
+```
+
+After creating the producer, the Pulsar broker validates that the existing topic schema is indeed of "Avro" type and that the format is compatible with the schema definition of the `Example` class.
+
+If there is a mismatch, an exception occurs in the producer creation.
+
+Once a producer is created with a certain schema definition,
+it will only accept objects that are instances of the declared
+schema class.
+
+Similarly, for a consumer/reader, the consumer will return an
+object, instance of the schema record class, rather than the raw
+bytes:
+
+```python
+
+consumer = client.subscribe(
+                  topic='my-topic',
+                  subscription_name='my-subscription',
+                  schema=AvroSchema(Example) )
+
+while True:
+    msg = consumer.receive()
+    ex = msg.value()
+    try:
+        print("Received message a={} b={} c={}".format(ex.a, ex.b, ex.c))
+        # Acknowledge successful processing of the message
+        consumer.acknowledge(msg)
+    except:
+        # Message failed to be processed
+        consumer.negative_acknowledge(msg)
+
+```
+
+### Supported schema types
+
+You can use different builtin schema types in Pulsar. All the definitions are in the `pulsar.schema` package.
+
+| Schema | Notes |
+| ------ | ----- |
+| `BytesSchema` | Get the raw payload as a `bytes` object. No serialization/deserialization are performed. This is the default schema mode |
+| `StringSchema` | Encode/decode payload as a UTF-8 string. Uses `str` objects |
+| `JsonSchema` | Require record definition. Serializes the record into standard JSON payload |
+| `AvroSchema` | Require record definition. Serializes in AVRO format |
+
+### Schema definition reference
+
+The schema definition is done through a class that inherits from `pulsar.schema.Record`.
+
+This class has a number of fields which can be of either
+`pulsar.schema.Field` type or another nested `Record`. All the
+fields are specified in the `pulsar.schema` package. The fields
+are matching the AVRO fields types.
+
+| Field Type | Python Type | Notes |
+| ---------- | ----------- | ----- |
+| `Boolean`  | `bool`      |       |
+| `Integer`  | `int`       |       |
+| `Long`     | `int`       |       |
+| `Float`    | `float`     |       |
+| `Double`   | `float`     |       |
+| `Bytes`    | `bytes`     |       |
+| `String`   | `str`       |       |
+| `Array`    | `list`      | Need to specify record type for items. |
+| `Map`      | `dict`      | Key is always `String`. Need to specify value type. |
+
+Additionally, any Python `Enum` type can be used as a valid field type.
+
+#### Fields parameters
+
+When adding a field, you can use these parameters in the constructor.
+
+| Argument   | Default | Notes |
+| ---------- | --------| ----- |
+| `default`  | `None`  | Set a default value for the field. Eg: `a = Integer(default=5)` |
+| `required` | `False` | Mark the field as "required". It is set in the schema accordingly. |
+
+#### Schema definition examples
+
+##### Simple definition
+
+```python
+
+class Example(Record):
+    a = String()
+    b = Integer()
+    c = Array(String())
+    i = Map(String())
+
+```
+
+##### Using enums
+
+```python
+
+from enum import Enum
+
+class Color(Enum):
+    red = 1
+    green = 2
+    blue = 3
+
+class Example(Record):
+    name = String()
+    color = Color
+
+```
+
+##### Complex types
+
+```python
+
+class MySubRecord(Record):
+    x = Integer()
+    y = Long()
+    z = String()
+
+class Example(Record):
+    a = String()
+    sub = MySubRecord()
+
+```
+
diff --git a/site2/website-next/versioned_docs/version-2.6.0/client-libraries-websocket.md b/site2/website-next/versioned_docs/version-2.6.0/client-libraries-websocket.md
new file mode 100644
index 0000000..9cc5d4a
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.6.0/client-libraries-websocket.md
@@ -0,0 +1,491 @@
+---
+id: client-libraries-websocket
+title: Pulsar's WebSocket API
+sidebar_label: "WebSocket"
+original_id: client-libraries-websocket
+---
+
+Pulsar's [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API) API is meant to provide a simple way to interact with Pulsar using languages that do not have an official [client library](getting-started-clients.md). Through WebSockets you can publish and consume messages and use all the features available in the [Java](client-libraries-java.md), [Go](client-libraries-go.md), [Python](client-libraries-python.md) and [C++](client-libraries-cpp) client libraries.
+
+
+> You can use Pulsar's WebSocket API with any WebSocket client library. See examples for Python and Node.js [below](#client-examples).
+
+## Running the WebSocket service
+
+The standalone variant of Pulsar that we recommend using for [local development](getting-started-standalone) already has the WebSocket service enabled.
+
+In non-standalone mode, there are two ways to deploy the WebSocket service:
+
+* [embedded](#embedded-with-a-pulsar-broker) with a Pulsar broker
+* as a [separate component](#as-a-separate-component)
+
+### Embedded with a Pulsar broker
+
+In this mode, the WebSocket service will run within the same HTTP service that's already running in the broker. To enable this mode, set the [`webSocketServiceEnabled`](reference-configuration.md#broker-webSocketServiceEnabled) parameter in the [`conf/broker.conf`](reference-configuration.md#broker) configuration file in your installation.
+
+```properties
+
+webSocketServiceEnabled=true
+
+```
+
+### As a separate component
+
+In this mode, the WebSocket service will be run from a Pulsar [broker](reference-terminology.md#broker) as a separate service. Configuration for this mode is handled in the [`conf/websocket.conf`](reference-configuration.md#websocket) configuration file. You'll need to set *at least* the following parameters:
+
+* [`configurationStoreServers`](reference-configuration.md#websocket-configurationStoreServers)
+* [`webServicePort`](reference-configuration.md#websocket-webServicePort)
+* [`clusterName`](reference-configuration.md#websocket-clusterName)
+
+Here's an example:
+
+```properties
+
+configurationStoreServers=zk1:2181,zk2:2181,zk3:2181
+webServicePort=8080
+clusterName=my-cluster
+
+```
+
+### Starting the broker
+
+When the configuration is set, you can start the service using the [`pulsar-daemon`](reference-cli-tools.md#pulsar-daemon) tool:
+
+```shell
+
+$ bin/pulsar-daemon start websocket
+
+```
+
+## API Reference
+
+Pulsar's WebSocket API offers three endpoints for [producing](#producer-endpoint) messages, [consuming](#consumer-endpoint) messages and [reading](#reader-endpoint) messages.
+
+All exchanges via the WebSocket API use JSON.
+
+### Producer endpoint
+
+The producer endpoint requires you to specify a tenant, namespace, and topic in the URL:
+
+```http
+
+ws://broker-service-url:8080/ws/v2/producer/persistent/:tenant/:namespace/:topic
+
+```
+
+##### Query param
+
+Key | Type | Required? | Explanation
+:---|:-----|:----------|:-----------
+`sendTimeoutMillis` | long | no | Send timeout (default: 30 secs)
+`batchingEnabled` | boolean | no | Enable batching of messages (default: false)
+`batchingMaxMessages` | int | no | Maximum number of messages permitted in a batch (default: 1000)
+`maxPendingMessages` | int | no | Set the max size of the internal-queue holding the messages (default: 1000)
+`batchingMaxPublishDelay` | long | no | Time period within which the messages will be batched (default: 10ms)
+`messageRoutingMode` | string | no | Message [routing mode](https://pulsar.apache.org/api/client/index.html?org/apache/pulsar/client/api/ProducerConfiguration.MessageRoutingMode.html) for the partitioned producer: `SinglePartition`, `RoundRobinPartition`
+`compressionType` | string | no | Compression [type](https://pulsar.apache.org/api/client/index.html?org/apache/pulsar/client/api/CompressionType.html): `LZ4`, `ZLIB`
+`producerName` | string | no | Specify the name for the producer. Pulsar will enforce only one producer with same name can be publishing on a topic
+`initialSequenceId` | long | no | Set the baseline for the sequence ids for messages published by the producer.
+`hashingScheme` | string | no | [Hashing function](http://pulsar.apache.org/api/client/org/apache/pulsar/client/api/ProducerConfiguration.HashingScheme.html) to use when publishing on a partitioned topic: `JavaStringHash`, `Murmur3_32Hash`
+
+
+#### Publishing a message
+
+```json
+
+{
+  "payload": "SGVsbG8gV29ybGQ=",
+  "properties": {"key1": "value1", "key2": "value2"},
+  "context": "1"
+}
+
+```
+
+Key | Type | Required? | Explanation
+:---|:-----|:----------|:-----------
+`payload` | string | yes | Base-64 encoded payload
+`properties` | key-value pairs | no | Application-defined properties
+`context` | string | no | Application-defined request identifier
+`key` | string | no | For partitioned topics, decides which partition to use
+`replicationClusters` | array | no | Restrict replication to this list of [clusters](reference-terminology.md#cluster), specified by name
+
+
+##### Example success response
+
+```json
+
+{
+   "result": "ok",
+   "messageId": "CAAQAw==",
+   "context": "1"
+ }
+
+```
+
+##### Example failure response
+
+```json
+
+ {
+   "result": "send-error:3",
+   "errorMsg": "Failed to de-serialize from JSON",
+   "context": "1"
+ }
+
+```
+
+Key | Type | Required? | Explanation
+:---|:-----|:----------|:-----------
+`result` | string | yes | `ok` if successful or an error message if unsuccessful
+`messageId` | string | yes | Message ID assigned to the published message
+`context` | string | no | Application-defined request identifier
+
+
+### Consumer endpoint
+
+The consumer endpoint requires you to specify a tenant, namespace, and topic, as well as a subscription, in the URL:
+
+```http
+
+ws://broker-service-url:8080/ws/v2/consumer/persistent/:tenant/:namespace/:topic/:subscription
+
+```
+
+##### Query param
+
+Key | Type | Required? | Explanation
+:---|:-----|:----------|:-----------
+`ackTimeoutMillis` | long | no | Set the timeout for unacked messages (default: 0)
+`subscriptionType` | string | no | [Subscription type](https://pulsar.apache.org/api/client/index.html?org/apache/pulsar/client/api/SubscriptionType.html): `Exclusive`, `Failover`, `Shared`, `Key_Shared`
+`receiverQueueSize` | int | no | Size of the consumer receive queue (default: 1000)
+`consumerName` | string | no | Consumer name
+`priorityLevel` | int | no | Define a [priority](http://pulsar.apache.org/api/client/org/apache/pulsar/client/api/ConsumerConfiguration.html#setPriorityLevel-int-) for the consumer
+`maxRedeliverCount` | int | no | Define a [maxRedeliverCount](http://pulsar.apache.org/api/client/org/apache/pulsar/client/api/ConsumerBuilder.html#deadLetterPolicy-org.apache.pulsar.client.api.DeadLetterPolicy-) for the consumer (default: 0). Activates [Dead Letter Topic](https://github.com/apache/pulsar/wiki/PIP-22%3A-Pulsar-Dead-Letter-Topic) feature.
+`deadLetterTopic` | string | no | Define a [deadLetterTopic](http://pulsar.apache.org/api/client/org/apache/pulsar/client/api/ConsumerBuilder.html#deadLetterPolicy-org.apache.pulsar.client.api.DeadLetterPolicy-) for the consumer (default: {topic}-{subscription}-DLQ). Activates [Dead Letter Topic](https://github.com/apache/pulsar/wiki/PIP-22%3A-Pulsar-Dead-Letter-Topic) feature.
+`pullMode` | boolean | no | Enable pull mode (default: false). See "Flow Control" below.
+
+NB: these parameter (except `pullMode`) apply to the internal consumer of the WebSocket service.
+So messages will be subject to the redelivery settings as soon as the get into the receive queue,
+even if the client doesn't consume on the WebSocket.
+
+##### Receiving messages
+
+Server will push messages on the WebSocket session:
+
+```json
+
+{
+  "messageId": "CAAQAw==",
+  "payload": "SGVsbG8gV29ybGQ=",
+  "properties": {"key1": "value1", "key2": "value2"},
+  "publishTime": "2016-08-30 16:45:57.785"
+}
+
+```
+
+Key | Type | Required? | Explanation
+:---|:-----|:----------|:-----------
+`messageId` | string | yes | Message ID
+`payload` | string | yes | Base-64 encoded payload
+`publishTime` | string | yes | Publish timestamp
+`properties` | key-value pairs | no | Application-defined properties
+`key` | string | no |  Original routing key set by producer
+
+#### Acknowledging the message
+
+Consumer needs to acknowledge the successful processing of the message to
+have the Pulsar broker delete it.
+
+```json
+
+{
+  "messageId": "CAAQAw=="
+}
+
+```
+
+Key | Type | Required? | Explanation
+:---|:-----|:----------|:-----------
+`messageId`| string | yes | Message ID of the processed message
+
+#### Flow control
+
+##### Push Mode
+
+By default (`pullMode=false`), the consumer endpoint will use the `receiverQueueSize` parameter both to size its
+internal receive queue and to limit the number of unacknowledged messages that are passed to the WebSocket client.
+In this mode, if you don't send acknowledgements, the Pulsar WebSocket service will stop sending messages after reaching
+`receiverQueueSize` unacked messages sent to the WebSocket client.
+
+##### Pull Mode
+
+If you set `pullMode` to `true`, the WebSocket client will need to send `permit` commands to permit the
+Pulsar WebSocket service to send more messages.
+
+```json
+
+{
+  "type": "permit",
+  "permitMessages": 100
+}
+
+```
+
+Key | Type | Required? | Explanation
+:---|:-----|:----------|:-----------
+`type`| string | yes | Type of command. Must be `permit`
+`permitMessages`| int | yes | Number of messages to permit
+
+NB: in this mode it's possible to acknowledge messages in a different connection.
+
+### Reader endpoint
+
+The reader endpoint requires you to specify a tenant, namespace, and topic in the URL:
+
+```http
+
+ws://broker-service-url:8080/ws/v2/reader/persistent/:tenant/:namespace/:topic
+
+```
+
+##### Query param
+
+Key | Type | Required? | Explanation
+:---|:-----|:----------|:-----------
+`readerName` | string | no | Reader name
+`receiverQueueSize` | int | no | Size of the consumer receive queue (default: 1000)
+`messageId` | int or enum | no | Message ID to start from, `earliest` or `latest` (default: `latest`)
+
+##### Receiving messages
+
+Server will push messages on the WebSocket session:
+
+```json
+
+{
+  "messageId": "CAAQAw==",
+  "payload": "SGVsbG8gV29ybGQ=",
+  "properties": {"key1": "value1", "key2": "value2"},
+  "publishTime": "2016-08-30 16:45:57.785"
+}
+
+```
+
+Key | Type | Required? | Explanation
+:---|:-----|:----------|:-----------
+`messageId` | string | yes | Message ID
+`payload` | string | yes | Base-64 encoded payload
+`publishTime` | string | yes | Publish timestamp
+`properties` | key-value pairs | no | Application-defined properties
+`key` | string | no |  Original routing key set by producer
+
+#### Acknowledging the message
+
+**In WebSocket**, Reader needs to acknowledge the successful processing of the message to
+have the Pulsar WebSocket service update the number of pending messages.
+If you don't send acknowledgements, Pulsar WebSocket service will stop sending messages after reaching the pendingMessages limit.
+
+```json
+
+{
+  "messageId": "CAAQAw=="
+}
+
+```
+
+Key | Type | Required? | Explanation
+:---|:-----|:----------|:-----------
+`messageId`| string | yes | Message ID of the processed message
+
+
+### Error codes
+
+In case of error the server will close the WebSocket session using the
+following error codes:
+
+Error Code | Error Message
+:----------|:-------------
+1 | Failed to create producer
+2 | Failed to subscribe
+3 | Failed to deserialize from JSON
+4 | Failed to serialize to JSON
+5 | Failed to authenticate client
+6 | Client is not authorized
+7 | Invalid payload encoding
+8 | Unknown error
+
+> The application is responsible for re-establishing a new WebSocket session after a backoff period.
+
+## Client examples
+
+Below you'll find code examples for the Pulsar WebSocket API in [Python](#python) and [Node.js](#nodejs).
+
+### Python
+
+This example uses the [`websocket-client`](https://pypi.python.org/pypi/websocket-client) package. You can install it using [pip](https://pypi.python.org/pypi/pip):
+
+```shell
+
+$ pip install websocket-client
+
+```
+
+You can also download it from [PyPI](https://pypi.python.org/pypi/websocket-client).
+
+#### Python producer
+
+Here's an example Python producer that sends a simple message to a Pulsar [topic](reference-terminology.md#topic):
+
+```python
+
+import websocket, base64, json
+
+TOPIC = 'ws://localhost:8080/ws/v2/producer/persistent/public/default/my-topic'
+
+ws = websocket.create_connection(TOPIC)
+
+# Send one message as JSON
+ws.send(json.dumps({
+    'payload' : base64.b64encode('Hello World'),
+    'properties': {
+        'key1' : 'value1',
+        'key2' : 'value2'
+    },
+    'context' : 5
+}))
+
+response =  json.loads(ws.recv())
+if response['result'] == 'ok':
+    print 'Message published successfully'
+else:
+    print 'Failed to publish message:', response
+ws.close()
+
+```
+
+#### Python consumer
+
+Here's an example Python consumer that listens on a Pulsar topic and prints the message ID whenever a message arrives:
+
+```python
+
+import websocket, base64, json
+
+TOPIC = 'ws://localhost:8080/ws/v2/consumer/persistent/public/default/my-topic/my-sub'
+
+ws = websocket.create_connection(TOPIC)
+
+while True:
+    msg = json.loads(ws.recv())
+    if not msg: break
+
+    print "Received: {} - payload: {}".format(msg, base64.b64decode(msg['payload']))
+
+    # Acknowledge successful processing
+    ws.send(json.dumps({'messageId' : msg['messageId']}))
+
+ws.close()
+
+```
+
+#### Python reader
+
+Here's an example Python reader that listens on a Pulsar topic and prints the message ID whenever a message arrives:
+
+```python
+
+import websocket, base64, json
+
+TOPIC = 'ws://localhost:8080/ws/v2/reader/persistent/public/default/my-topic'
+
+ws = websocket.create_connection(TOPIC)
+
+while True:
+    msg = json.loads(ws.recv())
+    if not msg: break
+
+    print "Received: {} - payload: {}".format(msg, base64.b64decode(msg['payload']))
+
+    # Acknowledge successful processing
+    ws.send(json.dumps({'messageId' : msg['messageId']}))
+
+ws.close()
+
+```
+
+### Node.js
+
+This example uses the [`ws`](https://websockets.github.io/ws/) package. You can install it using [npm](https://www.npmjs.com/):
+
+```shell
+
+$ npm install ws
+
+```
+
+#### Node.js producer
+
+Here's an example Node.js producer that sends a simple message to a Pulsar topic:
+
+```javascript
+
+var WebSocket = require('ws'),
+    topic = "ws://localhost:8080/ws/v2/producer/persistent/public/default/my-topic",
+    ws = new WebSocket(topic);
+
+var message = {
+  "payload" : new Buffer("Hello World").toString('base64'),
+  "properties": {
+    "key1" : "value1",
+    "key2" : "value2"
+  },
+  "context" : "1"
+};
+
+ws.on('open', function() {
+  // Send one message
+  ws.send(JSON.stringify(message));
+});
+
+ws.on('message', function(message) {
+  console.log('received ack: %s', message);
+});
+
+```
+
+#### Node.js consumer
+
+Here's an example Node.js consumer that listens on the same topic used by the producer above:
+
+```javascript
+
+var WebSocket = require('ws'),
+    topic = "ws://localhost:8080/ws/v2/consumer/persistent/public/default/my-topic/my-sub",
+    ws = new WebSocket(topic);
+
+ws.on('message', function(message) {
+    var receiveMsg = JSON.parse(message);
+    console.log('Received: %s - payload: %s', message, new Buffer(receiveMsg.payload, 'base64').toString());
+    var ackMsg = {"messageId" : receiveMsg.messageId};
+    ws.send(JSON.stringify(ackMsg));
+});
+
+```
+
+#### NodeJS reader
+
+```javascript
+
+var WebSocket = require('ws'),
+    topic = "ws://localhost:8080/ws/v2/reader/persistent/public/default/my-topic",
+    ws = new WebSocket(topic);
+
+ws.on('message', function(message) {
+    var receiveMsg = JSON.parse(message);
+    console.log('Received: %s - payload: %s', message, new Buffer(receiveMsg.payload, 'base64').toString());
+    var ackMsg = {"messageId" : receiveMsg.messageId};
+    ws.send(JSON.stringify(ackMsg));
+});
+
+```
+
diff --git a/site2/website-next/versioned_docs/version-2.6.0/deploy-aws.md b/site2/website-next/versioned_docs/version-2.6.0/deploy-aws.md
new file mode 100644
index 0000000..4845db0
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.6.0/deploy-aws.md
@@ -0,0 +1,268 @@
+---
+id: deploy-aws
+title: Deploying a Pulsar cluster on AWS using Terraform and Ansible
+sidebar_label: "Amazon Web Services"
+original_id: deploy-aws
+---
+
+> For instructions on deploying a single Pulsar cluster manually rather than using Terraform and Ansible, see [Deploying a Pulsar cluster on bare metal](deploy-bare-metal.md). For instructions on manually deploying a multi-cluster Pulsar instance, see [Deploying a Pulsar instance on bare metal](deploy-bare-metal-multi-cluster).
+
+One of the easiest ways to get a Pulsar [cluster](reference-terminology.md#cluster) running on [Amazon Web Services](https://aws.amazon.com/) (AWS) is to use the [Terraform](https://terraform.io) infrastructure provisioning tool and the [Ansible](https://www.ansible.com) server automation tool. Terraform can create the resources necessary for running the Pulsar cluster---[EC2](https://aws.amazon.com/ec2/) instances, networking and security infrastructure, etc.---While Ansible can install [...]
+
+## Requirements and setup
+
+In order to install a Pulsar cluster on AWS using Terraform and Ansible, you need to prepare the following things:
+
+* An [AWS account](https://aws.amazon.com/account/) and the [`aws`](https://aws.amazon.com/cli/) command-line tool
+* Python and [pip](https://pip.pypa.io/en/stable/)
+* The [`terraform-inventory`](https://github.com/adammck/terraform-inventory) tool, which enables Ansible to use Terraform artifacts
+
+You also need to make sure that you are currently logged into your AWS account via the `aws` tool:
+
+```bash
+
+$ aws configure
+
+```
+
+## Installation
+
+You can install Ansible on Linux or macOS using pip.
+
+```bash
+
+$ pip install ansible
+
+```
+
+You can install Terraform using the instructions [here](https://www.terraform.io/intro/getting-started/install.html).
+
+You also need to have the Terraform and Ansible configuration for Pulsar locally on your machine. You can find them in the [GitHub repository](https://github.com/apache/pulsar) of Pulsar, which you can fetch using Git commands:
+
+```bash
+
+$ git clone https://github.com/apache/pulsar
+$ cd pulsar/deployment/terraform-ansible/aws
+
+```
+
+## SSH setup
+
+> If you already have an SSH key and want to use it, you can skip the step of generating an SSH key and update `private_key_file` setting
+> in `ansible.cfg` file and `public_key_path` setting in `terraform.tfvars` file.
+>
+> For example, if you already have a private SSH key in `~/.ssh/pulsar_aws` and a public key in `~/.ssh/pulsar_aws.pub`,
+> follow the steps below:
+>
+> 1. update `ansible.cfg` with following values:
+>
+
+> ```shell
+> 
+> private_key_file=~/.ssh/pulsar_aws
+>
+> 
+> ```
+
+>
+> 2. update `terraform.tfvars` with following values:
+>
+
+> ```shell
+> 
+> public_key_path=~/.ssh/pulsar_aws.pub
+>
+> 
+> ```
+
+
+In order to create the necessary AWS resources using Terraform, you need to create an SSH key. Enter the following commands to create a private SSH key in `~/.ssh/id_rsa` and a public key in `~/.ssh/id_rsa.pub`:
+
+```bash
+
+$ ssh-keygen -t rsa
+
+```
+
+Do *not* enter a passphrase (hit **Enter** instead when the prompt comes out). Enter the following command to verify that a key has been created:
+
+```bash
+
+$ ls ~/.ssh
+id_rsa               id_rsa.pub
+
+```
+
+## Create AWS resources using Terraform
+
+To start building AWS resources with Terraform, you need to install all Terraform dependencies. Enter the following command:
+
+```bash
+
+$ terraform init
+# This will create a .terraform folder
+
+```
+
+After that, you can apply the default Terraform configuration by entering this command:
+
+```bash
+
+$ terraform apply
+
+```
+
+Then you see this prompt below:
+
+```bash
+
+Do you want to perform these actions?
+  Terraform will perform the actions described above.
+  Only 'yes' will be accepted to approve.
+
+  Enter a value:
+
+```
+
+Type `yes` and hit **Enter**. Applying the configuration could take several minutes. When the configuration applying finishes, you can see `Apply complete!` along with some other information, including the number of resources created.
+
+### Apply a non-default configuration
+
+You can apply a non-default Terraform configuration by changing the values in the `terraform.tfvars` file. The following variables are available:
+
+Variable name | Description | Default
+:-------------|:------------|:-------
+`public_key_path` | The path of the public key that you have generated. | `~/.ssh/id_rsa.pub`
+`region` | The AWS region in which the Pulsar cluster runs | `us-west-2`
+`availability_zone` | The AWS availability zone in which the Pulsar cluster runs | `us-west-2a`
+`aws_ami` | The [Amazon Machine Image](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html) (AMI) that the cluster uses  | `ami-9fa343e7`
+`num_zookeeper_nodes` | The number of [ZooKeeper](https://zookeeper.apache.org) nodes in the ZooKeeper cluster | 3
+`num_bookie_nodes` | The number of bookies that runs in the cluster | 3
+`num_broker_nodes` | The number of Pulsar brokers that runs in the cluster | 2
+`num_proxy_nodes` | The number of Pulsar proxies that runs in the cluster | 1
+`base_cidr_block` | The root [CIDR](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing) that network assets uses for the cluster | `10.0.0.0/16`
+`instance_types` | The EC2 instance types to be used. This variable is a map with two keys: `zookeeper` for the ZooKeeper instances, `bookie` for the BookKeeper bookies and `broker` and `proxy` for Pulsar brokers and bookies | `t2.small` (ZooKeeper), `i3.xlarge` (BookKeeper) and `c5.2xlarge` (Brokers/Proxies)
+
+### What is installed
+
+When you run the Ansible playbook, the following AWS resources are used:
+
+* 9 total [Elastic Compute Cloud](https://aws.amazon.com/ec2) (EC2) instances running the [ami-9fa343e7](https://access.redhat.com/articles/3135091) Amazon Machine Image (AMI), which runs [Red Hat Enterprise Linux (RHEL) 7.4](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html-single/7.4_release_notes/index). By default, that includes:
+  * 3 small VMs for ZooKeeper ([t2.small](https://www.ec2instances.info/?selected=t2.small) instances)
+  * 3 larger VMs for BookKeeper [bookies](reference-terminology.md#bookie) ([i3.xlarge](https://www.ec2instances.info/?selected=i3.xlarge) instances)
+  * 2 larger VMs for Pulsar [brokers](reference-terminology.md#broker) ([c5.2xlarge](https://www.ec2instances.info/?selected=c5.2xlarge) instances)
+  * 1 larger VMs for Pulsar [proxy](reference-terminology.md#proxy) ([c5.2xlarge](https://www.ec2instances.info/?selected=c5.2xlarge) instances)
+* An EC2 [security group](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-network-security.html)
+* A [virtual private cloud](https://aws.amazon.com/vpc/) (VPC) for security
+* An [API Gateway](https://aws.amazon.com/api-gateway/) for connections from the outside world
+* A [route table](http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_Route_Tables.html) for the Pulsar cluster's VPC
+* A [subnet](http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_Subnets.html) for the VPC
+
+All EC2 instances for the cluster run in the [us-west-2](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html) region.
+
+### Fetch your Pulsar connection URL
+
+When you apply the Terraform configuration by entering the command `terraform apply`, Terraform outputs a value for the `pulsar_service_url`. The value should look something like this:
+
+```
+
+pulsar://pulsar-elb-1800761694.us-west-2.elb.amazonaws.com:6650
+
+```
+
+You can fetch that value at any time by entering the command `terraform output pulsar_service_url` or parsing the `terraform.tstate` file (which is JSON, even though the filename does not reflect that):
+
+```bash
+
+$ cat terraform.tfstate | jq .modules[0].outputs.pulsar_service_url.value
+
+```
+
+### Destroy your cluster
+
+At any point, you can destroy all AWS resources associated with your cluster using Terraform's `destroy` command:
+
+```bash
+
+$ terraform destroy
+
+```
+
+## Setup Disks
+
+Before you run the Pulsar playbook, you need to mount the disks to the correct directories on those bookie nodes. Since different type of machines have different disk layout, you need to update the task defined in `setup-disk.yaml` file after changing the `instance_types` in your terraform config,
+
+To setup disks on bookie nodes, enter this command:
+
+```bash
+
+$ ansible-playbook \
+  --user='ec2-user' \
+  --inventory=`which terraform-inventory` \
+  setup-disk.yaml
+
+```
+
+After that, the disks is mounted under `/mnt/journal` as journal disk, and `/mnt/storage` as ledger disk.
+Remember to enter this command just only once. If you attempt to enter this command again after you have run Pulsar playbook, your disks might potentially be erased again, causing the bookies to fail to start up.
+
+## Run the Pulsar playbook
+
+Once you have created the necessary AWS resources using Terraform, you can install and run Pulsar on the Terraform-created EC2 instances using Ansible. To do so, enter this command:
+
+```bash
+
+$ ansible-playbook \
+  --user='ec2-user' \
+  --inventory=`which terraform-inventory` \
+  ../deploy-pulsar.yaml
+
+```
+
+If you have created a private SSH key at a location different from `~/.ssh/id_rsa`, you can specify the different location using the `--private-key` flag in the following command:
+
+```bash
+
+$ ansible-playbook \
+  --user='ec2-user' \
+  --inventory=`which terraform-inventory` \
+  --private-key="~/.ssh/some-non-default-key" \
+  ../deploy-pulsar.yaml
+
+```
+
+## Access the cluster
+
+You can now access your running Pulsar using the unique Pulsar connection URL for your cluster, which you can obtain following the instructions [above](#fetching-your-pulsar-connection-url).
+
+For a quick demonstration of accessing the cluster, we can use the Python client for Pulsar and the Python shell. First, install the Pulsar Python module using pip:
+
+```bash
+
+$ pip install pulsar-client
+
+```
+
+Now, open up the Python shell using the `python` command:
+
+```bash
+
+$ python
+
+```
+
+Once you are in the shell, enter the following command:
+
+```python
+
+>>> import pulsar
+>>> client = pulsar.Client('pulsar://pulsar-elb-1800761694.us-west-2.elb.amazonaws.com:6650')
+# Make sure to use your connection URL
+>>> producer = client.create_producer('persistent://public/default/test-topic')
+>>> producer.send('Hello world')
+>>> client.close()
+
+```
+
+If all of these commands are successful, Pulsar clients can now use your cluster!
+
diff --git a/site2/website-next/versioned_docs/version-2.6.0/deploy-bare-metal-multi-cluster.md b/site2/website-next/versioned_docs/version-2.6.0/deploy-bare-metal-multi-cluster.md
new file mode 100644
index 0000000..c81f2ef
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.6.0/deploy-bare-metal-multi-cluster.md
@@ -0,0 +1,479 @@
+---
+id: deploy-bare-metal-multi-cluster
+title: Deploying a multi-cluster on bare metal
+sidebar_label: "Bare metal multi-cluster"
+original_id: deploy-bare-metal-multi-cluster
+---
+
+:::tip
+
+1. Single-cluster Pulsar installations should be sufficient for all but the most ambitious use cases. If you are interested in experimenting with
+Pulsar or using it in a startup or on a single team, you had better opt for a single cluster. For instructions on deploying a single cluster,
+see the guide [here](deploy-bare-metal).
+2. If you want to use all builtin [Pulsar IO](io-overview) connectors in your Pulsar deployment, you need to download `apache-pulsar-io-connectors`
+package and install `apache-pulsar-io-connectors` under `connectors` directory in the pulsar directory on every broker node or on every function-worker node if you
+run a separate cluster of function workers for [Pulsar Functions](functions-overview).
+3. If you want to use [Tiered Storage](concepts-tiered-storage) feature in your Pulsar deployment, you need to download `apache-pulsar-offloaders`
+package and install `apache-pulsar-offloaders` under `offloaders` directory in the pulsar directory on every broker node. For more details of how to configure
+this feature, you can refer to the [Tiered storage cookbook](cookbooks-tiered-storage).
+
+:::
+
+A Pulsar *instance* consists of multiple Pulsar clusters working in unison. You can distribute clusters across data centers or geographical regions and replicate the clusters amongst themselves using [geo-replication](administration-geo). Deploying a multi-cluster Pulsar instance involves the following basic steps:
+
+* Deploying two separate [ZooKeeper](#deploy-zookeeper) quorums: a [local](#deploy-local-zookeeper) quorum for each cluster in the instance and a [configuration store](#configuration-store) quorum for instance-wide tasks
+* Initializing [cluster metadata](#cluster-metadata-initialization) for each cluster
+* Deploying a [BookKeeper cluster](#deploy-bookkeeper) of bookies in each Pulsar cluster
+* Deploying [brokers](#deploy-brokers) in each Pulsar cluster
+
+If you want to deploy a single Pulsar cluster, see [Clusters and Brokers](getting-started-standalone.md#start-the-cluster).
+
+> #### Run Pulsar locally or on Kubernetes?
+> This guide shows you how to deploy Pulsar in production in a non-Kubernetes environment. If you want to run a standalone Pulsar cluster on a single machine for development purposes, see the [Setting up a local cluster](getting-started-standalone.md) guide. If you want to run Pulsar on [Kubernetes](https://kubernetes.io), see the [Pulsar on Kubernetes](deploy-kubernetes) guide, which includes sections on running Pulsar on Kubernetes on [Google Kubernetes Engine](deploy-kubernetes#pulsar [...]
+
+## System requirement
+Currently, Pulsar is available for 64-bit **macOS**, **Linux**, and **Windows**. To use Pulsar, you need to install 64-bit JRE/JDK 8 or later versions.
+
+## Install Pulsar
+
+To get started running Pulsar, download a binary tarball release in one of the following ways:
+
+* by clicking the link below and downloading the release from an Apache mirror:
+
+  * <a href="pulsar:binary_release_url" download>Pulsar @pulsar:version@ binary release</a>
+
+* from the Pulsar [downloads page](pulsar:download_page_url)
+* from the Pulsar [releases page](https://github.com/apache/pulsar/releases/latest)
+* using [wget](https://www.gnu.org/software/wget):
+
+  ```shell
+  
+  $ wget 'https://www.apache.org/dyn/mirrors/mirrors.cgi?action=download&filename=pulsar/pulsar-@pulsar:version@/apache-pulsar-@pulsar:version@-bin.tar.gz' -O apache-pulsar-@pulsar:version@-bin.tar.gz
+  
+  ```
+
+Once you download the tarball, untar it and `cd` into the resulting directory:
+
+```bash
+
+$ tar xvfz apache-pulsar-@pulsar:version@-bin.tar.gz
+$ cd apache-pulsar-@pulsar:version@
+
+```
+
+## What your package contains
+
+The Pulsar binary package initially contains the following directories:
+
+Directory | Contains
+:---------|:--------
+`bin` | [Command-line tools](reference-cli-tools) of Pulsar, such as [`pulsar`](reference-cli-tools.md#pulsar) and [`pulsar-admin`](https://pulsar.apache.org/tools/pulsar-admin/)
+`conf` | Configuration files for Pulsar, including for [broker configuration](reference-configuration.md#broker), [ZooKeeper configuration](reference-configuration.md#zookeeper), and more
+`examples` | A Java JAR file containing example [Pulsar Functions](functions-overview)
+`lib` | The [JAR](https://en.wikipedia.org/wiki/JAR_(file_format)) files that Pulsar uses 
+`licenses` | License files, in `.txt` form, for various components of the Pulsar codebase
+
+The following directories are created once you begin running Pulsar:
+
+Directory | Contains
+:---------|:--------
+`data` | The data storage directory that ZooKeeper and BookKeeper use
+`instances` | Artifacts created for [Pulsar Functions](functions-overview)
+`logs` | Logs that the installation creates
+
+
+## Deploy 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-the-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.
+
+The configuration store quorum can be provided by an independent cluster of machines or by the same machines used by local ZooKeeper.
+
+
+### Deploy local ZooKeeper
+
+ZooKeeper manages a variety of essential coordination-related and configuration-related tasks for Pulsar.
+
+You need to stand up one local ZooKeeper cluster *per Pulsar cluster* for deploying a Pulsar instance. 
+
+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 for 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 ID of the node in the `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).
+
+> See the [Multi-server setup guide](https://zookeeper.apache.org/doc/r3.4.10/zookeeperAdmin.html#sc_zkMulitServerSetup) in the ZooKeeper documentation for detailed information on `myid` and more.
+
+On a ZooKeeper server at `zk1.us-west.example.com`, for example, you could set the `myid` value like this:
+
+```shell
+
+$ mkdir -p data/zookeeper
+$ echo 1 > data/zookeeper/myid
+
+```
+
+On `zk2.us-west.example.com` the command looks like `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#pulsar-daemon) CLI tool:
+
+```shell
+
+$ bin/pulsar-daemon start zookeeper
+
+```
+
+### Deploy the configuration store 
+
+The ZooKeeper cluster that is 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 should 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](#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, assume a Pulsar instance with the following clusters `us-west`,
+`us-east`, `us-central`, `eu-central`, `ap-south`. Also assume, each cluster has its own local ZK servers named such as the following: 
+
+```
+
+zk[1-3].${CLUSTER}.example.com
+
+```
+
+In this scenario if you want to pick the quorum participants from 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 method guarantees that writes to configuration store is possible even if one of these regions is unreachable.
+
+The ZK configuration in all the servers looks like:
+
+```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 the following parameters:
+
+```properties
+
+peerType=observer
+
+```
+
+##### Start the service
+
+Once your configuration store configuration is in place, you can start up the service using [`pulsar-daemon`](reference-cli-tools.md#pulsar-daemon)
+
+```shell
+
+$ bin/pulsar-daemon start configuration-store
+
+```
+
+## Cluster metadata initialization
+
+Once you set up the cluster-specific ZooKeeper and configuration store quorums for your instance, you need to write some metadata to ZooKeeper for each cluster in your instance. **you only needs to write these metadata once**.
+
+You can initialize this metadata using the [`initialize-cluster-metadata`](reference-cli-tools.md#pulsar-initialize-cluster-metadata) command of the [`pulsar`](reference-cli-tools.md#pulsar) CLI tool. The following is an example:
+
+```shell
+
+$ bin/pulsar initialize-cluster-metadata \
+  --cluster us-west \
+  --zookeeper zk1.us-west.example.com:2181 \
+  --configuration-store zk1.us-west.example.com:2184 \
+  --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/
+
+```
+
+As you can see from the example above, you need to specify the following:
+
+* The name of the cluster
+* The local ZooKeeper 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
+
+If you use [TLS](security-tls-transport), you also need to specify a TLS web service URL for the cluster as well as a TLS broker service URL for the brokers in the cluster.
+
+Make sure to run `initialize-cluster-metadata` for each cluster in your instance.
+
+## Deploy BookKeeper
+
+BookKeeper provides [persistent message storage](concepts-architecture-overview.md#persistent-storage) for Pulsar.
+
+Each Pulsar broker needs to have its own cluster of bookies. The BookKeeper cluster shares a local ZooKeeper quorum with the Pulsar cluster.
+
+### Configure bookies
+
+You can configure BookKeeper bookies using the [`conf/bookkeeper.conf`](reference-configuration.md#bookkeeper) configuration file. The most important aspect of configuring each bookie is ensuring that the [`zkServers`](reference-configuration.md#bookkeeper-zkServers) parameter is set to the connection string for the local ZooKeeper of Pulsar cluster.
+
+### Start bookies
+
+You can start a bookie in two ways: in the foreground or as a background daemon.
+
+To start a bookie in the background, use the [`pulsar-daemon`](reference-cli-tools.md#pulsar-daemon) CLI tool:
+
+```bash
+
+$ bin/pulsar-daemon start bookie
+
+```
+
+You can verify that the bookie works properly using the `bookiesanity` command for the [BookKeeper shell](reference-cli-tools.md#bookkeeper-shell):
+
+```shell
+
+$ bin/bookkeeper shell bookiesanity
+
+```
+
+This command creates a new ledger on the local bookie, writes a few entries, reads them back and finally deletes the ledger.
+
+After you have started all bookies, you can use the `simpletest` command for [BookKeeper shell](reference-cli-tools.md#shell) on any bookie node, to verify that all bookies in the cluster are running.
+
+```bash
+
+$ bin/bookkeeper shell simpletest --ensemble <num-bookies> --writeQuorum <num-bookies> --ackQuorum <num-bookies> --numEntries <num-entries>
+
+```
+
+Bookie hosts are responsible for storing message data on disk. In order for bookies to provide optimal performance, having a suitable hardware configuration is essential for the bookies. The following are key dimensions for bookie hardware capacity.
+
+* Disk I/O capacity read/write
+* Storage capacity
+
+Message entries written to bookies are always synced to disk before returning an acknowledgement to the Pulsar broker. To ensure low write latency, BookKeeper is
+designed to use multiple devices:
+
+* A **journal** to ensure durability. For sequential writes, having fast [fsync](https://linux.die.net/man/2/fsync) operations on bookie hosts is critical. Typically, small and fast [solid-state drives](https://en.wikipedia.org/wiki/Solid-state_drive) (SSDs) should suffice, or [hard disk drives](https://en.wikipedia.org/wiki/Hard_disk_drive) (HDDs) with a [RAID](https://en.wikipedia.org/wiki/RAID)s controller and a battery-backed write cache. Both solutions can reach fsync latency of ~0.4 ms.
+* A **ledger storage device** is where data is stored until all consumers acknowledge the message. Writes happen in the background, so write I/O is not a big concern. Reads happen sequentially most of the time and the backlog is drained only in case of consumer drain. To store large amounts of data, a typical configuration involves multiple HDDs with a RAID controller.
+
+
+
+## Deploy brokers
+
+Once you set up ZooKeeper, initialize cluster metadata, and spin up BookKeeper bookies, you can deploy brokers.
+
+### Broker configuration
+
+You can configure brokers using the [`conf/broker.conf`](reference-configuration.md#broker) configuration file.
+
+The most important element of broker configuration is ensuring that each broker is aware of its local ZooKeeper quorum as well as the configuration store quorum. Make sure that you set the [`zookeeperServers`](reference-configuration.md#broker-zookeeperServers) parameter to reflect the local quorum and the [`configurationStoreServers`](reference-configuration.md#broker-configurationStoreServers) parameter to reflect the configuration store quorum (although you need to specify only those  [...]
+
+You also need to specify the name of the [cluster](reference-terminology.md#cluster) to which the broker belongs using the [`clusterName`](reference-configuration.md#broker-clusterName) parameter. In addition, you need to match the broker and web service ports provided when you initialize the metadata (especially when you use a different port from default) of the cluster.
+
+The following is an example configuration:
+
+```properties
+
+# Local ZooKeeper servers
+zookeeperServers=zk1.us-west.example.com:2181,zk2.us-west.example.com:2181,zk3.us-west.example.com:2181
+
+# Configuration store quorum connection string.
+configurationStoreServers=zk1.us-west.example.com:2184,zk2.us-west.example.com:2184,zk3.us-west.example.com:2184
+
+clusterName=us-west
+
+# Broker data port
+brokerServicePort=6650
+
+# Broker data port for TLS
+brokerServicePortTls=6651
+
+# Port to use to server HTTP request
+webServicePort=8080
+
+# Port to use to server HTTPS request
+webServicePortTls=8443
+
+```
+
+### Broker hardware
+
+Pulsar brokers do not require any special hardware since they do not use the local disk. You had better choose fast CPUs and 10Gbps [NIC](https://en.wikipedia.org/wiki/Network_interface_controller) so that the software can take full advantage of that.
+
+### Start the broker service
+
+You can start a broker in the background by using [nohup](https://en.wikipedia.org/wiki/Nohup) with the [`pulsar-daemon`](reference-cli-tools.md#pulsar-daemon) CLI tool:
+
+```shell
+
+$ bin/pulsar-daemon start broker
+
+```
+
+You can also start brokers in the foreground by using [`pulsar broker`](reference-cli-tools.md#broker):
+
+```shell
+
+$ bin/pulsar broker
+
+```
+
+## Service discovery
+
+[Clients](getting-started-clients) connecting to Pulsar brokers need to be able to communicate with an entire Pulsar instance using a single URL. Pulsar provides a built-in service discovery mechanism that you can set up using the instructions [immediately below](#service-discovery-setup).
+
+You can also use your own service discovery system if you want. If you use your own system, you only need to satisfy just one requirement: when a client performs an HTTP request to an [endpoint](reference-configuration) for a Pulsar cluster, such as `http://pulsar.us-west.example.com:8080`, the client needs to be redirected to *some* active broker in the desired cluster, whether via DNS, an HTTP or IP redirect, or some other means.
+
+> #### Service discovery already provided by many scheduling systems
+> Many large-scale deployment systems, such as [Kubernetes](deploy-kubernetes), have service discovery systems built in. If you run Pulsar on such a system, you may not need to provide your own service discovery mechanism.
+
+
+### Service discovery setup
+
+The service discovery mechanism that included with Pulsar maintains a list of active brokers, which stored in ZooKeeper, and supports lookup using HTTP and also the [binary protocol](developing-binary-protocol) of Pulsar.
+
+To get started setting up the built-in service of discovery of Pulsar, you need to change a few parameters in the [`conf/discovery.conf`](reference-configuration.md#service-discovery) configuration file. Set the [`zookeeperServers`](reference-configuration.md#service-discovery-zookeeperServers) parameter to the ZooKeeper quorum connection string of the cluster and the [`configurationStoreServers`](reference-configuration.md#service-discovery-configurationStoreServers) setting to the [con [...]
+store](reference-terminology.md#configuration-store) quorum connection string.
+
+```properties
+
+# Zookeeper quorum connection string
+zookeeperServers=zk1.us-west.example.com:2181,zk2.us-west.example.com:2181,zk3.us-west.example.com:2181
+
+# Global configuration store connection string
+configurationStoreServers=zk1.us-west.example.com:2184,zk2.us-west.example.com:2184,zk3.us-west.example.com:2184
+
+```
+
+To start the discovery service:
+
+```shell
+
+$ bin/pulsar-daemon start discovery
+
+```
+
+## Admin client and verification
+
+At this point your Pulsar instance should be ready to use. You can now configure client machines that can serve as [administrative clients](admin-api-overview) for each cluster. You can use the [`conf/client.conf`](reference-configuration.md#client) configuration file to configure admin clients.
+
+The most important thing is that you point the [`serviceUrl`](reference-configuration.md#client-serviceUrl) parameter to the correct service URL for the cluster:
+
+```properties
+
+serviceUrl=http://pulsar.us-west.example.com:8080/
+
+```
+
+## Provision new tenants
+
+Pulsar is built as a fundamentally multi-tenant system.
+
+
+If a new tenant wants to use the system, you need to create a new one. You can create a new tenant by using the [`pulsar-admin`](reference-pulsar-admin.md#tenants) CLI tool:
+
+```shell
+
+$ bin/pulsar-admin tenants create test-tenant \
+  --allowed-clusters us-west \
+  --admin-roles test-admin-role
+
+```
+
+In this command, users who identify with `test-admin-role` role can administer the configuration for the `test-tenant` tenant. The `test-tenant` tenant can only use the `us-west` cluster. From now on, this tenant can manage its resources.
+
+Once you create a tenant, you need to create [namespaces](reference-terminology.md#namespace) for topics within that tenant.
+
+
+The first step is to create a namespace. A namespace is an administrative unit that can contain many topics. A common practice is to create a namespace for each different use case from a single tenant.
+
+```shell
+
+$ bin/pulsar-admin namespaces create test-tenant/ns1
+
+```
+
+##### Test producer and consumer
+
+
+Everything is now ready to send and receive messages. The quickest way to test the system is through the [`pulsar-perf`](reference-cli-tools.md#pulsar-perf) client tool.
+
+
+You can use a topic in the namespace that you have just created. Topics are automatically created the first time when a producer or a consumer tries to use them.
+
+The topic name in this case could be:
+
+```http
+
+persistent://test-tenant/ns1/my-topic
+
+```
+
+Start a consumer that creates a subscription on the topic and waits for messages:
+
+```shell
+
+$ bin/pulsar-perf consume persistent://test-tenant/ns1/my-topic
+
+```
+
+Start a producer that publishes messages at a fixed rate and reports stats every 10 seconds:
+
+```shell
+
+$ bin/pulsar-perf produce persistent://test-tenant/ns1/my-topic
+
+```
+
+To report the topic stats:
+
+```shell
+
+$ bin/pulsar-admin topics stats persistent://test-tenant/ns1/my-topic
+
+```
+
diff --git a/site2/website-next/versioned_docs/version-2.6.0/deploy-bare-metal.md b/site2/website-next/versioned_docs/version-2.6.0/deploy-bare-metal.md
new file mode 100644
index 0000000..54dcdf7
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.6.0/deploy-bare-metal.md
@@ -0,0 +1,527 @@
+---
+id: deploy-bare-metal
+title: Deploy a cluster on bare metal
+sidebar_label: "Bare metal"
+original_id: deploy-bare-metal
+---
+
+:::tip
+
+1. Single-cluster Pulsar installations should be sufficient for all but the most ambitious use cases. If you are interested in experimenting with
+Pulsar or using Pulsar in a startup or on a single team, it is simplest to opt for a single cluster. If you do need to run a multi-cluster Pulsar instance,
+see the guide [here](deploy-bare-metal-multi-cluster).
+2. If you want to use all builtin [Pulsar IO](io-overview) connectors in your Pulsar deployment, you need to download `apache-pulsar-io-connectors`
+package and install `apache-pulsar-io-connectors` under `connectors` directory in the pulsar directory on every broker node or on every function-worker node if you
+have run a separate cluster of function workers for [Pulsar Functions](functions-overview).
+3. If you want to use [Tiered Storage](concepts-tiered-storage) feature in your Pulsar deployment, you need to download `apache-pulsar-offloaders`
+package and install `apache-pulsar-offloaders` under `offloaders` directory in the pulsar directory on every broker node. For more details of how to configure
+this feature, you can refer to the [Tiered storage cookbook](cookbooks-tiered-storage).
+
+:::
+
+Deploying a Pulsar cluster involves doing the following (in order):
+
+* Deploy a [ZooKeeper](#deploy-a-zookeeper-cluster) cluster (optional)
+* Initialize [cluster metadata](#initialize-cluster-metadata)
+* Deploy a [BookKeeper](#deploy-a-bookkeeper-cluster) cluster
+* Deploy one or more Pulsar [brokers](#deploy-pulsar-brokers)
+
+## Preparation
+
+### Requirements
+
+Currently, Pulsar is available for 64-bit **macOS**, **Linux**, and **Windows**. To use Pulsar, you need to install 64-bit JRE/JDK 8 or later versions.
+
+> If you already have an existing ZooKeeper cluster and want to reuse it, you do not need to prepare the machines
+> for running ZooKeeper.
+
+To run Pulsar on bare metal, the following configuration is recommended:
+
+* At least 6 Linux machines or VMs
+  * 3 for running [ZooKeeper](https://zookeeper.apache.org)
+  * 3 for running a Pulsar broker, and a [BookKeeper](https://bookkeeper.apache.org) bookie
+* A single [DNS](https://en.wikipedia.org/wiki/Domain_Name_System) name covering all of the Pulsar broker hosts
+
+> If you do not have enough machines, or to try out Pulsar in cluster mode (and expand the cluster later),
+> you can deploy a full Pulsar configuration on one node, where Zookeeper, the bookie and broker are run on the same machine.
+
+> If you do not have a DNS server, you can use the multi-host format in the service URL instead.
+
+Each machine in your cluster needs to have [Java 8](http://www.oracle.com/technetwork/java/javase/downloads/index.html) or a more recent  version of Java installed.
+
+The following is a diagram showing the basic setup:
+
+![alt-text](/assets/pulsar-basic-setup.png)
+
+In this diagram, connecting clients need to be able to communicate with the Pulsar cluster using a single URL. In this case, `pulsar-cluster.acme.com` abstracts over all of the message-handling brokers. Pulsar message brokers run on machines alongside BookKeeper bookies; brokers and bookies, in turn, rely on ZooKeeper.
+
+### Hardware considerations
+
+When you deploy a Pulsar cluster, keep in mind the following basic better choices when you do the capacity planning.
+
+#### ZooKeeper
+
+For machines running ZooKeeper, is is recommended to use less powerful machines or VMs. Pulsar uses ZooKeeper only for periodic coordination-related and configuration-related tasks, *not* for basic operations. If you run Pulsar on [Amazon Web Services](https://aws.amazon.com/) (AWS), for example, a [t2.small](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/t2-instances.html) instance might likely suffice.
+
+#### Bookies and Brokers
+
+For machines running a bookie and a Pulsar broker, more powerful machines are required. For an AWS deployment, for example, [i3.4xlarge](https://aws.amazon.com/blogs/aws/now-available-i3-instances-for-demanding-io-intensive-applications/) instances may be appropriate. On those machines you can use the following:
+
+* Fast CPUs and 10Gbps [NIC](https://en.wikipedia.org/wiki/Network_interface_controller) (for Pulsar brokers)
+* Small and fast [solid-state drives](https://en.wikipedia.org/wiki/Solid-state_drive) (SSDs) or [hard disk drives](https://en.wikipedia.org/wiki/Hard_disk_drive) (HDDs) with a [RAID](https://en.wikipedia.org/wiki/RAID) controller and a battery-backed write cache (for BookKeeper bookies)
+
+## Install the Pulsar binary package
+
+> You need to install the Pulsar binary package on *each machine in the cluster*, including machines running [ZooKeeper](#deploy-a-zookeeper-cluster) and [BookKeeper](#deploy-a-bookkeeper-cluster).
+
+To get started deploying a Pulsar cluster on bare metal, you need to download a binary tarball release in one of the following ways:
+
+* By clicking on the link below directly, which automatically triggers a download:
+  * <a href="pulsar:binary_release_url" download>Pulsar @pulsar:version@ binary release</a>
+* From the Pulsar [downloads page](pulsar:download_page_url)
+* From the Pulsar [releases page](https://github.com/apache/pulsar/releases/latest) on [GitHub](https://github.com)
+* Using [wget](https://www.gnu.org/software/wget):
+
+```bash
+
+$ wget pulsar:binary_release_url
+
+```
+
+Once you download the tarball, untar it and `cd` into the resulting directory:
+
+```bash
+
+$ tar xvzf apache-pulsar-@pulsar:version@-bin.tar.gz
+$ cd apache-pulsar-@pulsar:version@
+
+```
+
+The extracted directory contains the following subdirectories:
+
+Directory | Contains
+:---------|:--------
+`bin` |[command-line tools](reference-cli-tools) of Pulsar, such as [`pulsar`](reference-cli-tools.md#pulsar) and [`pulsar-admin`](https://pulsar.apache.org/tools/pulsar-admin/)
+`conf` | Configuration files for Pulsar, including for [broker configuration](reference-configuration.md#broker), [ZooKeeper configuration](reference-configuration.md#zookeeper), and more
+`data` | The data storage directory that ZooKeeper and BookKeeper use
+`lib` | The [JAR](https://en.wikipedia.org/wiki/JAR_(file_format)) files that Pulsar uses
+`logs` | Logs that the installation creates
+
+## [Install Builtin Connectors (optional)]( https://pulsar.apache.org/docs/en/next/standalone/#install-builtin-connectors-optional)
+
+> Since Pulsar release `2.1.0-incubating`, Pulsar provides a separate binary distribution, containing all the `builtin` connectors.
+> If you want to enable those `builtin` connectors, you can follow the instructions as below; otherwise you can
+> skip this section for now.
+
+To get started using builtin connectors, you need to download the connectors tarball release on every broker node in one of the following ways:
+
+* by clicking the link below and downloading the release from an Apache mirror:
+
+  * <a href="pulsar:connector_release_url" download>Pulsar IO Connectors @pulsar:version@ release</a>
+
+* from the Pulsar [downloads page](pulsar:download_page_url)
+* from the Pulsar [releases page](https://github.com/apache/pulsar/releases/latest)
+* using [wget](https://www.gnu.org/software/wget):
+
+  ```shell
+  
+  $ wget pulsar:connector_release_url/{connector}-@pulsar:version@.nar
+  
+  ```
+
+Once you download the .nar file, copy the file to directory `connectors` in the pulsar directory. 
+For example, if you download the connector file `pulsar-io-aerospike-@pulsar:version@.nar`:
+
+```bash
+
+$ mkdir connectors
+$ mv pulsar-io-aerospike-@pulsar:version@.nar connectors
+
+$ ls connectors
+pulsar-io-aerospike-@pulsar:version@.nar
+...
+
+```
+
+## [Install Tiered Storage Offloaders (optional)](https://pulsar.apache.org/docs/en/next/standalone/#install-tiered-storage-offloaders-optional)
+
+> Since Pulsar release `2.2.0`, Pulsar releases a separate binary distribution, containing the tiered storage offloaders.
+> If you want to enable tiered storage feature, you can follow the instructions as below; otherwise you can
+> skip this section for now.
+
+To get started using tiered storage offloaders, you need to download the offloaders tarball release on every broker node in one of the following ways:
+
+* by clicking the link below and downloading the release from an Apache mirror:
+
+  * <a href="pulsar:offloader_release_url" download>Pulsar Tiered Storage Offloaders @pulsar:version@ release</a>
+
+* from the Pulsar [downloads page](pulsar:download_page_url)
+* from the Pulsar [releases page](https://github.com/apache/pulsar/releases/latest)
+* using [wget](https://www.gnu.org/software/wget):
+
+  ```shell
+  
+  $ wget pulsar:offloader_release_url
+  
+  ```
+
+Once you download the tarball, in the pulsar directory, untar the offloaders package and copy the offloaders as `offloaders` in the pulsar directory:
+
+```bash
+
+$ tar xvfz apache-pulsar-offloaders-@pulsar:version@-bin.tar.gz
+
+// you can find a directory named `apache-pulsar-offloaders-@pulsar:version@` in the pulsar directory
+// then copy the offloaders
+
+$ mv apache-pulsar-offloaders-@pulsar:version@/offloaders offloaders
+
+$ ls offloaders
+tiered-storage-jcloud-@pulsar:version@.nar
+
+```
+
+For more details of how to configure tiered storage feature, you can refer to the [Tiered storage cookbook](cookbooks-tiered-storage)
+
+
+## Deploy a ZooKeeper cluster
+
+> If you already have an existing zookeeper cluster and want to use it, you can skip this section.
+
+[ZooKeeper](https://zookeeper.apache.org) manages a variety of essential coordination- and configuration-related tasks for Pulsar. To deploy a Pulsar cluster, you need to deploy ZooKeeper first (before all other components). A 3-node ZooKeeper cluster is the recommended configuration. Pulsar does not make heavy use of ZooKeeper, so more lightweight machines or VMs should suffice for running ZooKeeper.
+
+To begin, add all ZooKeeper servers to the configuration specified in [`conf/zookeeper.conf`](reference-configuration.md#zookeeper) (in the Pulsar directory that you create [above](#install-the-pulsar-binary-package)). The following is an example:
+
+```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
+
+```
+
+> If you only have one machine on which to deploy Pulsar, you only need to add one server entry in the configuration file.
+
+On each host, you need to specify the ID of the node in the `myid` file, which is in the `data/zookeeper` folder of each server by default (you can change the file location via the [`dataDir`](reference-configuration.md#zookeeper-dataDir) parameter).
+
+> See the [Multi-server setup guide](https://zookeeper.apache.org/doc/r3.4.10/zookeeperAdmin.html#sc_zkMulitServerSetup) in the ZooKeeper documentation for detailed information on `myid` and more.
+
+For example, on a ZooKeeper server like `zk1.us-west.example.com`, you can set the `myid` value as follows:
+
+```bash
+
+$ 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 have the appropriate `myid` entry, you can start ZooKeeper on all hosts (in the background, using nohup) with the [`pulsar-daemon`](reference-cli-tools.md#pulsar-daemon) CLI tool:
+
+```bash
+
+$ bin/pulsar-daemon start zookeeper
+
+```
+
+> If you plan to deploy Zookeeper with the Bookie on the same node, you
+> need to start zookeeper by using different stats port.
+
+Start zookeeper with [`pulsar-daemon`](reference-cli-tools.md#pulsar-daemon) CLI tool like:
+
+```bash
+
+$ PULSAR_EXTRA_OPTS="-Dstats_server_port=8001" bin/pulsar-daemon start zookeeper
+
+```
+
+## Initialize cluster metadata
+
+Once you deploy ZooKeeper for your cluster, you need to write some metadata to ZooKeeper for each cluster in your instance. You only need to write this data **once**.
+
+You can initialize this metadata using the [`initialize-cluster-metadata`](reference-cli-tools.md#pulsar-initialize-cluster-metadata) command of the [`pulsar`](reference-cli-tools.md#pulsar) CLI tool. This command can be run on any machine in your ZooKeeper cluster. The following is an example:
+
+```shell
+
+$ bin/pulsar initialize-cluster-metadata \
+  --cluster pulsar-cluster-1 \
+  --zookeeper zk1.us-west.example.com:2181 \
+  --configuration-store zk1.us-west.example.com:2181 \
+  --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
+
+```
+
+As you can see from the example above, you will need to specify the following:
+
+Flag | Description
+:----|:-----------
+`--cluster` | A name for the cluster
+`--zookeeper` | A "local" ZooKeeper connection string for the cluster. This connection string only needs to include *one* machine in the ZooKeeper cluster.
+`--configuration-store` | The configuration store connection string for the entire instance. As with the `--zookeeper` flag, this connection string only needs to include *one* machine in the ZooKeeper cluster.
+`--web-service-url` | The web service URL for the cluster, plus a port. This URL should be a standard DNS name. The default port is 8080 (you had better not use a different port).
+`--web-service-url-tls` | If you use [TLS](security-tls-transport), you also need to specify a TLS web service URL for the cluster. The default port is 8443 (you had better not use a different port).
+`--broker-service-url` | A broker service URL enabling interaction with the brokers in the cluster. This URL should not use the same DNS name as the web service URL but should use the `pulsar` scheme instead. The default port is 6650 (you had better not use a different port).
+`--broker-service-url-tls` | If you use [TLS](security-tls-transport), you also need to specify a TLS web service URL for the cluster as well as a TLS broker service URL for the brokers in the cluster. The default port is 6651 (you had better not use a different port).
+
+
+> If you do not have a DNS server, you can use multi-host format in the service URL with the following settings:
+>
+
+> ```properties
+> 
+> --web-service-url http://host1:8080,host2:8080,host3:8080 \
+> --web-service-url-tls https://host1:8443,host2:8443,host3:8443 \
+> --broker-service-url pulsar://host1:6650,host2:6650,host3:6650 \
+> --broker-service-url-tls pulsar+ssl://host1:6651,host2:6651,host3:6651
+>
+> 
+> ```
+
+
+## Deploy a BookKeeper cluster
+
+[BookKeeper](https://bookkeeper.apache.org) handles all persistent data storage in Pulsar. You need to deploy a cluster of BookKeeper bookies to use Pulsar. You can choose to run a **3-bookie BookKeeper cluster**.
+
+You can configure BookKeeper bookies using the [`conf/bookkeeper.conf`](reference-configuration.md#bookkeeper) configuration file. The most important step in configuring bookies for our purposes here is ensuring that [`zkServers`](reference-configuration.md#bookkeeper-zkServers) is set to the connection string for the ZooKeeper cluster. The following is an example:
+
+```properties
+
+zkServers=zk1.us-west.example.com:2181,zk2.us-west.example.com:2181,zk3.us-west.example.com:2181
+
+```
+
+Once you appropriately modify the `zkServers` parameter, you can make any other configuration changes that you require. You can find a full listing of the available BookKeeper configuration parameters [here](reference-configuration.md#bookkeeper). However, consulting the [BookKeeper documentation](http://bookkeeper.apache.org/docs/latest/reference/config/) for a more in-depth guide might be a better choice.
+
+Once you apply the desired configuration in `conf/bookkeeper.conf`, you can start up a bookie on each of your BookKeeper hosts. You can start up each bookie either in the background, using [nohup](https://en.wikipedia.org/wiki/Nohup), or in the foreground.
+
+To start the bookie in the background, use the [`pulsar-daemon`](reference-cli-tools.md#pulsar-daemon) CLI tool:
+
+```bash
+
+$ bin/pulsar-daemon start bookie
+
+```
+
+To start the bookie in the foreground:
+
+```bash
+
+$ bin/bookkeeper bookie
+
+```
+
+You can verify that a bookie works properly by running the `bookiesanity` command on the [BookKeeper shell](reference-cli-tools.md#shell):
+
+```bash
+
+$ bin/bookkeeper shell bookiesanity
+
+```
+
+This command creates an ephemeral BookKeeper ledger on the local bookie, writes a few entries, reads them back, and finally deletes the ledger.
+
+After you start all the bookies, you can use `simpletest` command for [BookKeeper shell](reference-cli-tools.md#shell) on any bookie node, to verify all the bookies in the cluster are up running.
+
+```bash
+
+$ bin/bookkeeper shell simpletest --ensemble <num-bookies> --writeQuorum <num-bookies> --ackQuorum <num-bookies> --numEntries <num-entries>
+
+```
+
+This command creates a `num-bookies` sized ledger on the cluster, writes a few entries, and finally deletes the ledger.
+
+
+## Deploy Pulsar brokers
+
+Pulsar brokers are the last thing you need to deploy in your Pulsar cluster. Brokers handle Pulsar messages and provide the administrative interface of Pulsar. A good choice is to run **3 brokers**, one for each machine that already runs a BookKeeper bookie.
+
+### Configure Brokers
+
+The most important element of broker configuration is ensuring that each broker is aware of the ZooKeeper cluster that you have deployed. Ensure that the [`zookeeperServers`](reference-configuration.md#broker-zookeeperServers) and [`configurationStoreServers`](reference-configuration.md#broker-configurationStoreServers) parameters are correct. In this case, since you only have 1 cluster and no configuration store setup, the `configurationStoreServers` point to the same `zookeeperServers`.
+
+```properties
+
+zookeeperServers=zk1.us-west.example.com:2181,zk2.us-west.example.com:2181,zk3.us-west.example.com:2181
+configurationStoreServers=zk1.us-west.example.com:2181,zk2.us-west.example.com:2181,zk3.us-west.example.com:2181
+
+```
+
+You also need to specify the cluster name (matching the name that you provided when you [initialize the metadata of the cluster](#initialize-cluster-metadata)):
+
+```properties
+
+clusterName=pulsar-cluster-1
+
+```
+
+In addition, you need to match the broker and web service ports provided when you initialize the metadata of the cluster (especially when you use a different port than the default):
+
+```properties
+
+brokerServicePort=6650
+brokerServicePortTls=6651
+webServicePort=8080
+webServicePortTls=8443
+
+```
+
+> If you deploy Pulsar in a one-node cluster, you should update the replication settings in `conf/broker.conf` to `1`.
+>
+
+> ```properties
+> 
+> # Number of bookies to use when creating a ledger
+> managedLedgerDefaultEnsembleSize=1
+>
+> # Number of copies to store for each message
+> managedLedgerDefaultWriteQuorum=1
+> 
+> # Number of guaranteed copies (acks to wait before write is complete)
+> managedLedgerDefaultAckQuorum=1
+>
+> 
+> ```
+
+
+### Enable Pulsar Functions (optional)
+
+If you want to enable [Pulsar Functions](functions-overview), you can follow the instructions as below:
+
+1. Edit `conf/broker.conf` to enable functions worker, by setting `functionsWorkerEnabled` to `true`.
+
+   ```conf
+   
+   functionsWorkerEnabled=true
+   
+   ```
+
+2. Edit `conf/functions_worker.yml` and set `pulsarFunctionsCluster` to the cluster name that you provide when you [initialize the metadata of the cluster](#initialize-cluster-metadata). 
+
+   ```conf
+   
+   pulsarFunctionsCluster: pulsar-cluster-1
+   
+   ```
+
+If you want to learn more options about deploying the functions worker, check out [Deploy and manage functions worker](functions-worker).
+
+### Start Brokers
+
+You can then provide any other configuration changes that you want in the [`conf/broker.conf`](reference-configuration.md#broker) file. Once you decide on a configuration, you can start up the brokers for your Pulsar cluster. Like ZooKeeper and BookKeeper, you can start brokers either in the foreground or in the background, using nohup.
+
+You can start a broker in the foreground using the [`pulsar broker`](reference-cli-tools.md#pulsar-broker) command:
+
+```bash
+
+$ bin/pulsar broker
+
+```
+
+You can start a broker in the background using the [`pulsar-daemon`](reference-cli-tools.md#pulsar-daemon) CLI tool:
+
+```bash
+
+$ bin/pulsar-daemon start broker
+
+```
+
+Once you successfully start up all the brokers that you intend to use, your Pulsar cluster should be ready to go!
+
+## Connect to the running cluster
+
+Once your Pulsar cluster is up and running, you should be able to connect with it using Pulsar clients. One such client is the [`pulsar-client`](reference-cli-tools.md#pulsar-client) tool, which is included with the Pulsar binary package. The `pulsar-client` tool can publish messages to and consume messages from Pulsar topics and thus provide a simple way to make sure that your cluster runs properly.
+
+To use the `pulsar-client` tool, first modify the client configuration file in [`conf/client.conf`](reference-configuration.md#client) in your binary package. You need to change the values for `webServiceUrl` and `brokerServiceUrl`, substituting `localhost` (which is the default), with the DNS name that you assign to your broker/bookie hosts. The following is an example:
+
+```properties
+
+webServiceUrl=http://us-west.example.com:8080
+brokerServiceurl=pulsar://us-west.example.com:6650
+
+```
+
+> If you do not have a DNS server, you can specify multi-host in service URL as follows:
+>
+
+> ```properties
+> 
+> webServiceUrl=http://host1:8080,host2:8080,host3:8080
+> brokerServiceurl=pulsar://host1:6650,host2:6650,host3:6650
+>
+> 
+> ```
+
+
+Once that is complete, you can publish a message to the Pulsar topic:
+
+```bash
+
+$ bin/pulsar-client produce \
+  persistent://public/default/test \
+  -n 1 \
+  -m "Hello Pulsar"
+
+```
+
+> You may need to use a different cluster name in the topic if you specify a cluster name other than `pulsar-cluster-1`.
+
+This command publishes a single message to the Pulsar topic. In addition, you can subscribe to the Pulsar topic in a different terminal before publishing messages as below:
+
+```bash
+
+$ bin/pulsar-client consume \
+  persistent://public/default/test \
+  -n 100 \
+  -s "consumer-test" \
+  -t "Exclusive"
+
+```
+
+Once you successfully publish the above message to the topic, you should see it in the standard output:
+
+```bash
+
+----- got message -----
+Hello Pulsar
+
+```
+
+## Run Functions
+
+> If you have [enabled](#enable-pulsar-functions-optional) Pulsar Functions, you can try out the Pulsar Functions now.
+
+Create an ExclamationFunction `exclamation`.
+
+```bash
+
+bin/pulsar-admin functions create \
+  --jar examples/api-examples.jar \
+  --classname org.apache.pulsar.functions.api.examples.ExclamationFunction \
+  --inputs persistent://public/default/exclamation-input \
+  --output persistent://public/default/exclamation-output \
+  --tenant public \
+  --namespace default \
+  --name exclamation
+
+```
+
+Check whether the function runs as expected by [triggering](functions-deploying.md#triggering-pulsar-functions) the function.
+
+```bash
+
+bin/pulsar-admin functions trigger --name exclamation --trigger-value "hello world"
+
+```
+
+You should see the following output:
+
+```shell
+
+hello world!
+
+```
+
diff --git a/site2/website-next/versioned_docs/version-2.6.0/deploy-dcos.md b/site2/website-next/versioned_docs/version-2.6.0/deploy-dcos.md
new file mode 100644
index 0000000..f5f8d1f
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.6.0/deploy-dcos.md
@@ -0,0 +1,200 @@
+---
+id: deploy-dcos
+title: Deploy Pulsar on DC/OS
+sidebar_label: "DC/OS"
+original_id: deploy-dcos
+---
+
+:::tip
+
+If you want to enable all builtin [Pulsar IO](io-overview) connectors in your Pulsar deployment, you can choose to use `apachepulsar/pulsar-all` image instead of
+`apachepulsar/pulsar` image. `apachepulsar/pulsar-all` image has already bundled [all builtin connectors](io-overview.md#working-with-connectors).
+
+:::
+
+[DC/OS](https://dcos.io/) (the <strong>D</strong>ata<strong>C</strong>enter <strong>O</strong>perating <strong>S</strong>ystem) is a distributed operating system used for deploying and managing applications and systems on [Apache Mesos](http://mesos.apache.org/). DC/OS is an open-source tool that [Mesosphere](https://mesosphere.com/) creates and maintains .
+
+Apache Pulsar is available as a [Marathon Application Group](https://mesosphere.github.io/marathon/docs/application-groups.html), which runs multiple applications as manageable sets.
+
+## Prerequisites
+
+In order to run Pulsar on DC/OS, you need the following:
+
+* DC/OS version [1.9](https://docs.mesosphere.com/1.9/) or higher
+* A [DC/OS cluster](https://docs.mesosphere.com/1.9/installing/) with at least three agent nodes
+* The [DC/OS CLI tool](https://docs.mesosphere.com/1.9/cli/install/) installed
+* The [`PulsarGroups.json`](https://github.com/apache/pulsar/blob/master/deployment/dcos/PulsarGroups.json) configuration file from the Pulsar GitHub repo.
+
+  ```bash
+  
+  $ curl -O https://raw.githubusercontent.com/apache/pulsar/master/deployment/dcos/PulsarGroups.json
+  
+  ```
+
+Each node in the DC/OS-managed Mesos cluster must have at least:
+
+* 4 CPU
+* 4 GB of memory
+* 60 GB of total persistent disk
+
+Alternatively, you can change the configuration in `PulsarGroups.json` according to match your resources of DC/OS cluster.
+
+## Deploy Pulsar using the DC/OS command interface
+
+You can deploy Pulsar on DC/OS using this command:
+
+```bash
+
+$ dcos marathon group add PulsarGroups.json
+
+```
+
+This command deploys Docker container instances in three groups, which together comprise a Pulsar cluster:
+
+* 3 bookies (1 [bookie](reference-terminology.md#bookie) on each agent node and 1 [bookie recovery](http://bookkeeper.apache.org/docs/latest/admin/autorecovery/) instance)
+* 3 Pulsar [brokers](reference-terminology.md#broker) (1 broker on each node and 1 admin instance)
+* 1 [Prometheus](http://prometheus.io/) instance and 1 [Grafana](https://grafana.com/) instance
+
+
+> When you run DC/OS, a ZooKeeper cluster already runs at `master.mesos:2181`, thus you do not have to install or start up ZooKeeper separately.
+
+After executing the `dcos` command above, click on the **Services** tab in the DC/OS [GUI interface](https://docs.mesosphere.com/latest/gui/), which you can access at [http://m1.dcos](http://m1.dcos) in this example. You should see several applications in the process of deploying.
+
+![DC/OS command executed](/assets/dcos_command_execute.png)
+
+![DC/OS command executed2](/assets/dcos_command_execute2.png)
+
+## The BookKeeper group
+
+To monitor the status of the BookKeeper cluster deployment, click on the **bookkeeper** group in the parent **pulsar** group.
+
+![DC/OS bookkeeper status](/assets/dcos_bookkeeper_status.png)
+
+At this point, 3 [bookies](reference-terminology.md#bookie) should be shown as green, which means that the bookies have been deployed successfully and are now running.
+ 
+![DC/OS bookkeeper running](/assets/dcos_bookkeeper_run.png)
+ 
+You can also click into each bookie instance to get more detailed information, such as the bookie running log.
+
+![DC/OS bookie log](/assets/dcos_bookie_log.png)
+
+To display information about the BookKeeper in ZooKeeper, you can visit [http://m1.dcos/exhibitor](http://m1.dcos/exhibitor). In this example, 3 bookies are under the `available` directory.
+
+![DC/OS bookkeeper in zk](/assets/dcos_bookkeeper_in_zookeeper.png)
+
+## The Pulsar broker Group
+
+Similar to the BookKeeper group above, click into the **brokers** to check the status of the Pulsar brokers.
+
+![DC/OS broker status](/assets/dcos_broker_status.png)
+
+![DC/OS broker running](/assets/dcos_broker_run.png)
+
+You can also click into each broker instance to get more detailed information, such as the broker running log.
+
+![DC/OS broker log](/assets/dcos_broker_log.png)
+
+Broker cluster information in Zookeeper is also available through the web UI. In this example, you can see that the `loadbalance` and `managed-ledgers` directories have been created.
+
+![DC/OS broker in zk](/assets/dcos_broker_in_zookeeper.png)
+
+## Monitor Group
+
+The **monitory** group consists of Prometheus and Grafana.
+
+![DC/OS monitor status](/assets/dcos_monitor_status.png)
+
+### Prometheus
+
+Click into the instance of `prom` to get the endpoint of Prometheus, which is `192.168.65.121:9090` in this example.
+
+![DC/OS prom endpoint](/assets/dcos_prom_endpoint.png)
+
+If you click that endpoint, you can see the Prometheus dashboard. The [http://192.168.65.121:9090/targets](http://192.168.65.121:9090/targets) URL display all the bookies and brokers.
+
+![DC/OS prom targets](/assets/dcos_prom_targets.png)
+
+### Grafana
+
+Click into `grafana` to get the endpoint for Grafana, which is `192.168.65.121:3000` in this example.
+ 
+![DC/OS grafana endpoint](/assets/dcos_grafana_endpoint.png)
+
+If you click that endpoint, you can access the Grafana dashboard.
+
+![DC/OS grafana targets](/assets/dcos_grafana_dashboard.png)
+
+## Run a simple Pulsar consumer and producer on DC/OS
+
+Now that you have a fully deployed Pulsar cluster, you can run a simple consumer and producer to show Pulsar on DC/OS in action.
+
+### Download and prepare the Pulsar Java tutorial
+
+You can clone a [Pulsar Java tutorial](https://github.com/streamlio/pulsar-java-tutorial) repo. This repo contains a simple Pulsar consumer and producer (you can find more information in the `README` file of the repo).
+
+```bash
+
+$ git clone https://github.com/streamlio/pulsar-java-tutorial
+
+```
+
+Change the `SERVICE_URL` from `pulsar://localhost:6650` to `pulsar://a1.dcos:6650` in both [`ConsumerTutorial.java`](https://github.com/streamlio/pulsar-java-tutorial/blob/master/src/main/java/tutorial/ConsumerTutorial.java) and [`ProducerTutorial.java`](https://github.com/streamlio/pulsar-java-tutorial/blob/master/src/main/java/tutorial/ProducerTutorial.java).
+The `pulsar://a1.dcos:6650` endpoint is for the broker service. You can fetch the endpoint details for each broker instance from the DC/OS GUI. `a1.dcos` is a DC/OS client agent, which runs a broker. The client agent IP address can also replace this.
+
+Now, change the message number from 10 to 10000000 in main method of [`ProducerTutorial.java`](https://github.com/streamlio/pulsar-java-tutorial/blob/master/src/main/java/tutorial/ProducerTutorial.java) so that it can produce more messages.
+
+Now compile the project code using the command below:
+
+```bash
+
+$ mvn clean package
+
+```
+
+### Run the consumer and producer
+
+Execute this command to run the consumer:
+
+```bash
+
+$ mvn exec:java -Dexec.mainClass="tutorial.ConsumerTutorial"
+
+```
+
+Execute this command to run the producer:
+
+```bash
+
+$ mvn exec:java -Dexec.mainClass="tutorial.ProducerTutorial"
+
+```
+
+You can see the producer producing messages and the consumer consuming messages through the DC/OS GUI.
+
+![DC/OS pulsar producer](/assets/dcos_producer.png)
+
+![DC/OS pulsar consumer](/assets/dcos_consumer.png)
+
+### View Grafana metric output
+
+While the producer and consumer run, you can access running metrics information from Grafana.
+
+![DC/OS pulsar dashboard](/assets/dcos_metrics.png)
+
+
+## Uninstall Pulsar
+
+You can shut down and uninstall the `pulsar` application from DC/OS at any time in the following two ways:
+
+1. Using the DC/OS GUI, you can choose **Delete** at the right end of Pulsar group.
+
+   ![DC/OS pulsar uninstall](/assets/dcos_uninstall.png)
+
+2. You can use the following command:
+
+   ```bash
+   
+   $ dcos marathon group remove /pulsar
+   
+   ```
+
diff --git a/site2/website-next/versioned_docs/version-2.6.0/deploy-kubernetes.md b/site2/website-next/versioned_docs/version-2.6.0/deploy-kubernetes.md
new file mode 100644
index 0000000..dc7123d
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.6.0/deploy-kubernetes.md
@@ -0,0 +1,11 @@
+---
+id: deploy-kubernetes
+title: Deploy Pulsar on Kubernetes
+sidebar_label: "Kubernetes"
+original_id: deploy-kubernetes
+---
+
+To get up and running with these charts as fast as possible, in a **non-production** use case, we provide
+a [quick start guide](getting-started-helm) for Proof of Concept (PoC) deployments.
+
+To configure and install a Pulsar cluster on Kubernetes for production usage, follow the complete [Installation Guide](helm-install).
\ No newline at end of file
diff --git a/site2/website-next/versioned_docs/version-2.6.0/deploy-monitoring.md b/site2/website-next/versioned_docs/version-2.6.0/deploy-monitoring.md
new file mode 100644
index 0000000..bead6c1
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.6.0/deploy-monitoring.md
@@ -0,0 +1,103 @@
+---
+id: deploy-monitoring
+title: Monitoring
+sidebar_label: "Monitoring"
+original_id: deploy-monitoring
+---
+
+You can use different ways to monitor a Pulsar cluster, exposing both metrics that relate to the usage of topics and the overall health of the individual components of the cluster.
+
+## Collect metrics
+
+You can collect broker stats, ZooKeeper stats, and BookKeeper stats. 
+
+### Broker stats
+
+You can collect Pulsar broker metrics from brokers and export the metrics in JSON format. The Pulsar broker metrics mainly have two types:
+
+* *Destination dumps*, which contain stats for each individual topic. You can fetch the destination dumps using the command below:
+
+  ```shell
+  
+  bin/pulsar-admin broker-stats destinations
+  
+  ```
+
+* Broker metrics, which contain the broker information and topics stats aggregated at namespace level. You can fetch the broker metrics using the command below:
+
+  ```shell
+  
+  bin/pulsar-admin broker-stats monitoring-metrics
+  
+  ```
+
+All the message rates are updated every 1min.
+
+The aggregated broker metrics are also exposed in the [Prometheus](https://prometheus.io) format at:
+
+```shell
+
+http://$BROKER_ADDRESS:8080/metrics
+
+```
+
+### ZooKeeper stats
+
+The local Zookeeper and configuration store server and clients that are shipped with Pulsar have been instrumented to expose detailed stats through Prometheus as well.
+
+```shell
+
+http://$LOCAL_ZK_SERVER:8000/metrics
+http://$GLOBAL_ZK_SERVER:8001/metrics
+
+```
+
+The default port of local ZooKeeper is `8000` and the default port of configuration store is `8001`. You can change the default port of local Zookeeper and configuration store by specifying system property `stats_server_port`.
+
+### BookKeeper stats
+
+For BookKeeper you can configure the stats frameworks by changing the `statsProviderClass` in
+`conf/bookkeeper.conf`.
+
+The default BookKeeper configuration, which is included with Pulsar distribution, enables the Prometheus exporter.
+
+```shell
+
+http://$BOOKIE_ADDRESS:8000/metrics
+
+```
+
+The default port for bookie is `8000` (instead of `8080`). You can change the port by configuring `prometheusStatsHttpPort` in `conf/bookkeeper.conf`.
+
+## Configure Prometheus
+
+You can use Prometheus to collect and store the metrics data. For details, refer to [Prometheus guide](https://prometheus.io/docs/introduction/getting_started/).
+
+When you run Pulsar on bare metal, you can provide the list of nodes that needs to be probed. When you deploy Pulsar in a Kubernetes cluster, the monitoring is automatically setup with the [provided](deploy-kubernetes) instructions.
+
+## Dashboards
+
+When you collect time series statistics, the major problem is to make sure the number of dimensions attached to the data does not explode.
+
+For that reason you only need to collect time series of metrics aggregated at the namespace level.
+
+### Pulsar per-topic dashboard
+
+The per-topic dashboard instructions are available at [Dashboard](administration-dashboard).
+
+### Grafana
+
+You can use grafana to easily create dashboard driven by the data that is stored in Prometheus.
+
+When you deploy Pulsar on Kubernetes, a `pulsar-grafana` Docker image is enabled by default. You can use the docker image with the principal dashboards.
+
+Enter the command below to use the dashboard manually:
+
+```shell
+
+docker run -p3000:3000 \
+        -e PROMETHEUS_URL=http://$PROMETHEUS_HOST:9090/ \
+        apachepulsar/pulsar-grafana:latest
+
+```
+
diff --git a/site2/website-next/versioned_docs/version-2.6.0/helm-deploy.md b/site2/website-next/versioned_docs/version-2.6.0/helm-deploy.md
new file mode 100644
index 0000000..e393d53
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.6.0/helm-deploy.md
@@ -0,0 +1,434 @@
+---
+id: helm-deploy
+title: Deploy Pulsar cluster using Helm
+sidebar_label: "Deployment"
+original_id: helm-deploy
+---
+
+Before running `helm install`, you need to decide how to run Pulsar.
+Options can be specified using Helm's `--set option.name=value` command line option.
+
+## Select configuration options
+
+In each section, collect the options that are combined to use with the `helm install` command.
+
+### Kubernetes namespace
+
+By default, the Pulsar Helm chart is installed to a namespace called `pulsar`.
+
+```yaml
+
+namespace: pulsar
+
+```
+
+To install the Pulsar Helm chart into a different Kubernetes namespace, you can include this option in the `helm install` command.
+
+```bash
+
+--set namespace=<different-k8s-namespace>
+
+```
+
+By default, the Pulsar Helm chart doesn't create the namespace.
+
+```yaml
+
+namespaceCreate: false
+
+```
+
+To use the Pulsar Helm chart to create the Kubernetes namespace automatically, you can include this option in the `helm install` command.
+
+```bash
+
+--set namespaceCreate=true
+
+```
+
+### Persistence
+
+By default, the Pulsar Helm chart creates Volume Claims with the expectation that a dynamic provisioner creates the underlying Persistent Volumes.
+
+```yaml
+
+volumes:
+  persistence: true
+  # configure the components to use local persistent volume
+  # the local provisioner should be installed prior to enable local persistent volume
+  local_storage: false
+
+```
+
+To use local persistent volumes as the persistent storage for Helm release, you can install the [local storage provisioner](#install-local-storage-provisioner) and include the following option in the `helm install` command. 
+
+```bash
+
+--set volumes.local_storage=true
+
+```
+
+:::note
+
+Before installing the production instance of Pulsar, ensure to plan the storage settings to avoid extra storage migration work. Because after initial installation, you must edit Kubernetes objects manually if you want to change storage settings.
+
+:::
+
+The Pulsar Helm chart is designed for production use. To use the Pulsar Helm chart in a development environment (such as Minikube), you can disable persistence by including this option in your `helm install` command.
+
+```bash
+
+--set volumes.persistence=false
+
+```
+
+### Affinity 
+
+By default, `anti-affinity` is enabled to ensure pods of the same component can run on different nodes.
+
+```yaml
+
+affinity:
+  anti_affinity: true
+
+```
+
+To use the Pulsar Helm chart in a development environment (such as Minikue), you can disable `anti-affinity` by including this option in your `helm install` command.
+
+```bash
+
+--set affinity.anti_affinity=false
+
+```
+
+### Components
+
+The Pulsar Helm chart is designed for production usage. It deploys a production-ready Pulsar cluster, including Pulsar core components and monitoring components.
+
+You can customize the components to be deployed by turning on/off individual components.
+
+```yaml
+
+## Components
+##
+## Control what components of Apache Pulsar to deploy for the cluster
+components:
+  # zookeeper
+  zookeeper: true
+  # bookkeeper
+  bookkeeper: true
+  # bookkeeper - autorecovery
+  autorecovery: true
+  # broker
+  broker: true
+  # functions
+  functions: true
+  # proxy
+  proxy: true
+  # toolset
+  toolset: true
+  # pulsar manager
+  pulsar_manager: true
+
+## Monitoring Components
+##
+## Control what components of the monitoring stack to deploy for the cluster
+monitoring:
+  # monitoring - prometheus
+  prometheus: true
+  # monitoring - grafana
+  grafana: true
+
+```
+
+### Docker images
+
+The Pulsar Helm chart is designed to enable controlled upgrades. So it can configure independent image versions for components. You can customize the images by setting individual component.
+
+```yaml
+
+## Images
+##
+## Control what images to use for each component
+images:
+  zookeeper:
+    repository: apachepulsar/pulsar-all
+    tag: 2.5.0
+    pullPolicy: IfNotPresent
+  bookie:
+    repository: apachepulsar/pulsar-all
+    tag: 2.5.0
+    pullPolicy: IfNotPresent
+  autorecovery:
+    repository: apachepulsar/pulsar-all
+    tag: 2.5.0
+    pullPolicy: IfNotPresent
+  broker:
+    repository: apachepulsar/pulsar-all
+    tag: 2.5.0
+    pullPolicy: IfNotPresent
+  proxy:
+    repository: apachepulsar/pulsar-all
+    tag: 2.5.0
+    pullPolicy: IfNotPresent
+  functions:
+    repository: apachepulsar/pulsar-all
+    tag: 2.5.0
+  prometheus:
+    repository: prom/prometheus
+    tag: v1.6.3
+    pullPolicy: IfNotPresent
+  grafana:
+    repository: streamnative/apache-pulsar-grafana-dashboard-k8s
+    tag: 0.0.4
+    pullPolicy: IfNotPresent
+  pulsar_manager:
+    repository: apachepulsar/pulsar-manager
+    tag: v0.1.0
+    pullPolicy: IfNotPresent
+    hasCommand: false
+
+```
+
+### TLS
+
+The Pulsar Helm chart can be configured to enable TLS (Transport Layer Security) to protect all the traffic between components. Before enabling TLS, you have to provision TLS certificates for the required components.
+
+#### Provision TLS certificates using cert-manager
+
+To use the `cert-manager` to provision the TLS certificates, you have to install the [cert-manager](#install-cert-manager) before installing the Pulsar Helm chart. After successfully installing the cert-manager, you can set `certs.internal_issuer.enabled` to `true`. Therefore, the Pulsar Helm chart can use the `cert-manager` to generate `selfsigning` TLS certificates for the configured components.
+
+```yaml
+
+certs:
+  internal_issuer:
+    enabled: false
+    component: internal-cert-issuer
+    type: selfsigning
+
+```
+
+You can also customize the generated TLS certificates by configuring the fields as the following.
+
+```yaml
+
+tls:
+  # common settings for generating certs
+  common:
+    # 90d
+    duration: 2160h
+    # 15d
+    renewBefore: 360h
+    organization:
+      - pulsar
+    keySize: 4096
+    keyAlgorithm: rsa
+    keyEncoding: pkcs8
+
+```
+
+#### Enable TLS
+
+After installing the `cert-manager`, you can set `tls.enabled` to `true` to enable TLS encryption for the entire cluster.
+
+```yaml
+
+tls:
+  enabled: false
+
+```
+
+You can also configure whether to enable TLS encryption for individual component.
+
+```yaml
+
+tls:
+  # settings for generating certs for proxy
+  proxy:
+    enabled: false
+    cert_name: tls-proxy
+  # settings for generating certs for broker
+  broker:
+    enabled: false
+    cert_name: tls-broker
+  # settings for generating certs for bookies
+  bookie:
+    enabled: false
+    cert_name: tls-bookie
+  # settings for generating certs for zookeeper
+  zookeeper:
+    enabled: false
+    cert_name: tls-zookeeper
+  # settings for generating certs for recovery
+  autorecovery:
+    cert_name: tls-recovery
+  # settings for generating certs for toolset
+  toolset:
+    cert_name: tls-toolset
+
+```
+
+### Authentication
+
+By default, authentication is disabled. You can set `auth.authentication.enabled` to `true` to enable authentication.
+Currently, the Pulsar Helm chart only supports JWT authentication provider. You can set `auth.authentication.provider` to `jwt` to use the JWT authentication provider.
+
+```yaml
+
+# Enable or disable broker authentication and authorization.
+auth:
+  authentication:
+    enabled: false
+    provider: "jwt"
+    jwt:
+      # Enable JWT authentication
+      # If the token is generated by a secret key, set the usingSecretKey as true.
+      # If the token is generated by a private key, set the usingSecretKey as false.
+      usingSecretKey: false
+  superUsers:
+    # broker to broker communication
+    broker: "broker-admin"
+    # proxy to broker communication
+    proxy: "proxy-admin"
+    # pulsar-admin client to broker/proxy communication
+    client: "admin"
+
+```
+
+To enable authentication, you can run [prepare helm release](#prepare-the-helm-release) to generate token secret keys and tokens for three super users specified in the `auth.superUsers` field. The generated token keys and super user tokens are uploaded and stored as Kubernetes secrets prefixed with `<pulsar-release-name>-token-`. You can use the following command to find those secrets.
+
+```bash
+
+kubectl get secrets -n <k8s-namespace>
+
+```
+
+### Authorization
+
+By default, authorization is disabled. Authorization can be enabled only when authentication is enabled.
+
+```yaml
+
+auth:
+  authorization:
+    enabled: false
+
+```
+
+To enable authorization, you can include this option in the `helm install` command.
+
+```bash
+
+--set auth.authorization.enabled=true
+
+```
+
+### CPU and RAM resource requirements
+
+By default, the resource requests and the number of replicas for the Pulsar components in the Pulsar Helm chart are adequate for a small production deployment. If you deploy a non-production instance, you can reduce the defaults to fit into a smaller cluster.
+
+Once you have all of your configuration options collected, you can install dependent charts before installing the Pulsar Helm chart.
+
+## Install dependent charts
+
+### Install local storage provisioner
+
+To use local persistent volumes as the persistent storage, you need to install a storage provisioner for [local persistent volumes](https://kubernetes.io/blog/2019/04/04/kubernetes-1.14-local-persistent-volumes-ga/).
+
+One of the easiest way to get started is to use the local storage provisioner provided along with the Pulsar Helm chart.
+
+```
+
+helm repo add streamnative https://charts.streamnative.io
+helm repo update
+helm install pulsar-storage-provisioner streamnative/local-storage-provisioner
+
+```
+
+### Install cert-manager
+
+The Pulsar Helm chart uses the [cert-manager](https://github.com/jetstack/cert-manager) to provision and manage TLS certificates automatically. To enable TLS encryption for brokers or proxies, you need to install the cert-manager in advance.
+
+For details about how to install the cert-manager, follow the [official instructions](https://cert-manager.io/docs/installation/kubernetes/#installing-with-helm).
+
+Alternatively, we provide a bash script [install-cert-manager.sh](https://github.com/apache/pulsar-helm-chart/blob/master/scripts/cert-manager/install-cert-manager.sh) to install a cert-manager release to the namespace `cert-manager`.
+
+```bash
+
+git clone https://github.com/apache/pulsar-helm-chart
+cd pulsar-helm-chart
+./scripts/cert-manager/install-cert-manager.sh
+
+```
+
+## Prepare Helm release
+
+Once you have install all the dependent charts and collected all of your configuration options, you can run [prepare_helm_release.sh](https://github.com/apache/pulsar-helm-chart/blob/master/scripts/pulsar/prepare_helm_release.sh) to prepare the Helm release.
+
+```bash
+
+git clone https://github.com/apache/pulsar-helm-chart
+cd pulsar-helm-chart 
+./scripts/pulsar/prepare_helm_release.sh -n <k8s-namespace> -k <helm-release-name>
+
+```
+
+The `prepare_helm_release` creates the following resources:
+
+- A Kubernetes namespace for installing the Pulsar release
+- JWT secret keys and tokens for three super users: `broker-admin`, `proxy-admin`, and `admin`. By default, it generates an asymmetric pubic/private key pair. You can choose to generate a symmetric secret key by specifying `--symmetric`.
+  - `proxy-admin` role is used for proxies to communicate to brokers.
+  - `broker-admin` role is used for inter-broker communications.
+  - `admin` role is used by the admin tools.
+
+## Deploy Pulsar cluster using Helm
+
+Once you have finished the following three things, you can install a Helm release.
+
+- Collect all of your configuration options.
+- Install dependent charts.
+- Prepare the Helm release.
+
+In this example, we name our Helm release `pulsar`.
+
+```bash
+
+helm repo add apache https://pulsar.apache.org/charts
+helm repo update
+helm install pulsar apache/pulsar \
+    --timeout 10m \
+    --set initialize=true \
+    --set [your configuration options]
+
+```
+
+:::note
+
+For the first deployment, add `--set initialize=true` option to initialize bookie and Pulsar cluster metadata.
+
+:::
+
+You can also use the `--version <installation version>` option if you want to install a specific version of Pulsar Helm chart.
+
+## Monitor deployment
+
+A list of installed resources are output once the Pulsar cluster is deployed. This may take 5-10 minutes.
+
+The status of the deployment can be checked by running the `helm status pulsar` command, which can also be done while the deployment is taking place if you run the command in another terminal.
+
+## Access Pulsar cluster
+
+The default values will create a `ClusterIP` for the following resources, which you can use to interact with the cluster.
+
+- Proxy: You can use the IP address to produce and consume messages to the installed Pulsar cluster.
+- Pulsar Manager: You can access the Pulsar Manager UI at `http://<pulsar-manager-ip>:9527`.
+- Grafana Dashboard: You can access the Grafana dashboard at `http://<grafana-dashboard-ip>:3000`.
+
+To find the IP addresses of those components, run the following command:
+
+```bash
+
+kubectl get service -n <k8s-namespace>
+
+```
+
diff --git a/site2/website-next/versioned_docs/version-2.6.0/helm-install.md b/site2/website-next/versioned_docs/version-2.6.0/helm-install.md
new file mode 100644
index 0000000..edb1226
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.6.0/helm-install.md
@@ -0,0 +1,44 @@
+---
+id: helm-install
+title: Install Apache Pulsar using Helm
+sidebar_label: "Install"
+original_id: helm-install
+---
+
+Install Apache Pulsar on Kubernetes with the official Pulsar Helm chart.
+
+## Requirements
+
+To deploy Apache Pulsar on Kubernetes, the followings are required.
+
+- kubectl 1.14 or higher, compatible with your cluster ([+/- 1 minor release from your cluster](https://kubernetes.io/docs/tasks/tools/install-kubectl/#before-you-begin))
+- Helm v3 (3.0.2 or higher)
+- A Kubernetes cluster, version 1.14 or higher
+
+## Environment setup
+
+Before deploying Pulsar, you need to prepare your environment.
+
+### Tools
+
+Install [`helm`](helm-tools.md) and [`kubectl`](helm-tools) on your computer.
+
+## Cloud cluster preparation
+
+:::note
+
+Kubernetes 1.14 or higher is required.
+
+:::
+
+To create and connect to the Kubernetes cluster, follow the instructions:
+
+- [Google Kubernetes Engine](helm-prepare.md#google-kubernetes-engine)
+
+## Pulsar deployment
+
+Once the environment is set up and configuration is generated, you can now proceed to the [deployment of Pulsar](helm-deploy).
+
+## Pulsar upgrade
+
+To upgrade an existing Kubernetes installation, follow the [upgrade documentation](helm-upgrade).
diff --git a/site2/website-next/versioned_docs/version-2.6.0/helm-overview.md b/site2/website-next/versioned_docs/version-2.6.0/helm-overview.md
new file mode 100644
index 0000000..eaf0b96
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.6.0/helm-overview.md
@@ -0,0 +1,105 @@
+---
+id: helm-overview
+title: Apache Pulsar Helm Chart
+sidebar_label: "Overview"
+original_id: helm-overview
+---
+
+This is the official supported Helm chart to install Apache Pulsar on a cloud-native environment. It was enhanced based on StreamNative's [Helm Chart](https://github.com/streamnative/charts).
+
+## Introduction
+
+The Apache Pulsar Helm chart is one of the most convenient ways to operate Pulsar on Kubernetes. This Pulsar Helm chart contains all the required components to get started and can scale to large deployments.
+
+This chart includes all the components for a complete experience, but each part can be configured to be installed separately.
+
+- Pulsar core components:
+  - ZooKeeper
+  - Bookies
+  - Brokers
+  - Function workers
+  - Proxies
+- Control Center:
+  - Pulsar Manager
+  - Prometheus
+  - Grafana
+  - Alert Manager
+
+It includes support for:
+
+- Security
+  - Automatically provisioned TLS certificates, using [Jetstack](https://www.jetstack.io/)'s [cert-manager](https://cert-manager.io/docs/)
+      - self-signed
+      - [Let's Encrypt](https://letsencrypt.org/)
+  - TLS Encryption
+      - Proxy
+      - Broker
+      - Toolset
+      - Bookie
+      - ZooKeeper
+  - Authentication
+      - JWT
+  - Authorization
+- Storage
+  - Non-persistence storage
+  - Persistence volume
+  - Local persistent volumes
+- Functions
+  - Kubernetes Runtime
+  - Process Runtime
+  - Thread Runtime
+- Operations
+  - Independent image versions for all components, enabling controlled upgrades
+
+## Pulsar Helm chart quick start
+
+To get up and run with these charts as fast as possible, in a **non-production** use case, we provide a [quick start guide](getting-started-helm) for Proof of Concept (PoC) deployments.
+
+This guide walks the user through deploying these charts with default values and features, but *does not* meet production ready requirements. To deploy these charts into production under sustained load, follow the complete [Installation Guide](helm-install).
+
+## Troubleshooting
+
+We have done our best to make these charts as seamless as possible. Occasionally, troubles do go outside of our control. We have collected tips and tricks for troubleshooting common issues. Please check them first before raising an [issue](https://github.com/apache/pulsar/issues/new/choose), and feel free to add to them by raising a [Pull Request](https://github.com/apache/pulsar/compare).
+
+## Installation
+
+The Apache Pulsar Helm chart contains all required dependencies.
+
+If you deploy a PoC for testing, we strongly suggest you follow our [Quick Start Guide](getting-started-helm) for your first iteration.
+
+1. [Preparation](helm-prepare)
+2. [Deployment](helm-deploy)
+
+## Upgrading
+
+Once the Pulsar Helm chart is installed, use the `helm upgrade` to complete configuration changes and chart updates.
+
+```bash
+
+helm repo add apache https://pulsar.apache.org/charts
+helm repo update
+helm get values <pulsar-release-name> > pulsar.yaml
+helm upgrade <pulsar-release-name> apache/pulsar -f pulsar.yaml
+
+```
+
+For more detailed information, see [Upgrading](helm-upgrade).
+
+## Uninstallation
+
+To uninstall the Pulsar Helm chart, run the following command:
+
+```bash
+
+helm delete <pulsar-release-name>
+
+```
+
+For the purposes of continuity, these charts have some Kubernetes objects that cannot be removed when performing `helm delete`.
+It is recommended to *consciously* remove these items, as they affect re-deployment.
+
+* PVCs for stateful data: *consciously* remove these items.
+  - ZooKeeper: This is your metadata.
+  - BookKeeper: This is your data.
+  - Prometheus: This is your metrics data, which can be safely removed.
+* Secrets: if the secrets are generated by the [prepare release script](https://github.com/apache/pulsar-helm-chart/blob/master/scripts/pulsar/prepare_helm_release.sh), they contain secret keys and tokens. You can use the [cleanup release script](https://github.com/apache/pulsar-helm-chart/blob/master/scripts/pulsar/cleanup_helm_release.sh) to remove these secrets and tokens as needed.
diff --git a/site2/website-next/versioned_docs/version-2.6.0/helm-prepare.md b/site2/website-next/versioned_docs/version-2.6.0/helm-prepare.md
new file mode 100644
index 0000000..4814851
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.6.0/helm-prepare.md
@@ -0,0 +1,92 @@
+---
+id: helm-prepare
+title: Prepare Kubernetes resources
+sidebar_label: "Prepare"
+original_id: helm-prepare
+---
+
+For a fully functional Pulsar cluster, you need a few resources before deploying the Apache Pulsar Helm chart. The following provides instructions to prepare the Kubernetes cluster before deploying the Pulsar Helm chart.
+
+- [Google Kubernetes Engine](#google-kubernetes-engine)
+  - [Manual cluster creation](#manual-cluster-creation)
+  - [Scripted cluster creation](#scripted-cluster-creation)
+  - [Create cluster with local SSDs](#create-cluster-with-local-ssds)
+- [Next Steps](#next-steps)
+
+## Google Kubernetes Engine
+
+To get started easier, a script is provided to create the cluster automatically. Alternatively, a cluster can be created manually as well.
+
+- [Google Kubernetes Engine](#google-kubernetes-engine)
+  - [Manual cluster creation](#manual-cluster-creation)
+  - [Scripted cluster creation](#scripted-cluster-creation)
+  - [Create cluster with local SSDs](#create-cluster-with-local-ssds)
+- [Next Steps](#next-steps)
+
+### Manual cluster creation
+
+To provision a Kubernetes cluster manually, follow the [GKE instructions](https://cloud.google.com/kubernetes-engine/docs/how-to/creating-a-cluster).
+
+Alternatively, you can use the [instructions](#scripted-cluster-creation) below to provision a GKE cluster as needed.
+
+### Scripted cluster creation
+
+A [bootstrap script](https://github.com/streamnative/charts/tree/master/scripts/pulsar/gke_bootstrap_script.sh) has been created to automate much of the setup process for users on GCP/GKE.
+
+The script can:
+
+1. Create a new GKE cluster.
+2. Allow the cluster to modify DNS (Domain Name Server) records.
+3. Setup `kubectl`, and connect it to the cluster.
+
+Google Cloud SDK is a dependency of this script, so ensure it is [set up correctly](helm-tools.md#connect-to-a-gke-cluster) for the script to work.
+
+The script reads various parameters from environment variables and an argument `up` or `down` for bootstrap and clean-up respectively.
+
+The following table describes all variables.
+
+| **Variable** | **Description** | **Default value** |
+| ------------ | --------------- | ----------------- |
+| PROJECT      | ID of your GCP project | No default value. It requires to be set. |
+| CLUSTER_NAME | Name of the GKE cluster | `pulsar-dev` |
+| CONFDIR | Configuration directory to store Kubernetes configuration | ${HOME}/.config/streamnative |
+| INT_NETWORK | IP space to use within this cluster | `default` |
+| LOCAL_SSD_COUNT | Number of local SSD counts | 4 |
+| MACHINE_TYPE | Type of machine to use for nodes | `n1-standard-4` |
+| NUM_NODES | Number of nodes to be created in each of the cluster's zones | 4 |
+| PREEMPTIBLE | Create nodes using preemptible VM instances in the new cluster. | false |
+| REGION | Compute region for the cluster | `us-east1` |
+| USE_LOCAL_SSD | Flag to create a cluster with local SSDs | false |
+| ZONE | Compute zone for the cluster | `us-east1-b` |
+| ZONE_EXTENSION | The extension (`a`, `b`, `c`) of the zone name of the cluster | `b` |
+| EXTRA_CREATE_ARGS | Extra arguments passed to create command | |
+
+Run the script, by passing in your desired parameters. It can work with the default parameters except for `PROJECT` which is required:
+
+```bash
+
+PROJECT=<gcloud project id> scripts/pulsar/gke_bootstrap_script.sh up
+
+```
+
+The script can also be used to clean up the created GKE resources.
+
+```bash
+
+PROJECT=<gcloud project id> scripts/pulsar/gke_bootstrap_script.sh down
+
+```
+
+#### Create cluster with local SSDs
+
+To install a Pulsar Helm chart using local persistent volumes, you need to create a GKE cluster with local SSDs. You can do so Specifying the `USE_LOCAL_SSD` to be `true` in the following command to create a Pulsar cluster with local SSDs.
+
+```
+
+PROJECT=<gcloud project id> USE_LOCAL_SSD=true LOCAL_SSD_COUNT=<local-ssd-count> scripts/pulsar/gke_bootstrap_script.sh up
+
+```
+
+## Next Steps
+
+Continue with the [installation of the chart](helm-deploy) once you have the cluster up and running.
diff --git a/site2/website-next/versioned_docs/version-2.6.0/helm-tools.md b/site2/website-next/versioned_docs/version-2.6.0/helm-tools.md
new file mode 100644
index 0000000..efd61ea
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.6.0/helm-tools.md
@@ -0,0 +1,43 @@
+---
+id: helm-tools
+title: Required tools for deploying Pulsar Helm Chart
+sidebar_label: "Required Tools"
+original_id: helm-tools
+---
+
+Before deploying Pulsar to your Kubernetes cluster, there are some tools you must have installed locally.
+
+## kubectl
+
+kubectl is the tool that talks to the Kubernetes API. kubectl 1.14 or higher is required and it needs to be compatible with your cluster ([+/- 1 minor release from your cluster](https://kubernetes.io/docs/tasks/tools/install-kubectl/#before-you-begin)).
+
+To Install kubectl locally, follow the [Kubernetes documentation](https://kubernetes.io/docs/tasks/tools/install-kubectl/#install-kubectl).
+
+The server version of kubectl cannot be obtained until we connect to a cluster.
+
+## Helm
+
+Helm is the package manager for Kubernetes. The Apache Pulsar Helm Chart is tested and supported with Helm v3.
+
+### Get Helm
+
+You can get Helm from the project's [releases page](https://github.com/helm/helm/releases), or follow other options under the official documentation of [installing Helm](https://helm.sh/docs/intro/install/).
+
+### Next steps
+
+Once kubectl and Helm are configured, you can configure your [Kubernetes cluster](helm-prepare).
+
+## Additional information
+
+### Templates
+
+Templating in Helm is done through Golang's [text/template](https://golang.org/pkg/text/template/) and [sprig](https://godoc.org/github.com/Masterminds/sprig).
+
+For more information about how all the inner workings behave, check these documents:
+
+- [Functions and Pipelines](https://helm.sh/docs/chart_template_guide/functions_and_pipelines/)
+- [Subcharts and Globals](https://helm.sh/docs/chart_template_guide/subcharts_and_globals/)
+
+### Tips and tricks
+
+For additional information on developing with Helm, check [tips and tricks section](https://helm.sh/docs/howto/charts_tips_and_tricks/) in the Helm repository.
\ No newline at end of file
diff --git a/site2/website-next/versioned_docs/version-2.6.0/helm-upgrade.md b/site2/website-next/versioned_docs/version-2.6.0/helm-upgrade.md
new file mode 100644
index 0000000..1ebe4b4
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.6.0/helm-upgrade.md
@@ -0,0 +1,45 @@
+---
+id: helm-upgrade
+title: Upgrade Pulsar Helm release
+sidebar_label: "Upgrade"
+original_id: helm-upgrade
+---
+
+Before upgrading your Pulsar installation, you need to check the change log corresponding to the specific release you want to upgrade to and look for any release notes that might pertain to the new Pulsar helm chart version.
+
+We also recommend that you need to provide all values using the `helm upgrade --set key=value` syntax or the `-f values.yml` instead of using `--reuse-values`, because some of the current values might be deprecated.
+
+:::note
+
+You can retrieve your previous `--set` arguments cleanly, with `helm get values <release-name>`. If you direct this into a file (`helm get values <release-name> > pulsar.yml`), you can safely
+
+:::
+
+pass this file through `-f`. Thus `helm upgrade <release-name> apache/pulsar -f pulsar.yaml`. This safely replaces the behavior of `--reuse-values`.
+
+## Steps
+
+To upgrade Apache Pulsar to a newer version, follow these steps:
+
+1. Check the change log for the specific version you would like to upgrade to.
+2. Go through [deployment documentation](helm-deploy) step by step.
+3. Extract your previous `--set` arguments with the following command.
+
+   ```bash
+   
+   helm get values <release-name> > pulsar.yaml
+   
+   ```
+
+4. Decide all the values you need to set.
+5. Perform the upgrade, with all `--set` arguments extracted in step 4.
+
+   ```bash
+   
+   helm upgrade <release-name> apache/pulsar \
+       --version <new version> \
+       -f pulsar.yaml \
+       --set ...
+   
+   ```
+
diff --git a/site2/website-next/versioned_docs/version-2.6.0/performance-pulsar-perf.md b/site2/website-next/versioned_docs/version-2.6.0/performance-pulsar-perf.md
new file mode 100644
index 0000000..25be169
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.6.0/performance-pulsar-perf.md
@@ -0,0 +1,210 @@
+---
+id: performance-pulsar-perf
+title: Pulsar Perf
+sidebar_label: "Pulsar Perf"
+original_id: performance-pulsar-perf
+---
+
+This document describes how to use the Pulsar Perf for performance testing. For detailed information about performance tuning, see [here](https://streamnative.io/whitepaper/taking-a-deep-dive-into-apache-pulsar-architecture-for-performance-tuning/).
+
+## Pulsar Perf
+
+The Pulsar Perf is a built-in performance test tool for Apache Pulsar. You can use the Pulsar Perf to test message writing or reading performance.
+
+### Produce messages
+
+This example shows how the Pulsar Perf produces messages with default options. For all configuration options available for the `pulsar-perf produce` command, see [configuration options](#configuration-options-for-pulsar-perf-produce).
+
+```
+
+bin/pulsar-perf produce my-topic
+
+```
+
+After the command is executed, the test data is continuously output on the Console.
+
+**Output**
+
+```
+
+19:53:31.459 [pulsar-perf-producer-exec-1-1] INFO  org.apache.pulsar.testclient.PerformanceProducer - Created 1 producers
+19:53:31.482 [pulsar-timer-5-1] WARN  com.scurrilous.circe.checksum.Crc32cIntChecksum - Failed to load Circe JNI library. Falling back to Java based CRC32c provider
+19:53:40.861 [main] INFO  org.apache.pulsar.testclient.PerformanceProducer - Throughput produced:     93.7  msg/s ---      0.7 Mbit/s --- failure      0.0 msg/s --- Latency: mean:   3.575 ms - med:   3.460 - 95pct:   4.790 - 99pct:   5.308 - 99.9pct:   5.834 - 99.99pct:   6.609 - Max:   6.609
+19:53:50.909 [main] INFO  org.apache.pulsar.testclient.PerformanceProducer - Throughput produced:    100.0  msg/s ---      0.8 Mbit/s --- failure      0.0 msg/s --- Latency: mean:   3.437 ms - med:   3.328 - 95pct:   4.656 - 99pct:   5.071 - 99.9pct:   5.519 - 99.99pct:   5.588 - Max:   5.588
+19:54:00.926 [main] INFO  org.apache.pulsar.testclient.PerformanceProducer - Throughput produced:    100.0  msg/s ---      0.8 Mbit/s --- failure      0.0 msg/s --- Latency: mean:   3.376 ms - med:   3.276 - 95pct:   4.520 - 99pct:   4.939 - 99.9pct:   5.440 - 99.99pct:   5.490 - Max:   5.490
+19:54:10.940 [main] INFO  org.apache.pulsar.testclient.PerformanceProducer - Throughput produced:    100.0  msg/s ---      0.8 Mbit/s --- failure      0.0 msg/s --- Latency: mean:   3.298 ms - med:   3.220 - 95pct:   4.474 - 99pct:   4.926 - 99.9pct:   5.645 - 99.99pct:   5.654 - Max:   5.654
+19:54:20.956 [main] INFO  org.apache.pulsar.testclient.PerformanceProducer - Throughput produced:    100.1  msg/s ---      0.8 Mbit/s --- failure      0.0 msg/s --- Latency: mean:   3.308 ms - med:   3.199 - 95pct:   4.532 - 99pct:   4.871 - 99.9pct:   5.291 - 99.99pct:   5.323 - Max:   5.323
+19:54:30.972 [main] INFO  org.apache.pulsar.testclient.PerformanceProducer - Throughput produced:    100.0  msg/s ---      0.8 Mbit/s --- failure      0.0 msg/s --- Latency: mean:   3.249 ms - med:   3.144 - 95pct:   4.437 - 99pct:   4.970 - 99.9pct:   5.329 - 99.99pct:   5.414 - Max:   5.414
+19:54:40.987 [main] INFO  org.apache.pulsar.testclient.PerformanceProducer - Throughput produced:    100.0  msg/s ---      0.8 Mbit/s --- failure      0.0 msg/s --- Latency: mean:   3.435 ms - med:   3.361 - 95pct:   4.772 - 99pct:   5.150 - 99.9pct:   5.373 - 99.99pct:   5.837 - Max:   5.837
+^C19:54:44.325 [Thread-1] INFO  org.apache.pulsar.testclient.PerformanceProducer - Aggregated throughput stats --- 7286 records sent --- 99.140 msg/s --- 0.775 Mbit/s
+19:54:44.336 [Thread-1] INFO  org.apache.pulsar.testclient.PerformanceProducer - Aggregated latency stats --- Latency: mean:   3.383 ms - med:   3.293 - 95pct:   4.610 - 99pct:   5.059 - 99.9pct:   5.588 - 99.99pct:   5.837 - 99.999pct:   6.609 - Max:   6.609
+
+```
+
+From the above test data, you can get the throughput statistics and the write latency statistics. The aggregated statistics is printed when the Pulsar Perf is stopped. You can press **Ctrl**+**C** to stop the Pulsar Perf. After the Pulsar Perf is stopped, the [HdrHistogram](http://hdrhistogram.github.io/HdrHistogram/) formatted test result appears under your directory. The document looks like `perf-producer-1589370810837.hgrm`. You can also check the test result through [HdrHistogram Plo [...]
+
+#### Configuration options for `pulsar-perf produce`
+
+You can get all options by executing the `bin/pulsar-perf produce -h` command. Therefore, you can modify these options as required.
+
+The following table lists configuration options available for the `pulsar-perf produce` command.
+
+| Option | Description | Default value|
+|----|----|----|
+| auth-params | Set the authentication parameters, whose format is determined by the implementation of the `configure` method in the authentication plugin class, such as "key1:val1,key2:val2" or "{"key1":"val1","key2":"val2"}". | N/A |
+| auth_plugin | Set the authentication plugin class name. | N/A |
+| batch-max-bytes | Set the maximum number of bytes for each batch. | 4194304 |
+| batch-max-messages | Set the maximum number of messages for each batch. | 1000 |
+| batch-time-window | Set a window for a batch of messages. | 1 ms |
+| chunking | Configure whether to split the message and publish in chunks if message size is larger than allowed max size. | false |
+| compression | Compress the message payload. | N/A |
+| conf-file | Set the configuration file. | N/A |
+| delay | Mark messages with a given delay. | 0s |
+| encryption-key-name | Set the name of the public key used to encrypt the payload. | N/A |
+| encryption-key-value-file | Set the file which contains the public key used to encrypt the payload. | N/A |
+| exit-on-failure | Configure whether to exit from the process on publish failure. | false |
+| help | Configure the help message. | false |
+| max-connections | Set the maximum number of TCP connections to a single broker. | 100 |
+| max-outstanding | Set the maximum number of outstanding messages. | 1000 |
+| max-outstanding-across-partitions | Set the maximum number of outstanding messages across partitions. | 50000 |
+| num-messages | Set the number of messages to be published in total. If it is set to 0, it keeps publishing messages. | 0 |
+| num-producers | Set the number of producers for each topic. | 1 |
+| num-test-threads |  Set the number of test threads. | 1 |
+| num-topic | Set the number of topics. | 1 |
+| payload-delimiter | Set the delimiter used to split lines when using payload from a file. | \n |
+| payload-file | Use the payload from an UTF-8 encoded text file and a payload is randomly selected when messages are published. | N/A |
+| rate | Set the publish rate of messages across topics. | 100 |
+| service-url | Set the Pulsar service URL. | |
+| size | Set the message size. | 1024 bytes |
+| stats-interval-seconds | Set the statistics interval. If it is set to 0, statistics is disabled. | 0 |
+| test-duration | Set the test duration. If it is set to 0, it keeps publishing tests. | 0s |
+| trust-cert-file | Set the path for the trusted TLS certificate file. | | |
+| warmup-time | Set the warm-up time. | 1s |
+
+### Consume messages
+
+This example shows how the Pulsar Perf consumes messages with default options.
+
+```
+
+bin/pulsar-perf consume my-topic
+
+```
+
+After the command is executed, the test data is continuously output on the Console.
+
+**Output**
+
+```
+
+20:35:37.071 [main] INFO  org.apache.pulsar.testclient.PerformanceConsumer - Start receiving from 1 consumers on 1 topics
+20:35:41.150 [pulsar-client-io-1-9] WARN  com.scurrilous.circe.checksum.Crc32cIntChecksum - Failed to load Circe JNI library. Falling back to Java based CRC32c provider
+20:35:47.092 [main] INFO  org.apache.pulsar.testclient.PerformanceConsumer - Throughput received: 59.572  msg/s -- 0.465 Mbit/s --- Latency: mean: 11.298 ms - med: 10 - 95pct: 15 - 99pct: 98 - 99.9pct: 137 - 99.99pct: 152 - Max: 152
+20:35:57.104 [main] INFO  org.apache.pulsar.testclient.PerformanceConsumer - Throughput received: 99.958  msg/s -- 0.781 Mbit/s --- Latency: mean: 9.176 ms - med: 9 - 95pct: 15 - 99pct: 16 - 99.9pct: 17 - 99.99pct: 18 - Max: 18
+20:36:07.115 [main] INFO  org.apache.pulsar.testclient.PerformanceConsumer - Throughput received: 100.006  msg/s -- 0.781 Mbit/s --- Latency: mean: 9.316 ms - med: 9 - 95pct: 15 - 99pct: 16 - 99.9pct: 17 - 99.99pct: 17 - Max: 17
+20:36:17.125 [main] INFO  org.apache.pulsar.testclient.PerformanceConsumer - Throughput received: 100.085  msg/s -- 0.782 Mbit/s --- Latency: mean: 9.327 ms - med: 9 - 95pct: 15 - 99pct: 16 - 99.9pct: 17 - 99.99pct: 17 - Max: 17
+20:36:27.136 [main] INFO  org.apache.pulsar.testclient.PerformanceConsumer - Throughput received: 99.900  msg/s -- 0.780 Mbit/s --- Latency: mean: 9.404 ms - med: 9 - 95pct: 15 - 99pct: 16 - 99.9pct: 17 - 99.99pct: 17 - Max: 17
+20:36:37.147 [main] INFO  org.apache.pulsar.testclient.PerformanceConsumer - Throughput received: 99.985  msg/s -- 0.781 Mbit/s --- Latency: mean: 8.998 ms - med: 9 - 95pct: 15 - 99pct: 16 - 99.9pct: 17 - 99.99pct: 17 - Max: 17
+^C20:36:42.755 [Thread-1] INFO  org.apache.pulsar.testclient.PerformanceConsumer - Aggregated throughput stats --- 6051 records received --- 92.125 msg/s --- 0.720 Mbit/s
+20:36:42.759 [Thread-1] INFO  org.apache.pulsar.testclient.PerformanceConsumer - Aggregated latency stats --- Latency: mean: 9.422 ms - med: 9 - 95pct: 15 - 99pct: 16 - 99.9pct: 98 - 99.99pct: 137 - 99.999pct: 152 - Max: 152
+
+```
+
+From the output test data, you can get the throughput statistics and the end-to-end latency statistics. The aggregated statistics is printed after the Pulsar Perf is stopped. You can press **Ctrl**+**C** to stop the Pulsar Perf.
+
+#### Configuration options for `pulsar-perf consume`
+
+You can get all options by executing the `bin/pulsar-perf consume -h` command. Therefore, you can modify these options as required.
+
+The following table lists configuration options available for the `pulsar-perf consume` command.
+
+| Option | Description | Default value |
+|----|----|----|
+| acks-delay-millis | Set the acknowledgment grouping delay in milliseconds. | 100 ms |
+| auth-params | Set the authentication parameters, whose format is determined by the implementation of the `configure` method in the authentication plugin class, such as "key1:val1,key2:val2" or "{"key1":"val1","key2":"val2"}". | N/A |
+| auth_plugin | Set the authentication plugin class name. | N/A |
+| auto_ack_chunk_q_full | Configure whether to automatically ack for the oldest message in receiver queue if the queue is full. | false |
+| conf-file | Set the configuration file. | N/A |
+| encryption-key-name | Set the name of the public key used to encrypt the payload. | N/A |
+| encryption-key-value-file | Set the file which contains the public key used to encrypt the payload. | N/A |
+| help | Configure the help message. | false |
+| expire_time_incomplete_chunked_messages | Set the expiration time for incomplete chunk messages (in milliseconds). | 0 |
+| max-connections | Set the maximum number of TCP connections to a single broker. | 100 |
+| max_chunked_msg | Set the max pending chunk messages. | 0 |
+| num-consumers | Set the number of consumers for each topic. | 1 |
+| num-topic | Set the number of topics. | 1 |
+| rate | Simulate a slow message consumer (rate in msg/s). | 0.0 |
+| receiver-queue-size | Set the size of the receiver queue. | 1000 |
+| replicated | Configure whether the subscription status should be replicated. | false |
+| replicated | Configure whether the subscription status should be replicated. | false |
+| service-url | Set the Pulsar service URL. | |
+| stats-interval-seconds | Set the statistics interval. If it is set to 0, statistics is disabled. | 0 |
+| subscriber-name | Set the subscriber name prefix. | sub |
+| subscription-type | Set the subscription type. <li> Exclusive </li><li> Shared </li><li> Failover </li><li> Key_Shared </li>| Exclusive |
+| test-duration | Set the test duration (in seconds). If the value is 0 or smaller than 0, it keeps consuming messages. | 0 |
+| trust-cert-file | Set the path for the trusted TLS certificate file. | | |
+
+### Configurations
+
+By default, the Pulsar Perf uses `conf/client.conf` as the default configuration and uses `conf/log4j2.yaml` as the default Log4j configuration. If you want to connect to other Pulsar clusters, you can update the `brokerServiceUrl` in the client configuration.
+
+You can use the following commands to change the configuration file and the Log4j configuration file.
+
+```
+
+export PULSAR_CLIENT_CONF=<your-config-file>
+export PULSAR_LOG_CONF=<your-log-config-file>
+
+```
+
+In addition, you can use the following command to configure the JVM configuration through environment variables:
+
+```
+
+export PULSAR_EXTRA_OPTS='-Xms4g -Xmx4g -XX:MaxDirectMemorySize=4g'
+
+```
+
+## HdrHistogram Plotter
+
+The [HdrHistogram Plotter](https://hdrhistogram.github.io/HdrHistogram/plotFiles.html) is a visualization tool for checking Pulsar Perf test results, which makes it easier to observe the test results.
+
+To check test results through the HdrHistogram Plotter, follow these steps:
+
+1. Clone the HdrHistogram repository from GitHub to the local.
+
+   ```
+   
+   git clone https://github.com/HdrHistogram/HdrHistogram.git
+   
+   ```
+
+2. Switch to the HdrHistogram folder.
+
+   ```
+   
+   cd HdrHistogram
+   
+   ```
+
+3. Install the HdrHistogram Plotter.
+
+   ```
+   
+   mvn clean install -DskipTests
+   
+   ```
+
+4. Transform the file generated by the Pulsar Perf.
+
+   ```
+   
+   ./HistogramLogProcessor -i <hgrm file path that pulsar-perf generated> -o <output file>
+   
+   ```
+
+5. You will get two output files. Upload the output file with the filename extension of .hgrm to the [HdrHistogram Plotter](https://hdrhistogram.github.io/HdrHistogram/plotFiles.html).
+
+6. Check the test result through the Graphical User Interface of the HdrHistogram Plotter, as shown blow.
+
+   ![](/assets/perf-produce.png)
diff --git a/site2/website-next/versioned_docs/version-2.6.0/security-athenz.md b/site2/website-next/versioned_docs/version-2.6.0/security-athenz.md
new file mode 100644
index 0000000..947c3f4
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.6.0/security-athenz.md
@@ -0,0 +1,98 @@
+---
+id: security-athenz
+title: Authentication using Athenz
+sidebar_label: "Authentication using Athenz"
+original_id: security-athenz
+---
+
+[Athenz](https://github.com/AthenZ/athenz) is a role-based authentication/authorization system. In Pulsar, you can use Athenz role tokens (also known as *z-tokens*) to establish the identify of the client.
+
+## Athenz authentication settings
+
+A [decentralized Athenz system](https://github.com/AthenZ/athenz/blob/master/docs/decent_authz_flow.md) contains an [authori**Z**ation **M**anagement **S**ystem](https://github.com/AthenZ/athenz/blob/master/docs/setup_zms.md) (ZMS) server and an [authori**Z**ation **T**oken **S**ystem](https://github.com/AthenZ/athenz/blob/master/docs/setup_zts) (ZTS) server.
+
+To begin, you need to set up Athenz service access control. You need to create domains for the *provider* (which provides some resources to other services with some authentication/authorization policies) and the *tenant* (which is provisioned to access some resources in a provider). In this case, the provider corresponds to the Pulsar service itself and the tenant corresponds to each application using Pulsar (typically, a [tenant](reference-terminology.md#tenant) in Pulsar).
+
+### Create the tenant domain and service
+
+On the [tenant](reference-terminology.md#tenant) side, you need to do the following things:
+
+1. Create a domain, such as `shopping`
+2. Generate a private/public key pair
+3. Create a service, such as `some_app`, on the domain with the public key
+
+Note that you need to specify the private key generated in step 2 when the Pulsar client connects to the [broker](reference-terminology.md#broker) (see client configuration examples for [Java](client-libraries-java.md#tls-authentication) and [C++](client-libraries-cpp.md#tls-authentication)).
+
+For more specific steps involving the Athenz UI, refer to [Example Service Access Control Setup](https://github.com/AthenZ/athenz/blob/master/docs/example_service_athenz_setup.md#client-tenant-domain).
+
+### Create the provider domain and add the tenant service to some role members
+
+On the provider side, you need to do the following things:
+
+1. Create a domain, such as `pulsar`
+2. Create a role
+3. Add the tenant service to members of the role
+
+Note that you can specify any action and resource in step 2 since they are not used on Pulsar. In other words, Pulsar uses the Athenz role token only for authentication, *not* for authorization.
+
+For more specific steps involving UI, refer to [Example Service Access Control Setup](https://github.com/AthenZ/athenz/blob/master/docs/example_service_athenz_setup.md#server-provider-domain).
+
+## Configure the broker for Athenz
+
+> ### TLS encryption 
+>
+> Note that when you are using Athenz as an authentication provider, you had better use TLS encryption 
+> as it can protect role tokens from being intercepted and reused. (for more details involving TLS encryption see [Architecture - Data Model](https://github.com/AthenZ/athenz/blob/master/docs/data_model)).
+
+In the `conf/broker.conf` configuration file in your Pulsar installation, you need to provide the class name of the Athenz authentication provider as well as a comma-separated list of provider domain names.
+
+```properties
+
+# Add the Athenz auth provider
+authenticationEnabled=true
+authorizationEnabled=true
+authenticationProviders=org.apache.pulsar.broker.authentication.AuthenticationProviderAthenz
+athenzDomainNames=pulsar
+
+# Enable TLS
+tlsEnabled=true
+tlsCertificateFilePath=/path/to/broker-cert.pem
+tlsKeyFilePath=/path/to/broker-key.pem
+
+# Authentication settings of the broker itself. Used when the broker connects to other brokers, either in same or other clusters
+brokerClientAuthenticationPlugin=org.apache.pulsar.client.impl.auth.AuthenticationAthenz
+brokerClientAuthenticationParameters={"tenantDomain":"shopping","tenantService":"some_app","providerDomain":"pulsar","privateKey":"file:///path/to/private.pem","keyId":"v1"}
+
+```
+
+> A full listing of parameters is available in the `conf/broker.conf` file, you can also find the default
+> values for those parameters in [Broker Configuration](reference-configuration.md#broker).
+
+## Configure clients for Athenz
+
+For more information on Pulsar client authentication using Athenz, see the following language-specific docs:
+
+* [Java client](client-libraries-java.md#athenz)
+
+## Configure CLI tools for Athenz
+
+[Command-line tools](reference-cli-tools.md) like [`pulsar-admin`](reference-pulsar-admin), [`pulsar-perf`](reference-cli-tools.md#pulsar-perf), and [`pulsar-client`](reference-cli-tools.md#pulsar-client) use the `conf/client.conf` config file in a Pulsar installation.
+
+You need to add the following authentication parameters to the `conf/client.conf` config file to use Athenz with CLI tools of Pulsar:
+
+```properties
+
+# URL for the broker
+serviceUrl=https://broker.example.com:8443/
+
+# Set Athenz auth plugin and its parameters
+authPlugin=org.apache.pulsar.client.impl.auth.AuthenticationAthenz
+authParams={"tenantDomain":"shopping","tenantService":"some_app","providerDomain":"pulsar","privateKey":"file:///path/to/private.pem","keyId":"v1"}
+
+# Enable TLS
+useTls=true
+tlsAllowInsecureConnection=false
+tlsTrustCertsFilePath=/path/to/cacert.pem
+
+```
+
diff --git a/site2/website-next/versioned_docs/version-2.6.0/security-authorization.md b/site2/website-next/versioned_docs/version-2.6.0/security-authorization.md
new file mode 100644
index 0000000..28200ad
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.6.0/security-authorization.md
@@ -0,0 +1,113 @@
+---
+id: security-authorization
+title: Authentication and authorization in Pulsar
+sidebar_label: "Authorization and ACLs"
+original_id: security-authorization
+---
+
+
+In Pulsar, the [authentication provider](security-overview.md#authentication-providers) is responsible for properly identifying clients and associating the clients with [role tokens](security-overview.md#role-tokens). If you only enable authentication, an authenticated role token has the ability to access all resources in the cluster. *Authorization* is the process that determines *what* clients are able to do.
+
+The role tokens with the most privileges are the *superusers*. The *superusers* can create and destroy tenants, along with having full access to all tenant resources.
+
+When a superuser creates a [tenant](reference-terminology.md#tenant), that tenant is assigned an admin role. A client with the admin role token can then create, modify and destroy namespaces, and grant and revoke permissions to *other role tokens* on those namespaces.
+
+## Broker and Proxy Setup
+
+### Enable authorization and assign superusers
+You can enable the authorization and assign the superusers in the broker ([`conf/broker.conf`](reference-configuration.md#broker)) configuration files.
+
+```properties
+
+authorizationEnabled=true
+superUserRoles=my-super-user-1,my-super-user-2
+
+```
+
+> A full list of parameters is available in the `conf/broker.conf` file.
+> You can also find the default values for those parameters in [Broker Configuration](reference-configuration.md#broker). 
+
+Typically, you can not only use superuser roles for administrators and clients but also for broker-to-broker authorization. When you use [geo-replication](concepts-replication), every broker needs to be able to publish to all the other topics of clusters.
+
+You can also enable the authorization for the proxy in the proxy configuration file (`conf/proxy.conf`). Once you enable the authorization on the proxy, the proxy does an additional authorization check before forwarding the request to a broker. The broker still checks the authorization of the request when the broker receives the forwarded request.
+
+### Proxy Roles
+
+By default, the broker treats the connection between a proxy and the broker as a normal user connection. The broker authenticates the user as the role configured in `proxy.conf`(see ["Enable TLS Authentication on Proxies"](security-tls-authentication.md#enable-tls-authentication-on-proxies)). However, when the user connects to the cluster through a proxy, the user rarely requires the authentication. The user expects to be able to interact with the cluster as the role for which they have  [...]
+
+Pulsar uses *Proxy roles* to enable the authentication. Proxy roles are specified in the broker configuration file, [`conf/broker.conf`](reference-configuration.md#broker). If a client that is authenticated with a broker is one of its ```proxyRoles```, all requests from that client must also carry information about the role of the client that is authenticated with the proxy. This information is called the *original principle*. If the *original principle* misses, the client is not able to [...]
+
+You must authorize the *proxy role* and the *original principle* to access a resource. Thus that resource can be accessible via the proxy. Administrators can take two approaches to authorize the *proxy role* and the *original principle*.
+
+The more secure approach is to grant access to the proxy roles each time you grant access to a resource. For example, if you have a proxy role named `proxy1`, when the superuser creates a tenant, you should specify `proxy1` as one of the admin roles. When a role is granted permissions to produce or consume from a namespace, if that client wants to produce or consume through a proxy, you should also grant `proxy1` the same permissions.
+
+Another approach is to make the proxy role a superuser. This allows the proxy to access all resources. The client still needs to authenticate with the proxy, and all requests made through the proxy have their role downgraded to the *original principal* of the authenticated client. However, if the proxy is compromised, a bad actor could get full access to your cluster.
+
+You can specify the roles as proxy roles in [`conf/broker.conf`](reference-configuration.md#broker).
+
+```properties
+
+proxyRoles=my-proxy-role
+
+# if you want to allow superusers to use the proxy (see above)
+superUserRoles=my-super-user-1,my-super-user-2,my-proxy-role
+
+```
+
+## Administer tenants
+
+Pulsar [instance](reference-terminology.md#instance) administrators or some kind of self-service portal typically provisions a Pulsar [tenant](reference-terminology.md#tenant). 
+
+You can manage tenants using the [`pulsar-admin`](reference-pulsar-admin) tool. 
+
+### Create a new tenant
+
+The following is an example tenant creation command:
+
+```shell
+
+$ bin/pulsar-admin tenants create my-tenant \
+  --admin-roles my-admin-role \
+  --allowed-clusters us-west,us-east
+
+```
+
+This command creates a new tenant `my-tenant` that is allowed to use the clusters `us-west` and `us-east`.
+
+A client that successfully identifies itself as having the role `my-admin-role` is allowed to perform all administrative tasks on this tenant.
+
+The structure of topic names in Pulsar reflects the hierarchy between tenants, clusters, and namespaces:
+
+```shell
+
+persistent://tenant/namespace/topic
+
+```
+
+### Manage permissions
+
+You can use [Pulsar Admin Tools](admin-api-permissions) for managing permission in Pulsar.
+
+### Pulsar admin authentication
+
+```java
+
+PulsarAdmin admin = PulsarAdmin.builder()
+                    .serviceHttpUrl("http://broker:8080")
+                    .authentication("com.org.MyAuthPluginClass", "param1:value1")
+                    .build();
+
+```
+
+To use TLS:
+
+```java
+
+PulsarAdmin admin = PulsarAdmin.builder()
+                    .serviceHttpUrl("https://broker:8080")
+                    .authentication("com.org.MyAuthPluginClass", "param1:value1")
+                    .tlsTrustCertsFilePath("/path/to/trust/cert")
+                    .build();
+
+```
+
diff --git a/site2/website-next/versioned_docs/version-2.6.0/security-bouncy-castle.md b/site2/website-next/versioned_docs/version-2.6.0/security-bouncy-castle.md
new file mode 100644
index 0000000..1012f0e
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.6.0/security-bouncy-castle.md
@@ -0,0 +1,133 @@
+---
+id: security-bouncy-castle
+title: Bouncy Castle Providers
+sidebar_label: "Bouncy Castle Providers"
+original_id: security-bouncy-castle
+---
+
+## BouncyCastle Introduce
+
+`Bouncy Castle` is a Java library that complements the default Java Cryptographic Extension (JCE), 
+and it many more cipher suites and algorithms than the default JCE provided by Sun.
+
+In addition to that, `Bouncy Castle` has lots of utilities for reading arcane formats like PEM and ASN.1 that no sane person would want to rewrite themselves.
+
+In Pulsar, security and crypto have dependencies on BouncyCastle Jars. For the detailed installing and configuring Bouncy Castle FIPS, see [BC FIPS Documentation](https://www.bouncycastle.org/documentation.html), especially the **User Guides** and **Security Policy** PDFs.
+
+`Bouncy Castle` provides both [FIPS](https://www.bouncycastle.org/fips_faq.html) and non-FIPS version. But in a JVM, you can not include both of the 2 versions, and you need to exclude the current version before include the other.
+
+In Pulsar, the security and crypto methods also depends on `Bouncy Castle`, especially in [TLS Authentication](security-tls-authentication.md) and [Transport Encryption](security-encryption). This document contains the configuration between BouncyCastle FIPS(BC-FIPS) and non-FIPS(BC-non-FIPS) version while using Pulsar.
+
+## Include dependencies of BC-non-FIPS
+
+By default, BouncyCastle non-FIPS version is build along with Pulsar's Broker and Java client.
+
+Pulsar module `bouncy-castle-bc`, which defined by `bouncy-castle/bc/pom.xml` contains the needed non-FIPS jars for Pulsar.
+
+```xml
+
+    <dependency>
+      <groupId>org.bouncycastle</groupId>
+      <artifactId>bcpkix-jdk15on</artifactId>
+      <version>${bouncycastle.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.bouncycastle</groupId>
+      <artifactId>bcprov-ext-jdk15on</artifactId>
+      <version>${bouncycastle.version}</version>
+    </dependency>
+
+```
+
+By using this `bouncy-castle-bc` module, user can easily include and exclude BouncyCastle non-FIPS jars.
+
+### Pulsar Client and Broker dependencies on BC-non-FIPS
+
+Pulsar Client(`pulsar-client-original`) module include BouncyCastle non-FIPS jars by add dependency like this:
+
+```xml
+
+    <dependency>
+      <groupId>org.apache.pulsar</groupId>
+      <artifactId>bouncy-castle-bc</artifactId>
+      <version>${project.parent.version}</version>
+      <classifier>pkg</classifier>
+    </dependency>
+
+```
+
+And Pulsar Broker (`pulsar-broker`) module include BouncyCastle non-FIPS jars by indirectly include Pulsar Client(`pulsar-client-original`) module.
+
+```xml
+
+    <dependency>
+      <groupId>org.apache.pulsar</groupId>
+      <artifactId>pulsar-client-original</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+
+```
+
+## Exclude BC-non-FIPS and include BC-FIPS
+
+After understanding the above dependencies, user can easily exclude non-FIPS version and include FIPS version.
+
+### BC-FIPS
+
+Pulsar module `bouncy-castle-bcfips`, which defined by `bouncy-castle/bcfips/pom.xml` contains the needed FIPS jars for Pulsar.
+
+```xml
+
+    <dependency>
+      <groupId>org.bouncycastle</groupId>
+      <artifactId>bc-fips</artifactId>
+      <version>${bouncycastlefips.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.bouncycastle</groupId>
+      <artifactId>bcpkix-fips</artifactId>
+      <version>${bouncycastlefips.version}</version>
+    </dependency>
+
+```
+
+User can choose include module `bouncy-castle-bcfips` module directly, or include original BC-FIPS jars. 
+
+For example:
+
+```xml
+
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>pulsar-broker</artifactId>
+      <version>${project.version}</version>
+      <exclusions>
+        <exclusion>
+          <groupId>${project.groupId}</groupId>
+          <artifactId>bouncy-castle-bc</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+
+    <!--exclude bouncy castle non-FIPS version, then load fips version-->
+    <dependency>
+      <groupId>org.bouncycastle</groupId>
+      <artifactId>bc-fips</artifactId>
+      <version>${bouncycastlefips.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.bouncycastle</groupId>
+      <artifactId>bcpkix-fips</artifactId>
+      <version>${bouncycastlefips.version}</version>
+    </dependency>
+
+```
+
+Besides this, module `bouncy-castle-bcfips` builds contain an output with format NAR, you can set java environment by `-DBcPath='nar/file/path'`, Pulsar will auto load it.
+
+For more example, you can reference module `bcfips-include-test` and `bcfips-nar-test`.
+
+
diff --git a/site2/website-next/versioned_docs/version-2.6.0/security-encryption.md b/site2/website-next/versioned_docs/version-2.6.0/security-encryption.md
new file mode 100644
index 0000000..6879ff1
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.6.0/security-encryption.md
@@ -0,0 +1,190 @@
+---
+id: security-encryption
+title: Pulsar Encryption
+sidebar_label: "End-to-End Encryption"
+original_id: security-encryption
+---
+
+Applications can use Pulsar encryption to encrypt messages at the producer side and decrypt messages at the consumer side. You can use the public and private key pair that the application configures to perform encryption. Only the consumers with a valid key can decrypt the encrypted messages.
+
+## Asymmetric and symmetric encryption
+
+Pulsar uses dynamically generated symmetric AES key to encrypt messages(data). You can use the application provided ECDSA/RSA key pair to encrypt the AES key(data key), so you do not have to share the secret with everyone.
+
+Key is a public and private key pair used for encryption or decryption. The producer key is the public key of the key pair, and the consumer key is the private key of the key pair.
+
+The application configures the producer with the public key. You can use this key to encrypt the AES data key. The encrypted data key is sent as part of message header. Only entities with the private key (in this case the consumer) are able to decrypt the data key which is used to decrypt the message.
+
+You can encrypt a message with more than one key. Any one of the keys used for encrypting the message is sufficient to decrypt the message.
+
+Pulsar does not store the encryption key anywhere in the Pulsar service. If you lose or delete the private key, your message is irretrievably lost, and is unrecoverable.
+
+## Producer
+![alt text](/assets/pulsar-encryption-producer.jpg "Pulsar Encryption Producer")
+
+## Consumer
+![alt text](/assets/pulsar-encryption-consumer.jpg "Pulsar Encryption Consumer")
+
+## Get started
+
+1. Enter the commands below to create your ECDSA or RSA public and private key pair.
+
+```shell
+
+openssl ecparam -name secp521r1 -genkey -param_enc explicit -out test_ecdsa_privkey.pem
+openssl ec -in test_ecdsa_privkey.pem -pubout -outform pem -out test_ecdsa_pubkey.pem
+
+```
+
+2. Add the public and private key to the key management and configure your producers to retrieve public keys and consumers clients to retrieve private keys.
+
+3. Implement the CryptoKeyReader interface, specifically CryptoKeyReader.getPublicKey() for producer and CryptoKeyReader.getPrivateKey() for consumer, which Pulsar client invokes to load the key.
+
+4. Add encryption key name to producer builder: PulsarClient.newProducer().addEncryptionKey("myapp.key").
+
+5. Add CryptoKeyReader implementation to producer or consumer builder: PulsarClient.newProducer().cryptoKeyReader(keyReader) / PulsarClient.newConsumer().cryptoKeyReader(keyReader).
+
+6. Sample producer application:
+
+```java
+
+class RawFileKeyReader implements CryptoKeyReader {
+
+    String publicKeyFile = "";
+    String privateKeyFile = "";
+
+    RawFileKeyReader(String pubKeyFile, String privKeyFile) {
+        publicKeyFile = pubKeyFile;
+        privateKeyFile = privKeyFile;
+    }
+
+    @Override
+    public EncryptionKeyInfo getPublicKey(String keyName, Map<String, String> keyMeta) {
+        EncryptionKeyInfo keyInfo = new EncryptionKeyInfo();
+        try {
+            keyInfo.setKey(Files.readAllBytes(Paths.get(publicKeyFile)));
+        } catch (IOException e) {
+            System.out.println("ERROR: Failed to read public key from file " + publicKeyFile);
+            e.printStackTrace();
+        }
+        return keyInfo;
+    }
+
+    @Override
+    public EncryptionKeyInfo getPrivateKey(String keyName, Map<String, String> keyMeta) {
+        EncryptionKeyInfo keyInfo = new EncryptionKeyInfo();
+        try {
+            keyInfo.setKey(Files.readAllBytes(Paths.get(privateKeyFile)));
+        } catch (IOException e) {
+            System.out.println("ERROR: Failed to read private key from file " + privateKeyFile);
+            e.printStackTrace();
+        }
+        return keyInfo;
+    }
+}
+
+PulsarClient pulsarClient = PulsarClient.builder().serviceUrl("pulsar://localhost:6650").build();
+
+Producer producer = pulsarClient.newProducer()
+                .topic("persistent://my-tenant/my-ns/my-topic")
+                .addEncryptionKey("myappkey")
+                .cryptoKeyReader(new RawFileKeyReader("test_ecdsa_pubkey.pem", "test_ecdsa_privkey.pem"))
+                .create();
+
+for (int i = 0; i < 10; i++) {
+    producer.send("my-message".getBytes());
+}
+
+producer.close();
+pulsarClient.close();
+
+```
+
+7. Sample Consumer Application:
+
+```java
+
+class RawFileKeyReader implements CryptoKeyReader {
+
+    String publicKeyFile = "";
+    String privateKeyFile = "";
+
+    RawFileKeyReader(String pubKeyFile, String privKeyFile) {
+        publicKeyFile = pubKeyFile;
+        privateKeyFile = privKeyFile;
+    }
+
+    @Override
+    public EncryptionKeyInfo getPublicKey(String keyName, Map<String, String> keyMeta) {
+        EncryptionKeyInfo keyInfo = new EncryptionKeyInfo();
+        try {
+            keyInfo.setKey(Files.readAllBytes(Paths.get(publicKeyFile)));
+        } catch (IOException e) {
+            System.out.println("ERROR: Failed to read public key from file " + publicKeyFile);
+            e.printStackTrace();
+        }
+        return keyInfo;
+    }
+
+    @Override
+    public EncryptionKeyInfo getPrivateKey(String keyName, Map<String, String> keyMeta) {
+        EncryptionKeyInfo keyInfo = new EncryptionKeyInfo();
+        try {
+            keyInfo.setKey(Files.readAllBytes(Paths.get(privateKeyFile)));
+        } catch (IOException e) {
+            System.out.println("ERROR: Failed to read private key from file " + privateKeyFile);
+            e.printStackTrace();
+        }
+        return keyInfo;
+    }
+}
+
+PulsarClient pulsarClient = PulsarClient.builder().serviceUrl("pulsar://localhost:6650").build();
+Consumer consumer = pulsarClient.newConsumer()
+                .topic("persistent://my-tenant/my-ns/my-topic")
+                .subscriptionName("my-subscriber-name")
+                .cryptoKeyReader(new RawFileKeyReader("test_ecdsa_pubkey.pem", "test_ecdsa_privkey.pem"))
+                .subscribe();
+Message msg = null;
+
+for (int i = 0; i < 10; i++) {
+    msg = consumer.receive();
+    // do something
+    System.out.println("Received: " + new String(msg.getData()));
+}
+
+// Acknowledge the consumption of all messages at once
+consumer.acknowledgeCumulative(msg);
+consumer.close();
+pulsarClient.close();
+
+```
+
+## Key rotation
+Pulsar generates a new AES data key every 4 hours or after publishing a certain number of messages. A producer fetches the asymmetric public key every 4 hours by calling CryptoKeyReader.getPublicKey() to retrieve the latest version.
+
+## Enable encryption at the producer application
+If you produce messages that are consumed across application boundaries, you need to ensure that consumers in other applications have access to one of the private keys that can decrypt the messages. You can do this in two ways:
+1. The consumer application provides you access to their public key, which you add to your producer keys.
+2. You grant access to one of the private keys from the pairs that producer uses. 
+
+When producers want to encrypt the messages with multiple keys, producers add all such keys to the config. Consumer can decrypt the message as long as the consumer has access to at least one of the keys.
+
+If you need to encrypt the messages using 2 keys (myapp.messagekey1 and myapp.messagekey2), refer to the following example.
+
+```java
+
+PulsarClient.newProducer().addEncryptionKey("myapp.messagekey1").addEncryptionKey("myapp.messagekey2");
+
+```
+
+## Decrypt encrypted messages at the consumer application
+Consumers require access one of the private keys to decrypt messages that the producer produces. If you want to receive encrypted messages, create a public or private key and give your public key to the producer application to encrypt messages using your public key.
+
+## Handle failures
+* Producer/ Consumer loses access to the key
+  * Producer action fails indicating the cause of the failure. Application has the option to proceed with sending unencrypted message in such cases. Call PulsarClient.newProducer().cryptoFailureAction(ProducerCryptoFailureAction) to control the producer behavior. The default behavior is to fail the request.
+  * If consumption fails due to decryption failure or missing keys in consumer, application has the option to consume the encrypted message or discard it. Call PulsarClient.newConsumer().cryptoFailureAction(ConsumerCryptoFailureAction) to control the consumer behavior. The default behavior is to fail the request. Application is never able to decrypt the messages if the private key is permanently lost.
+* Batch messaging
+  * If decryption fails and the message contains batch messages, client is not able to retrieve individual messages in the batch, hence message consumption fails even if cryptoFailureAction() is set to ConsumerCryptoFailureAction.CONSUME.
+* If decryption fails, the message consumption stops and application notices backlog growth in addition to decryption failure messages in the client log. If application does not have access to the private key to decrypt the message, the only option is to skip or discard backlogged messages. 
diff --git a/site2/website-next/versioned_docs/version-2.6.0/security-extending.md b/site2/website-next/versioned_docs/version-2.6.0/security-extending.md
new file mode 100644
index 0000000..57b4c6a
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.6.0/security-extending.md
@@ -0,0 +1,205 @@
+---
+id: security-extending
+title: Extending Authentication and Authorization in Pulsar
+sidebar_label: "Extending"
+original_id: security-extending
+---
+
+Pulsar provides a way to use custom authentication and authorization mechanisms.
+
+## Authentication
+
+Pulsar supports mutual TLS and Athenz authentication plugins. For how to use these authentication plugins, you can refer to the description in [Security](security-overview).
+
+You can choose to use a custom authentication mechanism by providing the implementation in the form of two plugins. One plugin is for the Client library and the other plugin is for the Pulsar Broker to validate the credentials.
+
+### Client authentication plugin
+
+For client library, you need to implement `org.apache.pulsar.client.api.Authentication`. By entering the command below you can pass this class when you create a Pulsar client:
+
+```java
+
+PulsarClient client = PulsarClient.builder()
+    .serviceUrl("pulsar://localhost:6650")
+    .authentication(new MyAuthentication())
+    .build();
+
+```
+
+You can use 2 interfaces to implement on the client side:
+ * `Authentication` -> http://pulsar.apache.org/api/client/org/apache/pulsar/client/api/Authentication.html
+ * `AuthenticationDataProvider` -> http://pulsar.apache.org/api/client/org/apache/pulsar/client/api/AuthenticationDataProvider.html
+
+
+This in turn needs to provide the client credentials in the form of `org.apache.pulsar.client.api.AuthenticationDataProvider`. This leaves the chance to return different kinds of authentication token for different types of connection or by passing a certificate chain to use for TLS.
+
+
+You can find examples for client authentication providers at:
+
+ * Mutual TLS Auth -- https://github.com/apache/pulsar/tree/master/pulsar-client/src/main/java/org/apache/pulsar/client/impl/auth
+ * Athenz -- https://github.com/apache/pulsar/tree/master/pulsar-client-auth-athenz/src/main/java/org/apache/pulsar/client/impl/auth
+
+### Broker authentication plugin
+
+On broker side, you need the corresponding plugin to validate the credentials that the client passes. Broker can support multiple authentication providers at the same time.
+
+In `conf/broker.conf` you can choose to specify a list of valid providers:
+
+```properties
+
+# Authentication provider name list, which is comma separated list of class names
+authenticationProviders=
+
+```
+
+To implement `org.apache.pulsar.broker.authentication.AuthenticationProvider` on one single interface:
+
+```java
+
+/**
+ * Provider of authentication mechanism
+ */
+public interface AuthenticationProvider extends Closeable {
+
+    /**
+     * Perform initialization for the authentication provider
+     *
+     * @param config
+     *            broker config object
+     * @throws IOException
+     *             if the initialization fails
+     */
+    void initialize(ServiceConfiguration config) throws IOException;
+
+    /**
+     * @return the authentication method name supported by this provider
+     */
+    String getAuthMethodName();
+
+    /**
+     * Validate the authentication for the given credentials with the specified authentication data
+     *
+     * @param authData
+     *            provider specific authentication data
+     * @return the "role" string for the authenticated connection, if the authentication was successful
+     * @throws AuthenticationException
+     *             if the credentials are not valid
+     */
+    String authenticate(AuthenticationDataSource authData) throws AuthenticationException;
+
+}
+
+```
+
+The following is the example for Broker authentication plugins:
+
+ * Mutual TLS -- https://github.com/apache/pulsar/blob/master/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProviderTls.java
+ * Athenz -- https://github.com/apache/pulsar/blob/master/pulsar-broker-auth-athenz/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProviderAthenz.java
+
+## Authorization
+
+Authorization is the operation that checks whether a particular "role" or "principal" has a permission to perform a certain operation.
+
+By default, Pulsar provides an embedded authorization, though configuring a different one through a plugin is also an alternative choice.
+
+To provide a custom provider, you need to implement the `org.apache.pulsar.broker.authorization.AuthorizationProvider` interface, put this class in the Pulsar broker classpath and configure the class in `conf/broker.conf`:
+
+ ```properties
+ 
+ # Authorization provider fully qualified class-name
+ authorizationProvider=org.apache.pulsar.broker.authorization.PulsarAuthorizationProvider
+ 
+ ```
+
+```java
+
+/**
+ * Provider of authorization mechanism
+ */
+public interface AuthorizationProvider extends Closeable {
+
+    /**
+     * Perform initialization for the authorization provider
+     *
+     * @param config
+     *            broker config object
+     * @param configCache
+     *            pulsar zk configuration cache service
+     * @throws IOException
+     *             if the initialization fails
+     */
+    void initialize(ServiceConfiguration conf, ConfigurationCacheService configCache) throws IOException;
+
+    /**
+     * Check if the specified role has permission to send messages to the specified fully qualified topic name.
+     *
+     * @param topicName
+     *            the fully qualified topic name associated with the topic.
+     * @param role
+     *            the app id used to send messages to the topic.
+     */
+    CompletableFuture<Boolean> canProduceAsync(TopicName topicName, String role,
+            AuthenticationDataSource authenticationData);
+
+    /**
+     * Check if the specified role has permission to receive messages from the specified fully qualified topic name.
+     *
+     * @param topicName
+     *            the fully qualified topic name associated with the topic.
+     * @param role
+     *            the app id used to receive messages from the topic.
+     * @param subscription
+     *            the subscription name defined by the client
+     */
+    CompletableFuture<Boolean> canConsumeAsync(TopicName topicName, String role,
+            AuthenticationDataSource authenticationData, String subscription);
+
+    /**
+     * Check whether the specified role can perform a lookup for the specified topic.
+     *
+     * For that the caller needs to have producer or consumer permission.
+     *
+     * @param topicName
+     * @param role
+     * @return
+     * @throws Exception
+     */
+    CompletableFuture<Boolean> canLookupAsync(TopicName topicName, String role,
+            AuthenticationDataSource authenticationData);
+
+    /**
+     *
+     * Grant authorization-action permission on a namespace to the given client
+     *
+     * @param namespace
+     * @param actions
+     * @param role
+     * @param authDataJson
+     *            additional authdata in json format
+     * @return CompletableFuture
+     * @completesWith <br />
+     *                IllegalArgumentException when namespace not found<br />
+     *                IllegalStateException when failed to grant permission
+     */
+    CompletableFuture<Void> grantPermissionAsync(NamespaceName namespace, Set<AuthAction> actions, String role,
+            String authDataJson);
+
+    /**
+     * Grant authorization-action permission on a topic to the given client
+     *
+     * @param topicName
+     * @param role
+     * @param authDataJson
+     *            additional authdata in json format
+     * @return CompletableFuture
+     * @completesWith <br />
+     *                IllegalArgumentException when namespace not found<br />
+     *                IllegalStateException when failed to grant permission
+     */
+    CompletableFuture<Void> grantPermissionAsync(TopicName topicName, Set<AuthAction> actions, String role,
+            String authDataJson);
+
+}
+
+```
+
diff --git a/site2/website-next/versioned_docs/version-2.6.0/security-jwt.md b/site2/website-next/versioned_docs/version-2.6.0/security-jwt.md
new file mode 100644
index 0000000..b0f7755
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.6.0/security-jwt.md
@@ -0,0 +1,323 @@
+---
+id: security-jwt
+title: Client authentication using tokens based on JSON Web Tokens
+sidebar_label: "Authentication using JWT"
+original_id: security-jwt
+---
+
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+
+## Token authentication overview
+
+Pulsar supports authenticating clients using security tokens that are based on [JSON Web Tokens](https://jwt.io/introduction/) ([RFC-7519](https://tools.ietf.org/html/rfc7519)).
+
+You can use tokens to identify a Pulsar client and associate with some "principal" (or "role") that
+is permitted to do some actions (eg: publish to a topic or consume from a topic).
+
+A user typically gets a token string from the administrator (or some automated service).
+
+The compact representation of a signed JWT is a string that looks like as the following:
+
+```
+
+eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJKb2UifQ.ipevRNuRP6HflG8cFKnmUPtypruRC4fb1DWtoLL62SY
+
+```
+
+Application specifies the token when you create the client instance. An alternative is to pass a "token supplier" (a function that returns the token when the client library needs one).
+
+> #### Always use TLS transport encryption
+> Sending a token is equivalent to sending a password over the wire. You had better use TLS encryption all the time when you connect to the Pulsar service. See
+> [Transport Encryption using TLS](security-tls-transport) for more details.
+
+### CLI Tools
+
+[Command-line tools](reference-cli-tools.md) like [`pulsar-admin`](reference-pulsar-admin), [`pulsar-perf`](reference-cli-tools.md#pulsar-perf), and [`pulsar-client`](reference-cli-tools.md#pulsar-client) use the `conf/client.conf` config file in a Pulsar installation.
+
+You need to add the following parameters to that file to use the token authentication with CLI tools of Pulsar:
+
+```properties
+
+webServiceUrl=http://broker.example.com:8080/
+brokerServiceUrl=pulsar://broker.example.com:6650/
+authPlugin=org.apache.pulsar.client.impl.auth.AuthenticationToken
+authParams=token:eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJKb2UifQ.ipevRNuRP6HflG8cFKnmUPtypruRC4fb1DWtoLL62SY
+
+```
+
+The token string can also be read from a file, for example:
+
+```
+
+authParams=file:///path/to/token/file
+
+```
+
+### Pulsar client
+
+You can use tokens to authenticate the following Pulsar clients.
+
+<Tabs 
+  defaultValue="Java"
+  values={[{"label":"Java","value":"Java"},{"label":"Python","value":"Python"},{"label":"Go","value":"Go"},{"label":"C++","value":"C++"},{"label":"C#","value":"C#"}]}>
+<TabItem value="Java">
+
+```java
+
+PulsarClient client = PulsarClient.builder()
+    .serviceUrl("pulsar://broker.example.com:6650/")
+    .authentication(
+        AuthenticationFactory.token("eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJKb2UifQ.ipevRNuRP6HflG8cFKnmUPtypruRC4fb1DWtoLL62SY"))
+    .build();
+
+```
+
+Similarly, you can also pass a `Supplier`:
+
+```java
+
+PulsarClient client = PulsarClient.builder()
+    .serviceUrl("pulsar://broker.example.com:6650/")
+    .authentication(
+        AuthenticationFactory.token(() -> {
+            // Read token from custom source
+            return readToken();
+        }))
+    .build();
+
+```
+
+</TabItem>
+<TabItem value="Python">
+
+```python
+
+from pulsar import Client, AuthenticationToken
+
+client = Client('pulsar://broker.example.com:6650/'
+                authentication=AuthenticationToken('eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJKb2UifQ.ipevRNuRP6HflG8cFKnmUPtypruRC4fb1DWtoLL62SY'))
+
+```
+
+Alternatively, you can also pass a `Supplier`:
+
+```python
+
+def read_token():
+    with open('/path/to/token.txt') as tf:
+        return tf.read().strip()
+
+client = Client('pulsar://broker.example.com:6650/'
+                authentication=AuthenticationToken(read_token))
+
+```
+
+</TabItem>
+<TabItem value="Go">
+
+```go
+
+client, err := NewClient(ClientOptions{
+	URL:            "pulsar://localhost:6650",
+	Authentication: NewAuthenticationToken("eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJKb2UifQ.ipevRNuRP6HflG8cFKnmUPtypruRC4fb1DWtoLL62SY"),
+})
+
+```
+
+Similarly, you can also pass a `Supplier`:
+
+```go
+
+client, err := NewClient(ClientOptions{
+	URL:            "pulsar://localhost:6650",
+	Authentication: NewAuthenticationTokenSupplier(func () string {
+        // Read token from custom source
+		return readToken()
+	}),
+})
+
+```
+
+</TabItem>
+<TabItem value="C++">
+
+```c++
+
+#include <pulsar/Client.h>
+
+pulsar::ClientConfiguration config;
+config.setAuth(pulsar::AuthToken::createWithToken("eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJKb2UifQ.ipevRNuRP6HflG8cFKnmUPtypruRC4fb1DWtoLL62SY"));
+
+pulsar::Client client("pulsar://broker.example.com:6650/", config);
+
+```
+
+</TabItem>
+<TabItem value="C#">
+
+```c#
+
+var client = PulsarClient.Builder()
+                         .AuthenticateUsingToken("eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJKb2UifQ.ipevRNuRP6HflG8cFKnmUPtypruRC4fb1DWtoLL62SY")
+                         .Build();
+
+```
+
+</TabItem>
+
+</Tabs>
+
+## Enable token authentication 
+
+On how to enable token authentication on a Pulsar cluster, you can refer to the guide below.
+
+JWT supports two different kinds of keys in order to generate and validate the tokens:
+
+ * Symmetric :
+    - You can use a single ***Secret*** key to generate and validate tokens.
+ * Asymmetric: A pair of keys consists of the Private key and the Public key.
+    - You can use ***Private*** key to generate tokens.
+    - You can use ***Public*** key to validate tokens.
+
+### Create a secret key
+
+When you use a secret key, the administrator creates the key and uses the key to generate the client tokens. You can also configure this key to brokers in order to validate the clients.
+
+Output file is generated in the root of your Pulsar installation directory. You can also provide absolute path for the output file using the command below.
+
+```shell
+
+$ bin/pulsar tokens create-secret-key --output my-secret.key
+
+```
+
+Enter this command to generate base64 encoded private key.
+
+```shell
+
+$ bin/pulsar tokens create-secret-key --output  /opt/my-secret.key --base64
+
+```
+
+### Create a key pair
+
+With Public and Private keys, you need to create a pair of keys. Pulsar supports all algorithms that the Java JWT library (shown [here](https://github.com/jwtk/jjwt#signature-algorithms-keys)) supports.
+
+Output file is generated in the root of your Pulsar installation directory. You can also provide absolute path for the output file using the command below.
+
+```shell
+
+$ bin/pulsar tokens create-key-pair --output-private-key my-private.key --output-public-key my-public.key
+
+```
+
+ * Store `my-private.key` in a safe location and only administrator can use `my-private.key` to generate new tokens.
+ * `my-public.key` is distributed to all Pulsar brokers. You can publicly share this file without any security concern.
+
+### Generate tokens
+
+A token is the credential associated with a user. The association is done through the "principal" or "role". In the case of JWT tokens, this field is typically referred as **subject**, though they are exactly the same concept.
+
+Then, you need to use this command to require the generated token to have a **subject** field set.
+
+```shell
+
+$ bin/pulsar tokens create --secret-key file:///path/to/my-secret.key \
+            --subject test-user
+
+```
+
+This command prints the token string on stdout.
+
+Similarly, you can create a token by passing the "private" key using the command below:
+
+```shell
+
+$ bin/pulsar tokens create --private-key file:///path/to/my-private.key \
+            --subject test-user
+
+```
+
+Finally, you can enter the following command to create a token with a pre-defined TTL. And then the token is automatically invalidated.
+
+```shell
+
+$ bin/pulsar tokens create --secret-key file:///path/to/my-secret.key \
+            --subject test-user \
+            --expiry-time 1y
+
+```
+
+### Authorization
+
+The token itself does not have any permission associated. The authorization engine determines whether the token should have permissions or not. Once you have created the token, you can grant permission for this token to do certain actions. The following is an example.
+
+```shell
+
+$ bin/pulsar-admin namespaces grant-permission my-tenant/my-namespace \
+            --role test-user \
+            --actions produce,consume
+
+```
+
+### Enable token authentication on Brokers
+
+To configure brokers to authenticate clients, add the following parameters to `broker.conf`:
+
+```properties
+
+# Configuration to enable authentication and authorization
+authenticationEnabled=true
+authorizationEnabled=true
+authenticationProviders=org.apache.pulsar.broker.authentication.AuthenticationProviderToken
+
+# Authentication settings of the broker itself. Used when the broker connects to other brokers, either in same or other clusters
+brokerClientTlsEnabled=true
+brokerClientAuthenticationPlugin=org.apache.pulsar.client.impl.auth.AuthenticationToken
+brokerClientAuthenticationParameters=token:eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0LXVzZXIifQ.9OHgE9ZUDeBTZs7nSMEFIuGNEX18FLR3qvy8mqxSxXw
+# Or, alternatively, read token from file
+# brokerClientAuthenticationParameters=file:///path/to/proxy-token.txt
+brokerClientTrustCertsFilePath=/path/my-ca/certs/ca.cert.pem
+
+# If this flag is set then the broker authenticates the original Auth data
+# else it just accepts the originalPrincipal and authorizes it (if required).
+authenticateOriginalAuthData=true
+
+# If using secret key
+tokenSecretKey=file:///path/to/secret.key
+# The key can also be passed inline:
+# tokenSecretKey=data:;base64,FLFyW0oLJ2Fi22KKCm21J18mbAdztfSHN/lAT5ucEKU=
+
+# If using public/private
+# tokenPublicKey=file:///path/to/public.key
+
+```
+
+### Enable token authentication on Proxies
+
+To configure proxies to authenticate clients, add the following parameters to `proxy.conf`:
+
+The proxy uses its own token when connecting to brokers. You need to configure the role token for this key pair in the `proxyRoles` of the brokers. For more details, see the [authorization guide](security-authorization).
+
+```properties
+
+# For clients connecting to the proxy
+authenticationEnabled=true
+authorizationEnabled=true
+authenticationProviders=org.apache.pulsar.broker.authentication.AuthenticationProviderToken
+tokenSecretKey=file:///path/to/secret.key
+
+# For the proxy to connect to brokers
+brokerClientAuthenticationPlugin=org.apache.pulsar.client.impl.auth.AuthenticationToken
+brokerClientAuthenticationParameters=token:eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0LXVzZXIifQ.9OHgE9ZUDeBTZs7nSMEFIuGNEX18FLR3qvy8mqxSxXw
+# Or, alternatively, read token from file
+# brokerClientAuthenticationParameters=file:///path/to/proxy-token.txt
+
+# Whether client authorization credentials are forwarded to the broker for re-authorization.
+# Authentication must be enabled via authenticationEnabled=true for this to take effect.
+forwardAuthorizationCredentials=true
+
+```
+
diff --git a/site2/website-next/versioned_docs/version-2.6.0/security-kerberos.md b/site2/website-next/versioned_docs/version-2.6.0/security-kerberos.md
new file mode 100644
index 0000000..670586a
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.6.0/security-kerberos.md
@@ -0,0 +1,443 @@
+---
+id: security-kerberos
+title: Authentication using Kerberos
+sidebar_label: "Authentication using Kerberos"
+original_id: security-kerberos
+---
+
+[Kerberos](https://web.mit.edu/kerberos/) is a network authentication protocol. By using secret-key cryptography, [Kerberos](https://web.mit.edu/kerberos/) is designed to provide strong authentication for client applications and server applications. 
+
+In Pulsar, you can use Kerberos with [SASL](https://en.wikipedia.org/wiki/Simple_Authentication_and_Security_Layer) as a choice for authentication. And Pulsar uses the [Java Authentication and Authorization Service (JAAS)](https://en.wikipedia.org/wiki/Java_Authentication_and_Authorization_Service) for SASL configuration. You need to provide JAAS configurations for Kerberos authentication. 
+
+This document introduces how to configure `Kerberos` with `SASL` between Pulsar clients and brokers and how to configure Kerberos for Pulsar proxy in detail.
+
+## Configuration for Kerberos between Client and Broker
+
+### Prerequisites
+
+To begin, you need to set up (or already have) a [Key Distribution Center(KDC)](https://en.wikipedia.org/wiki/Key_distribution_center). Also you need to configure and run the [Key Distribution Center(KDC)](https://en.wikipedia.org/wiki/Key_distribution_center)in advance. 
+
+If your organization already uses a Kerberos server (for example, by using `Active Directory`), you do not have to install a new server for Pulsar. If your organization does not use a Kerberos server, you need to install one. Your Linux vendor might have packages for `Kerberos`. On how to install and configure Kerberos, refer to [Ubuntu](https://help.ubuntu.com/community/Kerberos), 
+[Redhat](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Managing_Smart_Cards/installing-kerberos.html).
+
+Note that if you use Oracle Java, you need to download JCE policy files for your Java version and copy them to the `$JAVA_HOME/jre/lib/security` directory.
+
+#### Kerberos principals
+
+If you use the existing Kerberos system, ask your Kerberos administrator for a principal for each Brokers in your cluster and for every operating system user that accesses Pulsar with Kerberos authentication(via clients and tools).
+
+If you have installed your own Kerberos system, you can create these principals with the following commands:
+
+```shell
+
+### add Principals for broker
+sudo /usr/sbin/kadmin.local -q 'addprinc -randkey broker/{hostname}@{REALM}'
+sudo /usr/sbin/kadmin.local -q "ktadd -k /etc/security/keytabs/{broker-keytabname}.keytab broker/{hostname}@{REALM}"
+### add Principals for client
+sudo /usr/sbin/kadmin.local -q 'addprinc -randkey client/{hostname}@{REALM}'
+sudo /usr/sbin/kadmin.local -q "ktadd -k /etc/security/keytabs/{client-keytabname}.keytab client/{hostname}@{REALM}"
+
+```
+
+Note that *Kerberos* requires that all your hosts can be resolved with their FQDNs.
+
+The first part of Broker principal (for example, `broker` in `broker/{hostname}@{REALM}`) is the `serverType` of each host. The suggested values of `serverType` are `broker` (host machine runs service Pulsar Broker) and `proxy` (host machine runs service Pulsar Proxy). 
+
+#### Configure how to connect to KDC
+
+You need to enter the command below to specify the path to the `krb5.conf` file for the client side and the broker side. The content of `krb5.conf` file indicates the default Realm and KDC information. See [JDK’s Kerberos Requirements](https://docs.oracle.com/javase/8/docs/technotes/guides/security/jgss/tutorials/KerberosReq.html) for more details.
+
+```shell
+
+-Djava.security.krb5.conf=/etc/pulsar/krb5.conf
+
+```
+
+Here is an example of the krb5.conf file:
+ 
+In the configuration file, `EXAMPLE.COM` is the default realm; `kdc = localhost:62037` is the kdc server url for realm `EXAMPLE.COM `:
+
+```
+
+[libdefaults]
+ default_realm = EXAMPLE.COM
+
+[realms]
+ EXAMPLE.COM  = {
+  kdc = localhost:62037
+ }
+
+```
+
+Usually machines configured with kerberos already have a system wide configuration and this configuration is optional.
+
+#### JAAS configuration file
+
+You need JAAS configuration file for the client side and the broker side. JAAS configuration file provides the section of information that is used to connect KDC. Here is an example named `pulsar_jaas.conf`:
+
+```
+
+ PulsarBroker {
+   com.sun.security.auth.module.Krb5LoginModule required
+   useKeyTab=true
+   storeKey=true
+   useTicketCache=false
+   keyTab="/etc/security/keytabs/pulsarbroker.keytab"
+   principal="broker/localhost@EXAMPLE.COM";
+};
+
+ PulsarClient {
+   com.sun.security.auth.module.Krb5LoginModule required
+   useKeyTab=true
+   storeKey=true
+   useTicketCache=false
+   keyTab="/etc/security/keytabs/pulsarclient.keytab"
+   principal="client/localhost@EXAMPLE.COM";
+};
+
+```
+
+You need to set the `JAAS` configuration file path as JVM parameter for client and broker. For example:
+
+```shell
+
+    -Djava.security.auth.login.config=/etc/pulsar/pulsar_jaas.conf
+
+```
+
+In the `pulsar_jaas.conf` file above 
+
+1. `PulsarBroker` is a section name in the JAAS file that each broker uses. This section tells the broker to use which principal inside Kerberos and the location of the keytab where the principal is stored. `PulsarBroker` allows the broker to use the keytab specified in this section.
+2. `PulsarClient` is a section name in the JASS file that each broker uses. This section tells the client to use which principal inside Kerberos and the location of the keytab where the principal is stored. `PulsarClient` allows the client to use the keytab specified in this section.
+   The following example also reuses this `PulsarClient` section in both the Pulsar internal admin configuration and in CLI command of `bin/pulsar-client`, `bin/pulsar-perf` and `bin/pulsar-admin`. You can also add different sections for different use cases.
+
+You can have 2 separate JAAS configuration files: 
+* the file for a broker that has sections of both `PulsarBroker` and `PulsarClient`; 
+* the file for a client that only has a `PulsarClient` section.
+
+
+### Kerberos configuration for Brokers
+
+#### Configure the `broker.conf` file
+ 
+ In the `broker.conf` file, set Kerberos related configurations.
+
+ - Set `authenticationEnabled` to `true`;
+ - Set `authenticationProviders` to choose `AuthenticationProviderSasl`;
+ - Set `saslJaasClientAllowedIds` regex for principal that is allowed to connect to broker;
+ - Set `saslJaasBrokerSectionName` that corresponds to the section in JAAS configuration file for broker;
+ 
+ To make Pulsar internal admin client work properly, you need to set the configuration in the `broker.conf` file as below: 
+ - Set `brokerClientAuthenticationPlugin` to client plugin `AuthenticationSasl`;
+ - Set `brokerClientAuthenticationParameters` to value in JSON string `{"saslJaasClientSectionName":"PulsarClient", "serverType":"broker"}`, in which `PulsarClient` is the section name in the `pulsar_jaas.conf` file, and `"serverType":"broker"` indicates that the internal admin client connects to a Pulsar Broker;
+
+ Here is an example:
+
+```
+
+authenticationEnabled=true
+authenticationProviders=org.apache.pulsar.broker.authentication.AuthenticationProviderSasl
+saslJaasClientAllowedIds=.*client.*
+saslJaasBrokerSectionName=PulsarBroker
+
+## Authentication settings of the broker itself. Used when the broker connects to other brokers
+brokerClientAuthenticationPlugin=org.apache.pulsar.client.impl.auth.AuthenticationSasl
+brokerClientAuthenticationParameters={"saslJaasClientSectionName":"PulsarClient", "serverType":"broker"}
+
+```
+
+#### Set Broker JVM parameter
+
+ Set JVM parameters for JAAS configuration file and krb5 configuration file with additional options.
+
+```shell
+
+   -Djava.security.auth.login.config=/etc/pulsar/pulsar_jaas.conf -Djava.security.krb5.conf=/etc/pulsar/krb5.conf
+
+```
+
+You can add this at the end of `PULSAR_EXTRA_OPTS` in the file [`pulsar_env.sh`](https://github.com/apache/pulsar/blob/master/conf/pulsar_env.sh)
+
+You must ensure that the operating system user who starts broker can reach the keytabs configured in the `pulsar_jaas.conf` file and kdc server in the `krb5.conf` file.
+
+### Kerberos configuration for clients
+
+#### Java Client and Java Admin Client
+
+In client application, include `pulsar-client-auth-sasl` in your project dependency.
+
+```
+
+    <dependency>
+      <groupId>org.apache.pulsar</groupId>
+      <artifactId>pulsar-client-auth-sasl</artifactId>
+      <version>${pulsar.version}</version>
+    </dependency>
+
+```
+
+Configure the authentication type to use `AuthenticationSasl`, and also provide the authentication parameters to it. 
+
+You need 2 parameters: 
+- `saslJaasClientSectionName`. This parameter corresponds to the section in JAAS configuration file for client; 
+- `serverType`. This parameter stands for whether this client connects to broker or proxy. And client uses this parameter to know which server side principal should be used. 
+
+When you authenticate between client and broker with the setting in above JAAS configuration file, we need to set `saslJaasClientSectionName` to `PulsarClient` and set `serverType` to `broker`.
+
+The following is an example of creating a Java client:
+
+ ```java
+ 
+ System.setProperty("java.security.auth.login.config", "/etc/pulsar/pulsar_jaas.conf");
+ System.setProperty("java.security.krb5.conf", "/etc/pulsar/krb5.conf");
+
+ Map<String, String> authParams = Maps.newHashMap();
+ authParams.put("saslJaasClientSectionName", "PulsarClient");
+ authParams.put("serverType", "broker");
+
+ Authentication saslAuth = AuthenticationFactory
+         .create(org.apache.pulsar.client.impl.auth.AuthenticationSasl.class.getName(), authParams);
+ 
+ PulsarClient client = PulsarClient.builder()
+         .serviceUrl("pulsar://my-broker.com:6650")
+         .authentication(saslAuth)
+         .build();
+ 
+ ```
+
+> The first two lines in the example above are hard coded, alternatively, you can set additional JVM parameters for JAAS and krb5 configuration file when you run the application like below:
+
+```
+
+java -cp -Djava.security.auth.login.config=/etc/pulsar/pulsar_jaas.conf -Djava.security.krb5.conf=/etc/pulsar/krb5.conf $APP-jar-with-dependencies.jar $CLASSNAME
+
+```
+
+You must ensure that the operating system user who starts pulsar client can reach the keytabs configured in the `pulsar_jaas.conf` file and kdc server in the `krb5.conf` file.
+
+#### Configure CLI tools
+
+If you use a command-line tool (such as `bin/pulsar-client`, `bin/pulsar-perf` and `bin/pulsar-admin`), you need to perform the following steps:
+
+Step 1. Enter the command below to configure your `client.conf`.
+
+```shell
+
+authPlugin=org.apache.pulsar.client.impl.auth.AuthenticationSasl
+authParams={"saslJaasClientSectionName":"PulsarClient", "serverType":"broker"}
+
+```
+
+Step 2. Enter the command below to set JVM parameters for JAAS configuration file and krb5 configuration file with additional options.
+
+```shell
+
+   -Djava.security.auth.login.config=/etc/pulsar/pulsar_jaas.conf -Djava.security.krb5.conf=/etc/pulsar/krb5.conf
+
+```
+
+You can add this at the end of `PULSAR_EXTRA_OPTS` in the file [`pulsar_tools_env.sh`](https://github.com/apache/pulsar/blob/master/conf/pulsar_tools_env.sh),
+or add this line `OPTS="$OPTS -Djava.security.auth.login.config=/etc/pulsar/pulsar_jaas.conf -Djava.security.krb5.conf=/etc/pulsar/krb5.conf "` directly to the CLI tool script.
+
+The meaning of configurations is the same as the meaning of configurations in Java client section.
+
+##  Kerberos configuration for working with Pulsar Proxy
+
+With the above configuration, client and broker can do authentication using Kerberos.  
+
+A client that connects to Pulsar Proxy is a little different. Pulsar Proxy (as a SASL Server in Kerberos) authenticates Client (as a SASL client in Kerberos) first; and then Pulsar broker authenticates Pulsar Proxy. 
+
+Now in comparison with the above configuration between client and broker, we show you how to configure Pulsar Proxy as follows. 
+
+### Create principal for Pulsar Proxy in Kerberos
+
+You need to add new principals for Pulsar Proxy comparing with the above configuration. If you already have principals for client and broker, you only need to add the proxy principal here.
+
+```shell
+
+### add Principals for Pulsar Proxy
+sudo /usr/sbin/kadmin.local -q 'addprinc -randkey proxy/{hostname}@{REALM}'
+sudo /usr/sbin/kadmin.local -q "ktadd -k /etc/security/keytabs/{proxy-keytabname}.keytab proxy/{hostname}@{REALM}"
+### add Principals for broker
+sudo /usr/sbin/kadmin.local -q 'addprinc -randkey broker/{hostname}@{REALM}'
+sudo /usr/sbin/kadmin.local -q "ktadd -k /etc/security/keytabs/{broker-keytabname}.keytab broker/{hostname}@{REALM}"
+### add Principals for client
+sudo /usr/sbin/kadmin.local -q 'addprinc -randkey client/{hostname}@{REALM}'
+sudo /usr/sbin/kadmin.local -q "ktadd -k /etc/security/keytabs/{client-keytabname}.keytab client/{hostname}@{REALM}"
+
+```
+
+### Add a section in JAAS configuration file for Pulsar Proxy
+
+In comparison with the above configuration, add a new section for Pulsar Proxy in JAAS configuration file.
+
+Here is an example named `pulsar_jaas.conf`:
+
+```
+
+ PulsarBroker {
+   com.sun.security.auth.module.Krb5LoginModule required
+   useKeyTab=true
+   storeKey=true
+   useTicketCache=false
+   keyTab="/etc/security/keytabs/pulsarbroker.keytab"
+   principal="broker/localhost@EXAMPLE.COM";
+};
+
+ PulsarProxy {
+   com.sun.security.auth.module.Krb5LoginModule required
+   useKeyTab=true
+   storeKey=true
+   useTicketCache=false
+   keyTab="/etc/security/keytabs/pulsarproxy.keytab"
+   principal="proxy/localhost@EXAMPLE.COM";
+};
+
+ PulsarClient {
+   com.sun.security.auth.module.Krb5LoginModule required
+   useKeyTab=true
+   storeKey=true
+   useTicketCache=false
+   keyTab="/etc/security/keytabs/pulsarclient.keytab"
+   principal="client/localhost@EXAMPLE.COM";
+};
+
+```
+
+### Proxy client configuration
+
+Pulsar client configuration is similar with client and broker configuration, except that you need to set `serverType` to `proxy` instead of `broker`, for the reason that you need to do the Kerberos authentication between client and proxy.
+
+ ```java
+ 
+ System.setProperty("java.security.auth.login.config", "/etc/pulsar/pulsar_jaas.conf");
+ System.setProperty("java.security.krb5.conf", "/etc/pulsar/krb5.conf");
+
+ Map<String, String> authParams = Maps.newHashMap();
+ authParams.put("saslJaasClientSectionName", "PulsarClient");
+ authParams.put("serverType", "proxy");        // ** here is the different **
+
+ Authentication saslAuth = AuthenticationFactory
+         .create(org.apache.pulsar.client.impl.auth.AuthenticationSasl.class.getName(), authParams);
+ 
+ PulsarClient client = PulsarClient.builder()
+         .serviceUrl("pulsar://my-broker.com:6650")
+         .authentication(saslAuth)
+         .build();
+ 
+ ```
+
+> The first two lines in the example above are hard coded, alternatively, you can set additional JVM parameters for JAAS and krb5 configuration file when you run the application like below:
+
+```
+
+java -cp -Djava.security.auth.login.config=/etc/pulsar/pulsar_jaas.conf -Djava.security.krb5.conf=/etc/pulsar/krb5.conf $APP-jar-with-dependencies.jar $CLASSNAME
+
+```
+
+### Kerberos configuration for Pulsar proxy service
+
+In the `proxy.conf` file, set Kerberos related configuration. Here is an example:
+
+```shell
+
+## related to authenticate client.
+authenticationEnabled=true
+authenticationProviders=org.apache.pulsar.broker.authentication.AuthenticationProviderSasl
+saslJaasClientAllowedIds=.*client.*
+saslJaasBrokerSectionName=PulsarProxy
+
+## related to be authenticated by broker
+brokerClientAuthenticationPlugin=org.apache.pulsar.client.impl.auth.AuthenticationSasl
+brokerClientAuthenticationParameters={"saslJaasClientSectionName":"PulsarProxy", "serverType":"broker"}
+forwardAuthorizationCredentials=true
+
+```
+
+The first part relates to authenticating between client and Pulsar Proxy. In this phase, client works as SASL client, while Pulsar Proxy works as SASL server. 
+
+The second part relates to authenticating between Pulsar Proxy and Pulsar Broker. In this phase, Pulsar Proxy works as SASL client, while Pulsar Broker works as SASL server.
+
+### Broker side configuration.
+
+The broker side configuration file is the same with the above `broker.conf`, you do not need special configuration for Pulsar Proxy.
+
+```
+
+authenticationEnabled=true
+authenticationProviders=org.apache.pulsar.broker.authentication.AuthenticationProviderSasl
+saslJaasClientAllowedIds=.*client.*
+saslJaasBrokerSectionName=PulsarBroker
+
+```
+
+## Regarding authorization and role token
+
+For Kerberos authentication, we usually use the authenticated principal as the role token for Pulsar authorization. For more information of authorization in Pulsar, see [security authorization](security-authorization).
+
+If you enable 'authorizationEnabled', you need to set `superUserRoles` in `broker.conf` that corresponds to the name registered in kdc.
+
+For example:
+
+```bash
+
+superUserRoles=client/{clientIp}@EXAMPLE.COM
+
+```
+
+## Regarding authentication between ZooKeeper and Broker
+
+Pulsar Broker acts as a Kerberos client when you authenticate with Zookeeper. According to [ZooKeeper document](https://cwiki.apache.org/confluence/display/ZOOKEEPER/Client-Server+mutual+authentication), you need these settings in `conf/zookeeper.conf`:
+
+```
+
+authProvider.1=org.apache.zookeeper.server.auth.SASLAuthenticationProvider
+requireClientAuthScheme=sasl
+
+```
+
+Enter the following commands to add a section of `Client` configurations in the file `pulsar_jaas.conf`, which Pulsar Broker uses:
+
+```
+
+ Client {
+   com.sun.security.auth.module.Krb5LoginModule required
+   useKeyTab=true
+   storeKey=true
+   useTicketCache=false
+   keyTab="/etc/security/keytabs/pulsarbroker.keytab"
+   principal="broker/localhost@EXAMPLE.COM";
+};
+
+```
+
+In this setting, the principal of Pulsar Broker and keyTab file indicates the role of Broker when you authenticate with ZooKeeper.
+
+## Regarding authentication between BookKeeper and Broker
+
+Pulsar Broker acts as a Kerberos client when you authenticate with Bookie. According to [BookKeeper document](http://bookkeeper.apache.org/docs/latest/security/sasl/), you need to add `bookkeeperClientAuthenticationPlugin` parameter in `broker.conf`:
+
+```
+
+bookkeeperClientAuthenticationPlugin=org.apache.bookkeeper.sasl.SASLClientProviderFactory
+
+```
+
+In this setting, `SASLClientProviderFactory` creates a BookKeeper SASL client in a Broker, and the Broker uses the created SASL client to authenticate with a Bookie node.
+
+Enter the following commands to add a section of `BookKeeper` configurations in the `pulsar_jaas.conf` that Pulsar Broker uses:
+
+```
+
+ BookKeeper {
+   com.sun.security.auth.module.Krb5LoginModule required
+   useKeyTab=true
+   storeKey=true
+   useTicketCache=false
+   keyTab="/etc/security/keytabs/pulsarbroker.keytab"
+   principal="broker/localhost@EXAMPLE.COM";
+};
+
+```
+
+In this setting, the principal of Pulsar Broker and keyTab file indicates the role of Broker when you authenticate with Bookie.
diff --git a/site2/website-next/versioned_docs/version-2.6.0/security-overview.md b/site2/website-next/versioned_docs/version-2.6.0/security-overview.md
new file mode 100644
index 0000000..aa03014
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.6.0/security-overview.md
@@ -0,0 +1,31 @@
+---
+id: security-overview
+title: Pulsar security overview
+sidebar_label: "Overview"
+original_id: security-overview
+---
+
+As the central message bus for a business, Apache Pulsar is frequently used for storing mission-critical data. Therefore, enabling security features in Pulsar is crucial.
+
+By default, Pulsar configures no encryption, authentication, or authorization. Any client can communicate to Apache Pulsar via plain text service URLs. So we must ensure that Pulsar accessing via these plain text service URLs is restricted to trusted clients only. In such cases, you can use Network segmentation and/or authorization ACLs to restrict access to trusted IPs. If you use neither, the state of cluster is wide open and anyone can access the cluster.
+
+Pulsar supports a pluggable authentication mechanism. And Pulsar clients use this mechanism to authenticate with brokers and proxies. You can also configure Pulsar to support multiple authentication sources.
+
+You had better secure the service components in your Apache Pulsar deployment.
+
+## Role tokens
+
+In Pulsar, a *role* is a string, like `admin` or `app1`, which can represent a single client or multiple clients. You can use roles to control permission for clients to produce or consume from certain topics, administer the configuration for tenants, and so on.
+
+Apache Pulsar uses a [Authentication Provider](#authentication-providers) to establish the identity of a client and then assign a *role token* to that client. This role token is then used for [Authorization and ACLs](security-authorization) to determine what the client is authorized to do.
+
+## Authentication providers
+
+Currently Pulsar supports the following authentication providers:
+
+- [TLS Authentication](security-tls-authentication)
+- [Athenz](security-athenz)
+- [Kerberos](security-kerberos)
+- [JSON Web Token Authentication](security-jwt)
+
+
diff --git a/site2/website-next/versioned_docs/version-2.6.0/security-tls-authentication.md b/site2/website-next/versioned_docs/version-2.6.0/security-tls-authentication.md
new file mode 100644
index 0000000..20a6604
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.6.0/security-tls-authentication.md
@@ -0,0 +1,220 @@
+---
+id: security-tls-authentication
+title: Authentication using TLS
+sidebar_label: "Authentication using TLS"
+original_id: security-tls-authentication
+---
+
+## TLS authentication overview
+
+TLS authentication is an extension of [TLS transport encryption](security-tls-transport). Not only servers have keys and certs that the client uses to verify the identity of servers, clients also have keys and certs that the server uses to verify the identity of clients. You must have TLS transport encryption configured on your cluster before you can use TLS authentication. This guide assumes you already have TLS transport encryption configured.
+
+`Bouncy Castle Provider` provides TLS related cipher suites and algorithms in Pulsar. If you need [FIPS](https://www.bouncycastle.org/fips_faq.html) version of `Bouncy Castle Provider`, please reference [Bouncy Castle page](security-bouncy-castle).
+
+### Create client certificates
+
+Client certificates are generated using the certificate authority. Server certificates are also generated with the same certificate authority.
+
+The biggest difference between client certs and server certs is that the **common name** for the client certificate is the **role token** which that client is authenticated as.
+
+First, you need to enter the following command to generate the key :
+
+```bash
+
+$ openssl genrsa -out admin.key.pem 2048
+
+```
+
+Similar to the broker, the client expects the key to be in [PKCS 8](https://en.wikipedia.org/wiki/PKCS_8) format, so you need to convert it by entering the following command:
+
+```bash
+
+$ openssl pkcs8 -topk8 -inform PEM -outform PEM \
+      -in admin.key.pem -out admin.key-pk8.pem -nocrypt
+
+```
+
+Next, enter the command below to generate the certificate request. When you are asked for a **common name**, enter the **role token** that you want this key pair to authenticate a client as.
+
+```bash
+
+$ openssl req -config openssl.cnf \
+      -key admin.key.pem -new -sha256 -out admin.csr.pem
+
+```
+
+:::note
+
+If openssl.cnf is not specified, read [Certificate authority](http://pulsar.apache.org/docs/en/security-tls-transport/#certificate-authority) to get the openssl.cnf.
+
+:::
+
+Then, enter the command below to sign with request with the certificate authority. Note that the client certs uses the **usr_cert** extension, which allows the cert to be used for client authentication.
+
+```bash
+
+$ openssl ca -config openssl.cnf -extensions usr_cert \
+      -days 1000 -notext -md sha256 \
+      -in admin.csr.pem -out admin.cert.pem
+
+```
+
+You can get a cert, `admin.cert.pem`, and a key, `admin.key-pk8.pem` from this command. With `ca.cert.pem`, clients can use this cert and this key to authenticate themselves to brokers and proxies as the role token ``admin``.
+
+:::note
+
+If the "unable to load CA private key" error occurs and the reason of this error is "No such file or directory: /etc/pki/CA/private/cakey.pem" in this step. Try the command below:
+
+```bash
+
+$ cd /etc/pki/tls/misc/CA
+$ ./CA -newca
+
+```
+
+to generate `cakey.pem` .
+
+:::
+
+## Enable TLS authentication on brokers
+
+To configure brokers to authenticate clients, add the following parameters to `broker.conf`, alongside [the configuration to enable tls transport](security-tls-transport.md#broker-configuration):
+
+```properties
+
+# Configuration to enable authentication
+authenticationEnabled=true
+authenticationProviders=org.apache.pulsar.broker.authentication.AuthenticationProviderTls
+
+# operations and publish/consume from all topics
+superUserRoles=admin
+
+# Authentication settings of the broker itself. Used when the broker connects to other brokers, either in same or other clusters
+brokerClientTlsEnabled=true
+brokerClientAuthenticationPlugin=org.apache.pulsar.client.impl.auth.AuthenticationTls
+brokerClientAuthenticationParameters=tlsCertFile:/path/my-ca/admin.cert.pem,tlsKeyFile:/path/my-ca/admin.key-pk8.pem
+brokerClientTrustCertsFilePath=/path/my-ca/certs/ca.cert.pem
+
+```
+
+## Enable TLS authentication on proxies
+
+To configure proxies to authenticate clients, add the following parameters to `proxy.conf`, alongside [the configuration to enable tls transport](security-tls-transport.md#proxy-configuration):
+
+The proxy should have its own client key pair for connecting to brokers. You need to configure the role token for this key pair in the ``proxyRoles`` of the brokers. See the [authorization guide](security-authorization) for more details.
+
+```properties
+
+# For clients connecting to the proxy
+authenticationEnabled=true
+authenticationProviders=org.apache.pulsar.broker.authentication.AuthenticationProviderTls
+
+# For the proxy to connect to brokers
+brokerClientAuthenticationPlugin=org.apache.pulsar.client.impl.auth.AuthenticationTls
+brokerClientAuthenticationParameters=tlsCertFile:/path/to/proxy.cert.pem,tlsKeyFile:/path/to/proxy.key-pk8.pem
+
+```
+
+## Client configuration
+
+When you use TLS authentication, client connects via TLS transport. You need to configure the client to use ```https://``` and 8443 port for the web service URL, ```pulsar+ssl://``` and 6651 port for the broker service URL.
+
+### CLI tools
+
+[Command-line tools](reference-cli-tools.md) like [`pulsar-admin`](reference-pulsar-admin), [`pulsar-perf`](reference-cli-tools.md#pulsar-perf), and [`pulsar-client`](reference-cli-tools.md#pulsar-client) use the `conf/client.conf` config file in a Pulsar installation.
+
+You need to add the following parameters to that file to use TLS authentication with the CLI tools of Pulsar:
+
+```properties
+
+webServiceUrl=https://broker.example.com:8443/
+brokerServiceUrl=pulsar+ssl://broker.example.com:6651/
+useTls=true
+tlsAllowInsecureConnection=false
+tlsTrustCertsFilePath=/path/to/ca.cert.pem
+authPlugin=org.apache.pulsar.client.impl.auth.AuthenticationTls
+authParams=tlsCertFile:/path/to/my-role.cert.pem,tlsKeyFile:/path/to/my-role.key-pk8.pem
+
+```
+
+### Java client
+
+```java
+
+import org.apache.pulsar.client.api.PulsarClient;
+
+PulsarClient client = PulsarClient.builder()
+    .serviceUrl("pulsar+ssl://broker.example.com:6651/")
+    .enableTls(true)
+    .tlsTrustCertsFilePath("/path/to/ca.cert.pem")
+    .authentication("org.apache.pulsar.client.impl.auth.AuthenticationTls",
+                    "tlsCertFile:/path/to/my-role.cert.pem,tlsKeyFile:/path/to/my-role.key-pk8.pem")
+    .build();
+
+```
+
+### Python client
+
+```python
+
+from pulsar import Client, AuthenticationTLS
+
+auth = AuthenticationTLS("/path/to/my-role.cert.pem", "/path/to/my-role.key-pk8.pem")
+client = Client("pulsar+ssl://broker.example.com:6651/",
+                tls_trust_certs_file_path="/path/to/ca.cert.pem",
+                tls_allow_insecure_connection=False,
+				authentication=auth)
+
+```
+
+### C++ client
+
+```c++
+
+#include <pulsar/Client.h>
+
+pulsar::ClientConfiguration config;
+config.setUseTls(true);
+config.setTlsTrustCertsFilePath("/path/to/ca.cert.pem");
+config.setTlsAllowInsecureConnection(false);
+
+pulsar::AuthenticationPtr auth = pulsar::AuthTls::create("/path/to/my-role.cert.pem",
+                                                         "/path/to/my-role.key-pk8.pem")
+config.setAuth(auth);
+
+pulsar::Client client("pulsar+ssl://broker.example.com:6651/", config);
+
+```
+
+### Node.js client
+
+```JavaScript
+
+const Pulsar = require('pulsar-client');
+
+(async () => {
+  const auth = new Pulsar.AuthenticationTls({
+    certificatePath: '/path/to/my-role.cert.pem',
+    privateKeyPath: '/path/to/my-role.key-pk8.pem',
+  });
+
+  const client = new Pulsar.Client({
+    serviceUrl: 'pulsar+ssl://broker.example.com:6651/',
+    authentication: auth,
+    tlsTrustCertsFilePath: '/path/to/ca.cert.pem',
+  });
+})();
+
+```
+
+### C# client
+
+```c#
+
+var clientCertificate = new X509Certificate2("admin.pfx");
+var client = PulsarClient.Builder()
+                         .AuthenticateUsingClientCertificate(clientCertificate)
+                         .Build();
+
+```
+
diff --git a/site2/website-next/versioned_docs/version-2.6.0/security-tls-keystore.md b/site2/website-next/versioned_docs/version-2.6.0/security-tls-keystore.md
new file mode 100644
index 0000000..e813912
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.6.0/security-tls-keystore.md
@@ -0,0 +1,322 @@
+---
+id: security-tls-keystore
+title: Using TLS with KeyStore configure
+sidebar_label: "Using TLS with KeyStore configure"
+original_id: security-tls-keystore
+---
+
+## Overview
+
+Apache Pulsar supports [TLS encryption](security-tls-transport.md) and [TLS authentication](security-tls-authentication) between clients and Apache Pulsar service. 
+By default it uses PEM format file configuration. This page tries to describe use [KeyStore](https://en.wikipedia.org/wiki/Java_KeyStore) type configure for TLS.
+
+
+## TLS encryption with KeyStore configure
+ 
+### Generate TLS key and certificate
+
+The first step of deploying TLS is to generate the key and the certificate for each machine in the cluster.
+You can use Java’s `keytool` utility to accomplish this task. We will generate the key into a temporary keystore
+initially for broker, so that we can export and sign it later with CA.
+
+```shell
+
+keytool -keystore broker.keystore.jks -alias localhost -validity {validity} -genkeypair -keyalg RSA
+
+```
+
+You need to specify two parameters in the above command:
+
+1. `keystore`: the keystore file that stores the certificate. The *keystore* file contains the private key of
+   the certificate; hence, it needs to be kept safely.
+2. `validity`: the valid time of the certificate in days.
+
+> Ensure that common name (CN) matches exactly with the fully qualified domain name (FQDN) of the server.
+The client compares the CN with the DNS domain name to ensure that it is indeed connecting to the desired server, not a malicious one.
+
+### Creating your own CA
+
+After the first step, each broker in the cluster has a public-private key pair, and a certificate to identify the machine.
+The certificate, however, is unsigned, which means that an attacker can create such a certificate to pretend to be any machine.
+
+Therefore, it is important to prevent forged certificates by signing them for each machine in the cluster.
+A `certificate authority (CA)` is responsible for signing certificates. CA works likes a government that issues passports —
+the government stamps (signs) each passport so that the passport becomes difficult to forge. Other governments verify the stamps
+to ensure the passport is authentic. Similarly, the CA signs the certificates, and the cryptography guarantees that a signed
+certificate is computationally difficult to forge. Thus, as long as the CA is a genuine and trusted authority, the clients have
+high assurance that they are connecting to the authentic machines.
+
+```shell
+
+openssl req -new -x509 -keyout ca-key -out ca-cert -days 365
+
+```
+
+The generated CA is simply a *public-private* key pair and certificate, and it is intended to sign other certificates.
+
+The next step is to add the generated CA to the clients' truststore so that the clients can trust this CA:
+
+```shell
+
+keytool -keystore client.truststore.jks -alias CARoot -import -file ca-cert
+
+```
+
+NOTE: If you configure the brokers to require client authentication by setting `tlsRequireTrustedClientCertOnConnect` to `true` on the
+broker configuration, then you must also provide a truststore for the brokers and it should have all the CA certificates that clients keys were signed by.
+
+```shell
+
+keytool -keystore broker.truststore.jks -alias CARoot -import -file ca-cert
+
+```
+
+In contrast to the keystore, which stores each machine’s own identity, the truststore of a client stores all the certificates
+that the client should trust. Importing a certificate into one’s truststore also means trusting all certificates that are signed
+by that certificate. As the analogy above, trusting the government (CA) also means trusting all passports (certificates) that
+it has issued. This attribute is called the chain of trust, and it is particularly useful when deploying TLS on a large BookKeeper cluster.
+You can sign all certificates in the cluster with a single CA, and have all machines share the same truststore that trusts the CA.
+That way all machines can authenticate all other machines.
+
+
+### Signing the certificate
+
+The next step is to sign all certificates in the keystore with the CA we generated. First, you need to export the certificate from the keystore:
+
+```shell
+
+keytool -keystore broker.keystore.jks -alias localhost -certreq -file cert-file
+
+```
+
+Then sign it with the CA:
+
+```shell
+
+openssl x509 -req -CA ca-cert -CAkey ca-key -in cert-file -out cert-signed -days {validity} -CAcreateserial -passin pass:{ca-password}
+
+```
+
+Finally, you need to import both the certificate of the CA and the signed certificate into the keystore:
+
+```shell
+
+keytool -keystore broker.keystore.jks -alias CARoot -import -file ca-cert
+keytool -keystore broker.keystore.jks -alias localhost -import -file cert-signed
+
+```
+
+The definitions of the parameters are the following:
+
+1. `keystore`: the location of the keystore
+2. `ca-cert`: the certificate of the CA
+3. `ca-key`: the private key of the CA
+4. `ca-password`: the passphrase of the CA
+5. `cert-file`: the exported, unsigned certificate of the broker
+6. `cert-signed`: the signed certificate of the broker
+
+### Configuring brokers
+
+Brokers enable TLS by provide valid `brokerServicePortTls` and `webServicePortTls`, and also need set `tlsEnabledWithKeyStore` to `true` for using KeyStore type configuration.
+Besides this, KeyStore path,  KeyStore password, TrustStore path, and TrustStore password need to provided.
+And since broker will create internal client/admin client to communicate with other brokers, user also need to provide config for them, this is similar to how user config the outside client/admin-client.
+If `tlsRequireTrustedClientCertOnConnect` is `true`, broker will reject the Connection if the Client Certificate is not trusted. 
+
+The following TLS configs are needed on the broker side:
+
+```properties
+
+tlsEnabledWithKeyStore=true
+# key store
+tlsKeyStoreType=JKS
+tlsKeyStore=/var/private/tls/broker.keystore.jks
+tlsKeyStorePassword=brokerpw
+
+# trust store
+tlsTrustStoreType=JKS
+tlsTrustStore=/var/private/tls/broker.truststore.jks
+tlsTrustStorePassword=brokerpw
+
+# internal client/admin-client config
+brokerClientTlsEnabled=true
+brokerClientTlsEnabledWithKeyStore=true
+brokerClientTlsTrustStoreType=JKS
+brokerClientTlsTrustStore=/var/private/tls/client.truststore.jks
+brokerClientTlsTrustStorePassword=clientpw
+
+```
+
+NOTE: it is important to restrict access to the store files via filesystem permissions.
+
+Optional settings that may worth consider:
+
+1. tlsClientAuthentication=false: Enable/Disable using TLS for authentication. This config when enabled will authenticate the other end
+   of the communication channel. It should be enabled on both brokers and clients for mutual TLS.
+2. tlsCiphers=[TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256], A cipher suite is a named combination of authentication, encryption, MAC and key exchange
+   algorithm used to negotiate the security settings for a network connection using TLS network protocol. By default,
+   it is null. [OpenSSL Ciphers](https://www.openssl.org/docs/man1.0.2/apps/ciphers.html)
+   [JDK Ciphers](http://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#ciphersuites)
+3. tlsProtocols=[TLSv1.2,TLSv1.1,TLSv1] (list out the TLS protocols that you are going to accept from clients).
+   By default, it is not set.
+
+### Configuring Clients
+
+This is similar to [TLS encryption configuing for client with PEM type](security-tls-transport.md#Client configuration).
+For a a minimal configuration, user need to provide the TrustStore information.
+
+e.g. 
+1. for [Command-line tools](reference-cli-tools) like [`pulsar-admin`](reference-cli-tools#pulsar-admin), [`pulsar-perf`](reference-cli-tools#pulsar-perf), and [`pulsar-client`](reference-cli-tools#pulsar-client) use the `conf/client.conf` config file in a Pulsar installation.
+
+   ```properties
+   
+   webServiceUrl=https://broker.example.com:8443/
+   brokerServiceUrl=pulsar+ssl://broker.example.com:6651/
+   useKeyStoreTls=true
+   tlsTrustStoreType=JKS
+   tlsTrustStorePath=/var/private/tls/client.truststore.jks
+   tlsTrustStorePassword=clientpw
+   
+   ```
+
+1. for java client
+
+   ```java
+   
+   import org.apache.pulsar.client.api.PulsarClient;
+   
+   PulsarClient client = PulsarClient.builder()
+       .serviceUrl("pulsar+ssl://broker.example.com:6651/")
+       .enableTls(true)
+       .useKeyStoreTls(true)
+       .tlsTrustStorePath("/var/private/tls/client.truststore.jks")
+       .tlsTrustStorePassword("clientpw")
+       .allowTlsInsecureConnection(false)
+       .build();
+   
+   ```
+
+1. for java admin client
+
+```java
+
+    PulsarAdmin amdin = PulsarAdmin.builder().serviceHttpUrl("https://broker.example.com:8443")
+                .useKeyStoreTls(true)
+                .tlsTrustStorePath("/var/private/tls/client.truststore.jks")
+                .tlsTrustStorePassword("clientpw")
+                .allowTlsInsecureConnection(false)
+                .build();
+
+```
+
+## TLS authentication with KeyStore configure
+
+This similar to [TLS authentication with PEM type](security-tls-authentication)
+
+### broker authentication config
+
+`broker.conf`
+
+```properties
+
+# Configuration to enable authentication
+authenticationEnabled=true
+authenticationProviders=org.apache.pulsar.broker.authentication.AuthenticationProviderTls
+
+# this should be the CN for one of client keystore.
+superUserRoles=admin
+
+# Enable KeyStore type
+tlsEnabledWithKeyStore=true
+requireTrustedClientCertOnConnect=true
+
+# key store
+tlsKeyStoreType=JKS
+tlsKeyStore=/var/private/tls/broker.keystore.jks
+tlsKeyStorePassword=brokerpw
+
+# trust store
+tlsTrustStoreType=JKS
+tlsTrustStore=/var/private/tls/broker.truststore.jks
+tlsTrustStorePassword=brokerpw
+
+# internal client/admin-client config
+brokerClientTlsEnabled=true
+brokerClientTlsEnabledWithKeyStore=true
+brokerClientTlsTrustStoreType=JKS
+brokerClientTlsTrustStore=/var/private/tls/client.truststore.jks
+brokerClientTlsTrustStorePassword=clientpw
+# internal auth config
+brokerClientAuthenticationPlugin=org.apache.pulsar.client.impl.auth.AuthenticationKeyStoreTls
+brokerClientAuthenticationParameters=keyStoreType:JKS,keyStorePath:/var/private/tls/client.keystore.jks,keyStorePassword:clientpw
+# currently websocket not support keystore type
+webSocketServiceEnabled=false
+
+```
+
+### client authentication configuring
+
+Besides the TLS encryption configuring. The main work is configuring the KeyStore, which contains a valid CN as client role, for client.
+
+e.g. 
+1. for [Command-line tools](reference-cli-tools) like [`pulsar-admin`](reference-cli-tools#pulsar-admin), [`pulsar-perf`](reference-cli-tools#pulsar-perf), and [`pulsar-client`](reference-cli-tools#pulsar-client) use the `conf/client.conf` config file in a Pulsar installation.
+
+   ```properties
+   
+   webServiceUrl=https://broker.example.com:8443/
+   brokerServiceUrl=pulsar+ssl://broker.example.com:6651/
+   useKeyStoreTls=true
+   tlsTrustStoreType=JKS
+   tlsTrustStorePath=/var/private/tls/client.truststore.jks
+   tlsTrustStorePassword=clientpw
+   authPlugin=org.apache.pulsar.client.impl.auth.AuthenticationKeyStoreTls
+   authParams={"keyStoreType":"JKS","keyStorePath":"/path/to/keystorefile","keyStorePassword":"keystorepw"}
+   
+   ```
+
+1. for java client
+
+   ```java
+   
+   import org.apache.pulsar.client.api.PulsarClient;
+   
+   PulsarClient client = PulsarClient.builder()
+       .serviceUrl("pulsar+ssl://broker.example.com:6651/")
+       .enableTls(true)
+       .useKeyStoreTls(true)
+       .tlsTrustStorePath("/var/private/tls/client.truststore.jks")
+       .tlsTrustStorePassword("clientpw")
+       .allowTlsInsecureConnection(false)
+       .authentication(
+               "org.apache.pulsar.client.impl.auth.AuthenticationKeyStoreTls",
+               "keyStoreType:JKS,keyStorePath:/var/private/tls/client.keystore.jks,keyStorePassword:clientpw")
+       .build();
+   
+   ```
+
+1. for java admin client
+
+   ```java
+   
+       PulsarAdmin amdin = PulsarAdmin.builder().serviceHttpUrl("https://broker.example.com:8443")
+           .useKeyStoreTls(true)
+           .tlsTrustStorePath("/var/private/tls/client.truststore.jks")
+           .tlsTrustStorePassword("clientpw")
+           .allowTlsInsecureConnection(false)
+           .authentication(
+                  "org.apache.pulsar.client.impl.auth.AuthenticationKeyStoreTls",
+                  "keyStoreType:JKS,keyStorePath:/var/private/tls/client.keystore.jks,keyStorePassword:clientpw")
+           .build();
+   
+   ```
+
+## Enabling TLS Logging
+
+You can enable TLS debug logging at the JVM level by starting the brokers and/or clients with `javax.net.debug` system property. For example:
+
+```shell
+
+-Djavax.net.debug=all
+
+```
+
+You can find more details on this in [Oracle documentation](http://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/ReadDebug.html) on [debugging SSL/TLS connections](http://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/ReadDebug.html).
diff --git a/site2/website-next/versioned_docs/version-2.6.0/security-tls-transport.md b/site2/website-next/versioned_docs/version-2.6.0/security-tls-transport.md
new file mode 100644
index 0000000..478189f
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.6.0/security-tls-transport.md
@@ -0,0 +1,290 @@
+---
+id: security-tls-transport
+title: Transport Encryption using TLS
+sidebar_label: "Transport Encryption using TLS"
+original_id: security-tls-transport
+---
+
+## TLS overview
+
+By default, Apache Pulsar clients communicate with the Apache Pulsar service in plain text. This means that all data is sent in the clear. You can use TLS to encrypt this traffic to protect the traffic from the snooping of a man-in-the-middle attacker.
+
+You can also configure TLS for both encryption and authentication. Use this guide to configure just TLS transport encryption and refer to [here](security-tls-authentication.md) for TLS authentication configuration. Alternatively, you can use [another authentication mechanism](security-athenz) on top of TLS transport encryption.
+
+> Note that enabling TLS may impact the performance due to encryption overhead.
+
+## TLS concepts
+
+TLS is a form of [public key cryptography](https://en.wikipedia.org/wiki/Public-key_cryptography). Using key pairs consisting of a public key and a private key can perform the encryption. The public key encrpyts the messages and the private key decrypts the messages.
+
+To use TLS transport encryption, you need two kinds of key pairs, **server key pairs** and a **certificate authority**.
+
+You can use a third kind of key pair, **client key pairs**, for [client authentication](security-tls-authentication).
+
+You should store the **certificate authority** private key in a very secure location (a fully encrypted, disconnected, air gapped computer). As for the certificate authority public key, the **trust cert**, you can freely shared it.
+
+For both client and server key pairs, the administrator first generates a private key and a certificate request, then uses the certificate authority private key to sign the certificate request, finally generates a certificate. This certificate is the public key for the server/client key pair.
+
+For TLS transport encryption, the clients can use the **trust cert** to verify that the server has a key pair that the certificate authority signed when the clients are talking to the server. A man-in-the-middle attacker does not have access to the certificate authority, so they couldn't create a server with such a key pair.
+
+For TLS authentication, the server uses the **trust cert** to verify that the client has a key pair that the certificate authority signed. The common name of the **client cert** is then used as the client's role token (see [Overview](security-overview)).
+
+`Bouncy Castle Provider` provides cipher suites and algorithms in Pulsar. If you need [FIPS](https://www.bouncycastle.org/fips_faq.html) version of `Bouncy Castle Provider`, please reference [Bouncy Castle page](security-bouncy-castle).
+
+## Create TLS certificates
+
+Creating TLS certificates for Pulsar involves creating a [certificate authority](#certificate-authority) (CA), [server certificate](#server-certificate), and [client certificate](#client-certificate).
+
+Follow the guide below to set up a certificate authority. You can also refer to plenty of resources on the internet for more details. We recommend [this guide](https://jamielinux.com/docs/openssl-certificate-authority/index.html) for your detailed reference.
+
+### Certificate authority
+
+1. Create the certificate for the CA. You can use CA to sign both the broker and client certificates. This ensures that each party will trust the others. You should store CA in a very secure location (ideally completely disconnected from networks, air gapped, and fully encrypted).
+
+2. Entering the following command to create a directory for your CA, and place [this openssl configuration file](https://github.com/apache/pulsar/tree/master/site2/website/static/examples/openssl.cnf) in the directory. You may want to modify the default answers for company name and department in the configuration file. Export the location of the CA directory to the environment variable, CA_HOME. The configuration file uses this environment variable to find the rest of the files and direc [...]
+
+```bash
+
+mkdir my-ca
+cd my-ca
+wget https://raw.githubusercontent.com/apache/pulsar/master/site2/website/static/examples/openssl.cnf
+export CA_HOME=$(pwd)
+
+```
+
+3. Enter the commands below to create the necessary directories, keys and certs.
+
+```bash
+
+mkdir certs crl newcerts private
+chmod 700 private/
+touch index.txt
+echo 1000 > serial
+openssl genrsa -aes256 -out private/ca.key.pem 4096
+chmod 400 private/ca.key.pem
+openssl req -config openssl.cnf -key private/ca.key.pem \
+    -new -x509 -days 7300 -sha256 -extensions v3_ca \
... 424 lines suppressed ...