跳转到内容

集群配置

如果你只运行一个 SyncTV 进程,通常不需要开启集群模式。

需要开启的场景:

  • Kubernetes 中运行多个副本。
  • 多台服务器共同服务同一个 SyncTV 实例。
  • 需要跨节点踢人、房间同步、缓存失效、直播协调。

开启方式:

cluster:
enabled: true

开启后,Redis 和 server.cluster_secret 都是必需项。

集群模式解决的是“多个 SyncTV 进程共同服务同一个实例”时的运行时一致性问题。它不是简单的负载均衡开关,也不替代 PostgreSQL、Redis、Ingress 或直播存储/代理策略。

状态单一来源

PostgreSQL 保存 durable state:用户、房间、权限、Provider、偏好设置和审计数据。所有节点必须连接同一个数据库。

运行时协调

Redis 保存 ephemeral/shared state:节点注册、pub/sub、Redis Stream catch-up、leader election、限流和短期认证状态。

节点间信任

server.cluster_secret 用于节点间 gRPC 调用认证。所有节点必须一致,且不能暴露给客户端。

直播可达性

RTMP publisher 可能在任意节点上,HLS segment 也可能被任意节点读取;因此直播需要 publisher registry,并在本地 backend 与共享 backend 之间选择合适模型。

SyncTV 集群运行时架构图,展示客户端通过 HTTP/gRPC 入口访问多个节点,节点共享 PostgreSQL 和 Redis,并通过 HLS backend 或 publisher-node proxy 读取直播分片。 SyncTV 集群运行时架构图,展示客户端通过 HTTP/gRPC 入口访问多个节点,节点共享 PostgreSQL 和 Redis,并通过 HLS backend 或 publisher-node proxy 读取直播分片。
集群模式下,业务持久状态进入 PostgreSQL,跨节点运行时状态进入 Redis。HLS 可以使用本地 backend 加 publisher-node proxy,也可以使用共享文件系统或 OSS 让各节点直接读取分片。
  1. 每个节点启动后使用相同配置连接 PostgreSQL 和 Redis,并生成或读取自己的节点 ID。
  2. 节点通过 cluster.discovery_mode 注册和发现其他节点。默认 redis 模式适合大多数环境;Kubernetes 可以选择 k8s_dns 辅助发现 Pod。
  3. 房间事件、权限变更、缓存失效、踢人等运行时事件通过 Redis pub/sub 分发。节点短暂断线后通过 Redis Stream 在 cluster.catchup_window_secs 窗口内补事件。
  4. 后台任务通过 cluster.leader_election_mode 选出一个 leader,避免多个副本重复执行同一类全局任务。
  5. 直播 publisher 会登记到共享 registry,其他节点可以知道某个房间/媒体当前由哪个节点持有。
  6. HLS 请求落到非 publisher 节点时,如果本地没有可直接读取的分片,会通过 HLS gRPC proxy 向 publisher 节点读取 playlist/segment。
部署形态适用场景推荐配置
单进程小规模、自托管、开发测试cluster.enabled=false,Redis 可选但生产建议配置
多进程固定节点多台 VM 或裸机,节点数量稳定cluster.enabled=truediscovery_mode=staticredis
Kubernetes 多副本水平扩缩容、滚动升级、Ingress 暴露cluster.enabled=truediscovery_mode=redisk8s_dns、HTTP/gRPC 独立 Service
多副本直播,小流量HLS/FLV 需要跨节点播放,但 segment 请求量不高cluster.enabled=true,可使用 memory 或本地 file,依赖 publisher-node proxy
多副本直播,高流量HLS 请求量高、需要更稳定的滚动升级边界在集群配置基础上增加 file 共享存储或 oss HLS backend

默认值:false

开启后,SyncTV 会启用跨节点协调逻辑。

必须满足:

  • 所有节点连接同一个 PostgreSQL。
  • 所有节点连接同一个 Redis。
  • 所有节点使用同一个 server.cluster_secret
  • 节点之间能访问彼此的 API/gRPC 地址。

