Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion doc/cfg/mududb_cfg.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
mpk_path = "/your database path/mpk"

# The path of database files
data_path = "/your database path/data"
# `data_path` is still accepted as a compatibility alias; new files should use
# the field name used by the Rust configuration struct.
db_path = "/your database path/data"

listen_ip = "127.0.0.1"
http_listen_port = 8300
Expand All @@ -16,13 +18,21 @@ pg_listen_port = 5432
# Enable the WASI component runtime used by the new backend.
enable_async = true

# Component ABI target. Omit this field to use the default `p2`.
# Allowed values: "p2", "p3".
component_target = "p2"

# 0 = Legacy
# 1 = IOUring
# 2 = Tokio
server_mode = 1

# TCP port used by the custom framed client/server protocol.
tcp_listen_port = 9527

# Enable one TCP listener per worker when supported by the selected backend.
tcp_multi_port = false

# 0 means: detect the worker count from available CPU cores.
io_uring_worker_threads = 0

Expand Down
13 changes: 9 additions & 4 deletions doc/cn/how_to_start.cn.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,18 +116,23 @@ python script/build/install_binaries.py --all-workspace-bins
```


## 创建配置文件
## 配置文件

[mududb_cfg.toml 示例](../cfg/mududb_cfg.toml)

在以下位置创建配置文件
`mudud` 会从以下位置读取配置

```bash
mkdir -p ${HOME}/.mududb
touch ${HOME}/.mududb/mududb_cfg.toml
```

如果该文件不存在,`mudud` 首次启动时也会按默认值自动创建 `${HOME}/.mududb/mududb_cfg.toml`。
不要创建空的 `mududb_cfg.toml`:服务端只要发现文件存在,就会把它当作用户配置解析。如果该文件不存在,`mudud` 首次启动时会按默认值自动创建 `${HOME}/.mududb/mududb_cfg.toml`。

如果要使用示例配置,可以复制:

```bash
cp doc/cfg/mududb_cfg.toml ${HOME}/.mududb/mududb_cfg.toml
```

## 使用 MuduDB

Expand Down
76 changes: 76 additions & 0 deletions doc/cn/partition.cn.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,80 @@ worker 会按需懒创建自己需要访问的 partition relation。

当路由命中远端 worker 时,请求会按 partition placement 转发到该 worker 处理。

## Port Sharding 策略

partition placement 负责决定一个逻辑 partition 归属哪个 worker。Port sharding 则把这些 worker 暴露为稳定的
TCP 端口,让客户端和工具可以直接连接到目标数据所在的 worker。

当前 IOUring 和 Tokio 后端使用以下端口策略:

- `tcp_listen_port` 是基础 TCP 端口
- worker `0` 监听 `tcp_listen_port`
- worker `1` 监听 `tcp_listen_port + 1`
- worker `N` 监听 `tcp_listen_port + N`

当后端 worker 数量大于 1 时,启动路径会自动开启 `tcp_multi_port`。例如 `tcp_listen_port = 9527` 且有 4 个
worker 时,端口分布如下:

```text
worker 0 -> 9527
worker 1 -> 9528
worker 2 -> 9529
worker 3 -> 9530
```

这是传输层的分片机制,不替代 partition placement。placement 仍然负责把 `partition_id` 映射到 `worker_id`;
port sharding 负责把目标 worker 映射到可连接的 TCP endpoint。

### 发现 Worker 端口

可以通过 HTTP 管理接口查看当前 topology:

```bash
mcli --http-addr 127.0.0.1:8300 server-topology
```

返回结果包含:

- `worker_count`
- `tcp_multi_port`
- `tcp_base_listen_port`
- 每个 worker 的 `worker_index`
- 每个 worker 的 `worker_id`
- 每个 worker 的 `tcp_listen_port`
- 当前与该 worker 关联的 partition id 列表

可以用 `partition-route` 查询某个 rule key 或 range 会路由到哪些 partition 和 worker:

```bash
mcli --http-addr 127.0.0.1:8300 partition-route --rule-name r_orders --key 1001,50001
```

客户端可以组合使用这两个接口:

1. `partition-route` 解析目标 `partition_id` 和 `worker_id`。
2. `server-topology` 把该 `worker_id` 解析为 `tcp_listen_port`。
3. 客户端连接 `listen_ip:tcp_listen_port`。

### 作用

当调用方能在打开或重新绑定 session 前确定目标 partition 时,port sharding 可以减少不必要的 worker 间转发。

它提供的能力包括:

- 让客户端直接亲和到 partition 所在 worker
- 减少 partition-local 流量的跨 worker 转发
- 为 benchmark 和运维工具提供稳定的 per-worker endpoint
- 从外部观察 placement 如何映射到网络端口

### 限制

port sharding 目前绑定在多 worker 的 IOUring 和 Tokio 后端路径上。legacy 后端仍保持较早的单 TCP/PG serving
模型,不应当把它当作 per-worker 端口分片部署来使用。

客户端仍然必须尊重 partition placement。连接某个 worker 端口只是在选择执行 worker;它不会移动数据,也不会改变某个
partition 的归属关系。

## 当前语义与限制

当前实现有明确边界。
Expand All @@ -235,6 +309,7 @@ worker 会按需懒创建自己需要访问的 partition relation。
- partition pruning 目前只围绕 key 列进行
- placement 是显式元数据,不是自动调度
- 远端 partition 访问通过 worker-to-worker RPC 完成
- per-worker port sharding 可用于多 worker 的 IOUring 和 Tokio 后端路径

目前还存在一个重要限制:

Expand Down Expand Up @@ -267,6 +342,7 @@ worker 会按需懒创建自己需要访问的 partition relation。
- worker 放置
- 物理存储
- 执行期路由
- 可选的 per-worker TCP port sharding

这样的拆分可以保持 schema 模型干净,也为后续扩展打基础,例如:

Expand Down
13 changes: 9 additions & 4 deletions doc/en/how_to_start.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,18 +115,23 @@ python script/build/install_binaries.py --all-workspace-bins
```


