modify: 清除diskcache依赖
This commit is contained in:
@@ -279,13 +279,13 @@ worker/<type>/<worker_id>/__admin__
|
||||
- **单一事实来源**:`count` 存于 cache 键 `worker:cm:counts:<type>`,在线网关 id 列表存 `worker:cm:gateways`,各网关分摊配额存 `worker:cm:quota:<type>:<gw>`(可观测)。
|
||||
- **网关登记/注销 + 心跳租约**:网关启动时 `register_gateway()` 加入在线列表,并每 15s `heartbeat_gateway()` 刷新自身时间戳;超过租约(60s)未心跳的死网关会被自动清理(crash/kill -9 也不残留,避免配额失真)。当前由 `CHONGMING_GATEWAY_ID` 环境变量指定(多实例需唯一,尤其**同宿主多网关必须显式指定**;缺省回退 `hostname`,稳定且重启不变,不残留);关闭时 `unregister_gateway()` 移除,其余网关实时重算分摊。
|
||||
- **分摊算法**:`own_quota()` 将全局总量按在线网关 sorted(id) 均分,余量按序补前若干。`/admin/workers/<type>/scale`(body `{count:<全局总量>}`)写全局 count 后,各网关把自己的 session 副本调到自己的 quota。
|
||||
- **共享方式与后端**:单实例本机 `diskcache` 即可;**多实例必须共享同一 cache 后端**(同一共享卷的 diskcache 或 redis),否则各写各的 cache 无法收敛成全局量。
|
||||
- **共享方式与后端**:单实例本机 `sqlite` 即可;**多实例必须共享同一 cache 后端**(同一共享卷的 sqlite 或 redis),否则各写各的 cache 无法收敛成全局量。
|
||||
- **启动优先级开关**:根 `config.toml` 的 `[cache].launch_worker_count` 决定网关启动时副本数的来源:
|
||||
|
||||
```toml
|
||||
[cache]
|
||||
backend = "diskcache" # "diskcache"(默认) | "redis"
|
||||
cache_store_path = "./cache_data"
|
||||
backend = "sqlite" # "sqlite"(默认,本机共享) | "redis"(跨主机)
|
||||
path = "./cache_data/cache.db"
|
||||
launch_worker_count = "toml" # "toml"(默认)=启动用 toml 的 count 覆盖并写回 cache;"cache"=cache 为单一事实来源,toml 仅在缺失时引导
|
||||
```
|
||||
|
||||
@@ -293,7 +293,7 @@ worker/<type>/<worker_id>/__admin__
|
||||
- **实例登记 + 心跳租约**:每个 external 进程启动时向 `worker:cm:instances:<type>` 登记自身参与方(`[instance_id, ts]`),并每 15s 心跳续约;超过租约(60s)未心跳的死实例会被清理。`divmod` 按存活参与方 N 均分全局 count(余量补靠前实例),`N==1` 时退化为全额(单部署零影响)。
|
||||
- **实例标识默认唯一**:`--instance` / 环境变量 `CHONGMING_WORKER_INSTANCE` 显式指定(跨重启稳定、逐实例精细扩缩可持续命中);缺省回退 `{hostname}:{pid}`——**同一机器并行多个未指定 `--instance` 的进程也能靠 pid 区分**,不会因为 id 相同被并成一个参与方导致副本翻倍或前端只显示一个实例。注意缺省 id 随进程重启变化。
|
||||
- **广播 + 幂等收敛**:`/scale` 写全局 count 后向该类型**全部存活实例**广播 `rescale`,各实例读同一全局 count + 同一份参与方列表算出的 quota 一致,重复 rescale 也幂等,因此任意地收敛到同一预期状态。
|
||||
- **前提**:external 需共用共享 `[cache]`(多实例 redis 或共享卷 diskcache);`cache is None` 时退化为全额(仅单实例安全)。
|
||||
- **前提**:external 需共用共享 `[cache]`(多实例 redis 或共享卷 sqlite);`cache is None` 时退化为全额(仅单实例安全)。
|
||||
|
||||
### 外部进程实例粒度扩缩(逐实例精细扩缩)
|
||||
|
||||
@@ -312,7 +312,7 @@ inline worker 的生命周期交给**基于分布式锁的宿主级领导选举*
|
||||
- **多 worker(同网关)**:同一时刻只有一个网关进程托管 inline worker(副本数精确等于 `count`,不再是 `worker 数 × count`);其余进程只做 HTTP,经 Zenoh liveliness 发现并调用 inline worker。HTTP 层仍由所有 gunicorn worker 分担吞吐。
|
||||
- **多实例(不同网关)**:各网关按自己的 `gateway_id` 各自选举,互不抢占。
|
||||
- **持有者崩溃自愈**:非持有者进程经 `refresh_workers` 周期性巡检(`_maybe_heal_inline`)——若发现某 inline 类型既无线活副本又无本地副本,就经分布式锁抢得领导权并拉起这些 worker(防 gunicorn 复活死 slot 却因租约未过期而跳过的问题)。接管同样 `set_nx` 唯一胜出,无双持有。
|
||||
- 前提:同一共享 `[cache]`(见「全局副本数协调」);单实例本机 `diskcache` 即可,多实例需共享后端。
|
||||
- 前提:同一共享 `[cache]`(见「全局副本数协调」);单实例本机 `sqlite` 即可,多实例需共享后端。
|
||||
|
||||
### 多 worker 的边界(转发 vs 处理)
|
||||
|
||||
@@ -628,10 +628,10 @@ MQTT Bridge 是**网关进程内**的 MQTT 客户端组件,负责订阅主题
|
||||
|
||||
```toml
|
||||
[cache]
|
||||
backend = "redis" # 跨主机收敛必须用 redis(或共享卷 diskcache)
|
||||
backend = "redis" # 跨主机收敛必须用 redis(或共享卷 sqlite)
|
||||
```
|
||||
|
||||
- **关键条件**:跨机器收敛依赖**共享缓存后端**(与「全局副本数协调」同一 `[cache]`,单一事实来源)。仅 `redis`(或共享卷的 `diskcache`)后端时,不同物理机上的网关才会看到同一把锁,真正全局单 Bridge。
|
||||
- **关键条件**:跨机器收敛依赖**共享缓存后端**(与「全局副本数协调」同一 `[cache]`,单一事实来源)。仅 `redis`(或共享卷的 `sqlite`)后端时,不同物理机上的网关才会看到同一把锁,真正全局单 Bridge。
|
||||
- **`use_embedded_broker = true`(各机内嵌独立 Broker)**:各机 Broker 互不相连、本身不产生重复响应;此时全局单 Bridge 只会连到持锁网关那台机器的 Broker。
|
||||
- **`use_embedded_broker = false`(共享外部 Broker)**:原先 N 台网关的 N 个 Bridge 会共同订阅同一批主题,导致一条请求被各消费一次、各回一份响应;改用分布式锁后全局只有一个 Bridge 消费,彻底规避重复响应。
|
||||
|
||||
@@ -639,12 +639,12 @@ backend = "redis" # 跨主机收敛必须用 redis(或共享卷 dis
|
||||
|
||||
| 部署形态 | MQTT Broker | `[cache]` 后端 | 状态 |
|
||||
| -------- | ----------- | ------------- | ---- |
|
||||
| 单机(含多 worker) | 内嵌 amqtt | 本地 `diskcache` | ✅ 完全够用 |
|
||||
| 多实例分布式 | **外部 Broker**(必须,内嵌各机不聚合、接管会断设备) | **redis**(或共享卷 `diskcache`) | ✅ 推荐 |
|
||||
| 单机(含多 worker) | 内嵌 amqtt | 本地 `sqlite` | ✅ 完全够用 |
|
||||
| 多实例分布式 | **外部 Broker**(必须,内嵌各机不聚合、接管会断设备) | **redis**(或共享卷 `sqlite`) | ✅ 推荐 |
|
||||
|
||||
> 关键:多实例是否收敛,**MQTT 只是其中一环**,真正的收敛前提是**所有网关共享同一 `[cache]` 后端**。Bridge 全局锁、inline 领导选举锁、在线网关清单/quota 全部工作在同一共享 cache 上;若各实例用各自本机 cache,`mqtt_bridge` 锁跨不了主机,每台都能抢到 Bridge,又会退化成 N 个 Bridge 各连各的 Broker → 单请求多响应,问题回归。
|
||||
>
|
||||
> 即:**单机 = 内嵌 Broker + 本地 diskcache;多实例 = 外部 Broker(必须)+ redis/共享卷 diskcache(选一)**。
|
||||
> 即:**单机 = 内嵌 Broker + 本地 sqlite;多实例 = 外部 Broker(必须)+ redis/共享卷 sqlite(选一)**。
|
||||
|
||||
### 请求负载格式(信封协议)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user