默认值:1000

作用:高优先级事件通道容量,例如踢人、权限变更等不能随便丢的事件。

满了以后发送方会等待,而不是丢弃事件。

默认值:10000

作用:普通 Redis publish 通道容量。

普通事件在极端拥塞时可能丢弃并记录 warning,避免拖垮主流程。

可选值:

  • redis
  • static
  • k8s_dns

默认值。节点通过 Redis 注册和发现。

优点:

  • 跨环境通用。
  • 不依赖 Kubernetes DNS。
  • 配置简单。

手动配置节点地址。

cluster:
discovery_mode: "static"
peers:
- "node2.example.com:8080"
- "node3.example.com"

适合固定服务器数量的小集群。

如果 peer 不写端口,SyncTV 会尝试使用 server.port

通过 Kubernetes headless service DNS 发现 Pod。

需要环境变量:

  • HEADLESS_SERVICE_NAME
  • POD_NAMESPACE

注意:k8s_dns 仍然需要 Redis。DNS 只帮助更快发现 Pod,不替代 Redis 的健康监控、负载均衡和 pub/sub。

可选值:

  • redis
  • k8s_lease

默认值。通过 Redis 锁做 leader election。

适合 Docker Compose、普通服务器、Kubernetes。

使用 Kubernetes coordination.k8s.io/v1 Lease

需要:

  • POD_NAME
  • POD_NAMESPACE
  • RBAC 权限

Helm chart 会在需要时渲染相关 RBAC。

默认值:300

作用:新节点加入时,从 Redis Stream 回放多久以内的事件,避免刚订阅时漏掉短时间内发布的事件。

调大:

  • 事件量不大,但你希望更保守。
  • 节点启动慢。

调小:

  • 事件量很大。
  • 想缩短启动回放时间。

默认值:10000

作用:每个 Redis Stream 大约保留多少条事件。

高流量房间很多时,太小可能导致断线节点还没追上,事件就被裁剪。太大则占用更多 Redis 内存。

集群 HLS 不只有共享存储一种模式。当前实现通过 publisher registry 定位推流所在节点,并在需要时通过 HLS gRPC proxy 从 publisher 节点读取 playlist/segment。

适用 backend:

  • memory
  • filehls_shared_storage=false

这种模型部署简单,不要求所有副本共享分片目录。代价是非 publisher 节点的 HLS segment 请求会跨节点回源到 publisher 节点;publisher 节点重启、不可达或网络分区时,远端节点可能无法继续读取该直播的分片。

示例:

livestream:
hls_storage_backend: "memory"

或:

livestream:
hls_storage_backend: "file"
hls_shared_storage: false
hls_storage_path: "/var/lib/synctv/hls"

文件系统方案:

livestream:
hls_storage_backend: "file"
hls_shared_storage: true
hls_storage_path: "/var/lib/synctv/hls"

并确保所有 Pod 都能读写同一个路径,例如 NFS、RWX PVC 或 CSI volume。

对象存储方案:

livestream:
hls_storage_backend: "oss"
hls_oss:
endpoint: "https://s3.example.com"
bucket: "synctv-hls"
base_path: "synctv/hls/"

oss backend 使用 S3 兼容对象存储,不需要 hls_shared_storagehls_shared_storage=true 只允许搭配 hls_storage_backend=file,在 memoryoss 下会被配置校验拒绝。

Helm chart 默认不启用集群模式。扩容前必须显式开启 config.cluster.enabled=true。HLS 可以先使用 publisher-node proxy 模型;如果直播 HLS 流量较高,建议配置 file 共享存储或 oss 对象存储。

扩容前必须确认:

  • Redis 可用。
  • server.cluster_secret 已设置。
  • HLS 模型已明确:小规模使用本地 backend + publisher-node proxy,生产高流量使用 file + hls_shared_storage=true + RWX/PVCoss
  • gRPC Service/Ingress 与内部节点访问符合你的网络设计。