## Create a Configuration File
## Configuration File

[mududb_cfg.toml example](../cfg/mududb_cfg.toml)

Create the configuration file at:
`mudud` reads its configuration from:

```bash
mkdir -p ${HOME}/.mududb
touch ${HOME}/.mududb/mududb_cfg.toml
```

If the file does not exist, `mudud` also creates `${HOME}/.mududb/mududb_cfg.toml` automatically on first start with default values.
Do not create an empty `mududb_cfg.toml`: the server treats an existing file as user configuration and parses it. If the file does not exist, `mudud` creates `${HOME}/.mududb/mududb_cfg.toml` automatically on first start with default values.

To use the example configuration instead:

```bash
cp doc/cfg/mududb_cfg.toml ${HOME}/.mududb/mududb_cfg.toml
```

## Use MuduDB

Expand Down
83 changes: 81 additions & 2 deletions doc/en/partition.md
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,80 @@ Supported remote actions:

Remote requests are routed by partition placement and executed by the worker that owns the target partition.

## Port Sharding

Partition placement decides which worker owns a logical partition. Port sharding exposes those workers through stable
TCP ports so clients and tools can connect directly to the worker that owns the data they want to use.

The current IOUring and Tokio backends use this policy:

- `tcp_listen_port` is the base TCP port
- worker `0` listens on `tcp_listen_port`
- worker `1` listens on `tcp_listen_port + 1`
- worker `N` listens on `tcp_listen_port + N`

When the backend has more than one worker, `tcp_multi_port` is enabled by the backend startup path. For example, with
`tcp_listen_port = 9527` and four workers, the worker ports are:

```text
worker 0 -> 9527
worker 1 -> 9528
worker 2 -> 9529
worker 3 -> 9530
```

This is a transport-level sharding mechanism. It does not replace partition placement. Placement still maps
`partition_id` to `worker_id`; port sharding maps the selected worker to a reachable TCP endpoint.

### Discovering Worker Ports

Use the HTTP management API to read the live topology:

```bash
mcli --http-addr 127.0.0.1:8300 server-topology
```

The response includes:

- `worker_count`
- `tcp_multi_port`
- `tcp_base_listen_port`
- each worker's `worker_index`
- each worker's `worker_id`
- each worker's `tcp_listen_port`
- the partition ids currently associated with that worker

Use `partition-route` to resolve a rule key or range to partition and worker ids:

```bash
mcli --http-addr 127.0.0.1:8300 partition-route --rule-name r_orders --key 1001,50001
```

A client can combine both calls:

1. `partition-route` resolves the target `partition_id` and `worker_id`.
2. `server-topology` resolves that `worker_id` to `tcp_listen_port`.
3. The client connects to `listen_ip:tcp_listen_port`.

### Why It Exists

Port sharding is useful when the caller can choose the target partition before opening or rebinding a session.

It enables:

- direct client affinity to the owning worker
- fewer cross-worker forwards for partition-local traffic
- stable per-worker endpoints for benchmark and operational tooling
- an external way to inspect how placement maps onto network endpoints

### Limits

Port sharding is currently tied to the multi-worker IOUring and Tokio backend paths. The legacy backend keeps the older
single TCP/PG serving model and should not be treated as a per-worker port-sharded deployment.

Clients still need to respect partition placement. Connecting to a worker port only selects an execution worker; it
does not move data or change which worker owns a partition.

## Current Semantics and Limits

The current implementation is intentionally scoped.
Expand All @@ -237,6 +311,7 @@ The current implementation is intentionally scoped.
- partition pruning is based on key columns, not arbitrary predicates
- placement is explicit metadata
- remote partition access uses worker-to-worker RPC
- per-worker port sharding is available on the multi-worker IOUring and Tokio backend paths

There is still an important transactional limit:

Expand All @@ -258,13 +333,17 @@ Avoid using the current implementation as if it were already a general distribut

## Summary

The partition subsystem separates:
The current partition subsystem separates:

- logical partition definition
- table binding
- worker placement
- physical storage
- execution-time routing
- runtime routing
- optional per-worker TCP port sharding

This keeps the schema model separate from deployment topology while still allowing clients and tools to discover the
worker endpoint that owns a routed partition.

This keeps the schema model clean and allows the engine to evolve toward partition rebalance, partition split or merge,
and distributed commit in later iterations.
16 changes: 16 additions & 0 deletions mudu_cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ It exposes these operations:
- `invoke`
- `app-install`
- `app-invoke`
- `app-list`
- `app-detail`
- `app-uninstall`
- `server-topology`
- `partition-route`

## Examples

Expand Down Expand Up @@ -106,6 +111,17 @@ mcli --addr 127.0.0.1:9527 --http-addr 127.0.0.1:8300 app-invoke --app kv --modu
}'
```

Management commands:

```bash
mcli --http-addr 127.0.0.1:8300 app-list
mcli --http-addr 127.0.0.1:8300 app-detail --app wallet
mcli --http-addr 127.0.0.1:8300 app-detail --app wallet --module wallet --proc create_user
mcli --http-addr 127.0.0.1:8300 app-uninstall --app wallet
mcli --http-addr 127.0.0.1:8300 server-topology
mcli --http-addr 127.0.0.1:8300 partition-route --rule-name user_rule --key user-100
```

## JSON input

JSON request bodies can be supplied in three ways:
Expand Down
6 changes: 6 additions & 0 deletions mudu_cli/src/binding_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,16 @@ pub struct MuduKeyValueBinding {
#[derive(Debug, Clone, uniffi::Record)]
pub struct WorkerTopologyBinding {
pub worker_index: u64,
pub tcp_listen_port: u16,
pub worker_id: String,
pub partitions: Vec<String>,
}

#[derive(Debug, Clone, uniffi::Record)]
pub struct ServerTopologyBinding {
pub worker_count: u64,
pub tcp_multi_port: bool,
pub tcp_base_listen_port: u16,
pub workers: Vec<WorkerTopologyBinding>,
}

Expand Down Expand Up @@ -278,11 +281,14 @@ fn to_server_topology_binding(
) -> ServerTopologyBinding {
ServerTopologyBinding {
worker_count: topology.worker_count as u64,
tcp_multi_port: topology.tcp_multi_port,
tcp_base_listen_port: topology.tcp_base_listen_port,
workers: topology
.workers
.into_iter()
.map(|worker| WorkerTopologyBinding {
worker_index: worker.worker_index as u64,
tcp_listen_port: worker.tcp_listen_port,
worker_id: worker.worker_id.to_string(),
partitions: worker
.partitions
Expand Down
Loading
Loading