diff --git a/daprdocs/content/en/concepts/dapr-services/placement.md b/daprdocs/content/en/concepts/dapr-services/placement.md
index 7db47a37491..d94f9a8435d 100644
--- a/daprdocs/content/en/concepts/dapr-services/placement.md
+++ b/daprdocs/content/en/concepts/dapr-services/placement.md
@@ -2,25 +2,29 @@
type: docs
title: "Dapr Placement control plane service overview"
linkTitle: "Placement"
-description: "Overview of the Dapr placement service"
+description: "Overview of the Dapr Placement service"
---
-The Dapr Placement service is used to calculate and distribute distributed hash tables for the location of [Dapr actors]({{< ref actors >}}) running in [self-hosted mode]({{< ref self-hosted >}}) or on [Kubernetes]({{< ref kubernetes >}}). This hash table maps actor IDs to pods or processes so a Dapr application can communicate with the actor.Anytime a Dapr application activates a Dapr actor, the placement updates the hash tables with the latest actor locations.
+The Dapr Placement service is used to calculate and distribute distributed hash tables for the location of [Dapr actors]({{< ref actors >}}) running in [self-hosted mode]({{< ref self-hosted >}}) or on [Kubernetes]({{< ref kubernetes >}}). Grouped by namespace, the hash tables map actor types to pods or processes so a Dapr application can communicate with the actor. Anytime a Dapr application activates a Dapr actor, the Placement service updates the hash tables with the latest actor location.
## Self-hosted mode
-The placement service Docker container is started automatically as part of [`dapr init`]({{< ref self-hosted-with-docker.md >}}). It can also be run manually as a process if you are running in [slim-init mode]({{< ref self-hosted-no-docker.md >}}).
+The Placement service Docker container is started automatically as part of [`dapr init`]({{< ref self-hosted-with-docker.md >}}). It can also be run manually as a process if you are running in [slim-init mode]({{< ref self-hosted-no-docker.md >}}).
## Kubernetes mode
-The placement service is deployed as part of `dapr init -k`, or via the Dapr Helm charts. For more information on running Dapr on Kubernetes, visit the [Kubernetes hosting page]({{< ref kubernetes >}}).
+The Placement service is deployed as part of `dapr init -k`, or via the Dapr Helm charts. For more information on running Dapr on Kubernetes, visit the [Kubernetes hosting page]({{< ref kubernetes >}}).
## Placement tables
-There is an [HTTP API `/placement/state` for placement service]({{< ref placement_api.md >}}) that exposes placement table information. The API is exposed on the sidecar on the same port as the healthz. This is an unauthenticated endpoint, and is disabled by default. You need to set `DAPR_PLACEMENT_METADATA_ENABLED` environment or `metadata-enabled` command line args to true to enable it. If you are using helm you just need to set `dapr_placement.metadataEnabled` to true.
+There is an [HTTP API `/placement/state` for Placement service]({{< ref placement_api.md >}}) that exposes placement table information. The API is exposed on the sidecar on the same port as the healthz. This is an unauthenticated endpoint, and is disabled by default. You need to set `DAPR_PLACEMENT_METADATA_ENABLED` environment or `metadata-enabled` command line args to true to enable it. If you are using helm you just need to set `dapr_placement.metadataEnabled` to true.
+
+{{% alert title="Important" color="warning" %}}
+When deploying actors into different namespaces ({{< ref namespaced-actors.md >}}), it is recommended to disable the `metadata-enabled` if you want to prevent retrieving actors from all namespaces. The metadata endpoint is scoped to all namespaces.
+{{% /alert %}}
### Usecase:
-The placement table API can be used for retrieving the current placement table, which contains all the actors registered. This can be helpful for debugging and allows tools to extract and present information about actors.
+The placement table API can be used to retrieve the current placement table, which contains all the actors registered across all namespaces. This is helpful for debugging and allowing tools to extract and present information about actors.
### HTTP Request
@@ -61,26 +65,29 @@ updatedAt | timestamp | Timestamp of the actor registered/updated.
```json
{
- "hostList": [{
- "name": "198.18.0.1:49347",
- "appId": "actor1",
- "actorTypes": ["testActorType1", "testActorType3"],
- "updatedAt": 1690274322325260000
- },
- {
- "name": "198.18.0.2:49347",
- "appId": "actor2",
- "actorTypes": ["testActorType2"],
- "updatedAt": 1690274322325260000
- },
- {
- "name": "198.18.0.3:49347",
- "appId": "actor2",
- "actorTypes": ["testActorType2"],
- "updatedAt": 1690274322325260000
- }
- ],
- "tableVersion": 1
+ "hostList": [{
+ "name": "198.18.0.1:49347",
+ "namespace": "ns1",
+ "appId": "actor1",
+ "actorTypes": ["testActorType1", "testActorType3"],
+ "updatedAt": 1690274322325260000
+ },
+ {
+ "name": "198.18.0.2:49347",
+ "namespace": "ns2",
+ "appId": "actor2",
+ "actorTypes": ["testActorType2"],
+ "updatedAt": 1690274322325260000
+ },
+ {
+ "name": "198.18.0.3:49347",
+ "namespace": "ns2",
+ "appId": "actor2",
+ "actorTypes": ["testActorType2"],
+ "updatedAt": 1690274322325260000
+ }
+ ],
+ "tableVersion": 1
}
```
diff --git a/daprdocs/content/en/concepts/terminology.md b/daprdocs/content/en/concepts/terminology.md
index 80d5c89d7a2..9901f966ffe 100644
--- a/daprdocs/content/en/concepts/terminology.md
+++ b/daprdocs/content/en/concepts/terminology.md
@@ -17,6 +17,8 @@ This page details all of the common terms you may come across in the Dapr docs.
| Dapr | Distributed Application Runtime. | [Dapr overview]({{< ref overview.md >}})
| Dapr control plane | A collection of services that are part of a Dapr installation on a hosting platform such as a Kubernetes cluster. This allows Dapr-enabled applications to run on the platform and handles Dapr capabilities such as actor placement, Dapr sidecar injection, or certificate issuance/rollover. | [Self-hosted overview]({{< ref self-hosted-overview >}})
[Kubernetes overview]({{< ref kubernetes-overview >}})
| HTTPEndpoint | HTTPEndpoint is a Dapr resource use to identify non-Dapr endpoints to invoke via the service invocation API. | [Service invocation API]({{< ref service_invocation_api.md >}})
+| Namespacing | Namespacing in Dapr provides isolation, and thus provides multi-tenancy. | Learn more about namespacing [components]({{< ref component-scopes.md >}}), [service invocation]({{< ref service-invocation-namespaces.md >}}), [pub/sub]({{< ref pubsub-namespaces.md >}}), and [actors]({{< ref namespaced-actors.md >}})
| Self-hosted | Windows/macOS/Linux machine(s) where you can run your applications with Dapr. Dapr provides the capability to run on machines in "self-hosted" mode. | [Self-hosted mode]({{< ref self-hosted-overview.md >}})
| Service | A running application or binary. This can refer to your application or to a Dapr application.
| Sidecar | A program that runs alongside your application as a separate process or container. | [Sidecar pattern](https://docs.microsoft.com/azure/architecture/patterns/sidecar)
+
diff --git a/daprdocs/content/en/developing-applications/building-blocks/actors/actor-reentrancy.md b/daprdocs/content/en/developing-applications/building-blocks/actors/actor-reentrancy.md
index 4351b19cfbe..6153860e7da 100644
--- a/daprdocs/content/en/developing-applications/building-blocks/actors/actor-reentrancy.md
+++ b/daprdocs/content/en/developing-applications/building-blocks/actors/actor-reentrancy.md
@@ -2,7 +2,7 @@
type: docs
title: "How-to: Enable and use actor reentrancy in Dapr"
linkTitle: "How-To: Actor reentrancy"
-weight: 70
+weight: 80
description: Learn more about actor reentrancy
---
diff --git a/daprdocs/content/en/developing-applications/building-blocks/actors/actors-overview.md b/daprdocs/content/en/developing-applications/building-blocks/actors/actors-overview.md
index fdde091390d..bb96b9b2326 100644
--- a/daprdocs/content/en/developing-applications/building-blocks/actors/actors-overview.md
+++ b/daprdocs/content/en/developing-applications/building-blocks/actors/actors-overview.md
@@ -60,6 +60,12 @@ Each actor is uniquely identified by an actor ID. An actor ID can be _any_ strin
## Features
+### Namespaced actors
+
+Dapr supports namespaced actors. An actor type can be deployed into different namespaces. You can call instances of these actors in the same namespace.
+
+[Learn more about namespaced actors and how they work.]({{< ref namespaced-actors.md >}})
+
### Actor lifetime
Since Dapr actors are virtual, they do not need to be explicitly created or destroyed. The Dapr actor runtime:
diff --git a/daprdocs/content/en/developing-applications/building-blocks/actors/actors-timers-reminders.md b/daprdocs/content/en/developing-applications/building-blocks/actors/actors-timers-reminders.md
index f6131475e96..7a4cd1ec74c 100644
--- a/daprdocs/content/en/developing-applications/building-blocks/actors/actors-timers-reminders.md
+++ b/daprdocs/content/en/developing-applications/building-blocks/actors/actors-timers-reminders.md
@@ -2,7 +2,7 @@
type: docs
title: "Actors timers and reminders"
linkTitle: "Timers and reminders"
-weight: 40
+weight: 50
description: "Setting timers and reminders and performing error handling for your actors"
aliases:
- "/developing-applications/building-blocks/actors/actors-background"
diff --git a/daprdocs/content/en/developing-applications/building-blocks/actors/howto-actors-partitioning.md b/daprdocs/content/en/developing-applications/building-blocks/actors/howto-actors-partitioning.md
index 0d4017096e9..79c7303aba1 100644
--- a/daprdocs/content/en/developing-applications/building-blocks/actors/howto-actors-partitioning.md
+++ b/daprdocs/content/en/developing-applications/building-blocks/actors/howto-actors-partitioning.md
@@ -2,7 +2,7 @@
type: docs
title: "How to: Enable partitioning of actor reminders"
linkTitle: "How to: Partition reminders"
-weight: 50
+weight: 60
description: "Enable actor reminders partitioning for your application"
aliases:
- "/developing-applications/building-blocks/actors/actors-background"
diff --git a/daprdocs/content/en/developing-applications/building-blocks/actors/howto-actors.md b/daprdocs/content/en/developing-applications/building-blocks/actors/howto-actors.md
index 16c7bbf4383..e0902e12c1b 100644
--- a/daprdocs/content/en/developing-applications/building-blocks/actors/howto-actors.md
+++ b/daprdocs/content/en/developing-applications/building-blocks/actors/howto-actors.md
@@ -2,7 +2,7 @@
type: docs
title: "How-to: Interact with virtual actors using scripting"
linkTitle: "How-To: Interact with virtual actors"
-weight: 60
+weight: 70
description: Invoke the actor method for state management
---
diff --git a/daprdocs/content/en/developing-applications/building-blocks/actors/namespaced-actors.md b/daprdocs/content/en/developing-applications/building-blocks/actors/namespaced-actors.md
new file mode 100644
index 00000000000..5954b61a1bf
--- /dev/null
+++ b/daprdocs/content/en/developing-applications/building-blocks/actors/namespaced-actors.md
@@ -0,0 +1,124 @@
+---
+type: docs
+title: "Namespaced actors"
+linkTitle: "Namespaced actors"
+weight: 40
+description: "Learn about namespaced actors"
+---
+
+
+Namespacing in Dapr provides isolation, and thus multi-tenancy. With actor namespacing, the same actor type can be deployed into different namespaces. You can call instances of these actors in the same namespace.
+
+{{% alert title="Note" color="primary" %}}
+Each namespaced actor deployment must use its own separate state store, especially if the same actor type is used across namespaces. In other words, no namespace information is written as part of the actor record, and hence separate state stores are required for each namespace. See [Configuring actor state stores for namespacing]({{< ref "#configuring-actor-state-stores-for-namespacing" >}}) section for examples.
+{{% /alert %}}
+
+## Creating and configuring namespaces
+
+You can use namespaces either in self-hosted mode or on Kubernetes.
+
+{{< tabs "Self-Hosted" "Kubernetes">}}
+
+{{% codetab %}}
+In self-hosted mode, you can specify the namespace for a Dapr instance by setting [the `NAMESPACE` environment variable]({{< ref environment.md >}}).
+
+{{% /codetab %}}
+
+{{% codetab %}}
+On Kubernetes, you can create and configure namepaces when deploying actor applications. For example, start with the following `kubectl` commands:
+
+```bash
+kubectl create namespace namespace-actorA
+kubectl config set-context --current --namespace=namespace-actorA
+```
+
+Then, deploy your actor applications into this namespace (in the example, `namespace-actorA`).
+
+{{% /codetab %}}
+
+{{< /tabs >}}
+
+## Configuring actor state stores for namespacing
+
+Each namespaced actor deployment **must** use its own separate state store. While you could use different physical databases for each actor namespace, some state store components provide a way to logically separate data by table, prefix, collection, and more. This allows you to use the same physical database for multiple namespaces, as long as you provide the logical separation in the Dapr component definition.
+
+Some examples are provided below.
+
+### Example 1: By a prefix in etcd
+
+```yaml
+apiVersion: dapr.io/v1alpha1
+kind: Component
+metadata:
+ name: statestore
+spec:
+ type: state.etcd
+ version: v2
+ metadata:
+ - name: endpoints
+ value: localhost:2379
+ - name: keyPrefixPath
+ value: namespace-actorA
+ - name: actorStateStore
+ value: "true"
+```
+
+### Example 2: By table name in SQLite
+
+```yaml
+apiVersion: dapr.io/v1alpha1
+kind: Component
+metadata:
+ name: statestore
+spec:
+ type: state.sqlite
+ version: v1
+ metadata:
+ - name: connectionString
+ value: "data.db"
+ - name: tableName
+ value: "namespace-actorA"
+ - name: actorStateStore
+ value: "true"
+```
+
+### Example 3: By logical database number in Redis
+
+```yaml
+apiVersion: dapr.io/v1alpha1
+kind: Component
+metadata:
+ name: statestore
+spec:
+ type: state.redis
+ version: v1
+ metadata:
+ - name: redisHost
+ value: localhost:6379
+ - name: redisPassword
+ value: ""
+ - name: actorStateStore
+ value: "true"
+ - name: redisDB
+ value: "1"
+ - name: redisPassword
+ secretKeyRef:
+ name: redis-secret
+ key: redis-password
+ - name: actorStateStore
+ value: "true"
+ - name: redisDB
+ value: "1"
+auth:
+ secretStore:
+```
+
+Check your [state store component specs]({{< ref supported-state-stores.md >}}) to see what it provides.
+
+{{% alert title="Note" color="primary" %}}
+Namespaced actors use the multi-tenant Placement service. With this control plane service where each application deployment has its own namespace, sidecars belonging to an application in namespace "ActorA" won't receive placement information for an application in namespace "ActorB".
+{{% /alert %}}
+
+## Next steps
+- [Learn more about the Dapr Placement service]({{< ref placement.md >}})
+- [Placement API reference guide]({{< ref placement_api.md >}})
\ No newline at end of file
diff --git a/daprdocs/content/en/reference/api/placement_api.md b/daprdocs/content/en/reference/api/placement_api.md
index a882eb8618e..dde238edf12 100644
--- a/daprdocs/content/en/reference/api/placement_api.md
+++ b/daprdocs/content/en/reference/api/placement_api.md
@@ -6,10 +6,14 @@ description: "Detailed documentation on the Placement API"
weight: 1200
---
-Dapr has an HTTP API `/placement/state` for placement service that exposes placement table information. The API is exposed on the sidecar on the same port as the healthz. This is an unauthenticated endpoint, and is disabled by default.
+Dapr has an HTTP API `/placement/state` for Placement service that exposes placement table information. The API is exposed on the sidecar on the same port as the healthz. This is an unauthenticated endpoint, and is disabled by default.
To enable the placement metadata in self-hosted mode you can either set`DAPR_PLACEMENT_METADATA_ENABLED` environment variable or `metadata-enabled` command line args on the Placement service to `true` to. See [how to run the Placement service in self-hosted mode]({{< ref "self-hosted-no-docker.md#enable-actors" >}}).
+{{% alert title="Important" color="warning" %}}
+When running placement in [multi-tenant mode]({{< ref namespaced-actors.md >}}), disable the `metadata-enabled` command line args to prevent different namespaces from seeing each other's data.
+{{% /alert %}}
+
If you are using Helm for deployment of the Placement service on Kubernetes then to enable the placement metadata, set `dapr_placement.metadataEnabled` to `true`.
## Usecase
@@ -55,25 +59,28 @@ updatedAt | timestamp | Timestamp of the actor registered/updated.
```json
{
- "hostList": [{
- "name": "198.18.0.1:49347",
- "appId": "actor1",
- "actorTypes": ["testActorType1", "testActorType3"],
- "updatedAt": 1690274322325260000
- },
- {
- "name": "198.18.0.2:49347",
- "appId": "actor2",
- "actorTypes": ["testActorType2"],
- "updatedAt": 1690274322325260000
- },
- {
- "name": "198.18.0.3:49347",
- "appId": "actor2",
- "actorTypes": ["testActorType2"],
- "updatedAt": 1690274322325260000
- }
- ],
- "tableVersion": 1
+ "hostList": [{
+ "name": "198.18.0.1:49347",
+ "namespace": "ns1",
+ "appId": "actor1",
+ "actorTypes": ["testActorType1", "testActorType3"],
+ "updatedAt": 1690274322325260000
+ },
+ {
+ "name": "198.18.0.2:49347",
+ "namespace": "ns2",
+ "appId": "actor2",
+ "actorTypes": ["testActorType2"],
+ "updatedAt": 1690274322325260000
+ },
+ {
+ "name": "198.18.0.3:49347",
+ "namespace": "ns2",
+ "appId": "actor2",
+ "actorTypes": ["testActorType2"],
+ "updatedAt": 1690274322325260000
+ }
+ ],
+ "tableVersion": 1
}
```
\ No newline at end of file