9.7 KiB
理解 Endor:从全球入口到对象数据
Endor 的概念模型把全球访问、区域运行时和对象数据连接起来:请求从统一入口进入,在合适的区域找到 Nexus Runtime,再由它承载的 Aster VM 执行对象操作。数据以分片组织,在区域内保持高可用,并为每个分片安排跨区域恢复目标。
概念设计草案:本文按当前讨论绘制目标架构,不表示这些组件和协议已经全部实现。图中的区域、节点、分片数量仅为示例;CDN 和身份服务的接入方式是建议方案。
架构总览
图中绿色/蓝色实线表示请求路径或区域内数据依赖,紫色虚线表示身份控制与公钥分发,蓝色点线表示 CDN 回源,金色虚线表示跨区复制和备份。连线表示可达或依赖关系,不表示请求向所有节点广播。
图的编排由 Python 生成 SVG:节点图标、二分全连接和复制线路都能复现和编辑。Python 更适合这张静态架构图;页面查看、缩放与下载由 TypeScript/React 负责。
全球入口与区域入口
客户端包括浏览器、Tessera、SDK 和 CLI。endorphin API 是逻辑上的全球流量入口,尚未在本文规定一个真实的域名。全球调度根据健康、延迟、项目归属和数据放置策略选择区域;不能只选择网络最近的区域而忽略对象在哪个分片。
示例使用北美和亚洲两个区域。每个区域有自己的负载均衡入口,下面是 Traefik 网关,负责按配置进行 TLS、主机名或路径路由。图中的第二个 Traefik 标记为 HA 副本:多副本是生产冗余选项,单实例概念部署不要求两个网关。
为什么画成二分全连接
每个区域示例中有两个 Traefik 和三个 Nexus Runtime,画出全部六条边,即二分图 K₂,₃。每个网关都能把请求路由到任意一个符合条件的健康 Runtime,避免把一个网关固定绑定到一个运行时。
这是逻辑可达关系。实际转发仍需考虑服务发现、健康检查、项目和对象归属,以及有状态连接的路由策略;Runtime 之间并没有因此形成全连接网状网络。
Nexus Runtime 与 Aster VM
此处采用 一个 Nexus Runtime 节点配一个 Aster VM 的概念约定。Nexus 表示对外接入与运行时承载边界,Aster VM 执行对象相关逻辑。图中每台服务器下面都单独画出一个 VM 芯片,避免把多个 VM 误读成另一个共享池。
请求经过区域入口和 Traefik 到达 Nexus,再定位目标分片。图中运行时下方的连接汇入分片路由层,表示节点可以按归属访问区域分片,不是「Runtime 1 只能访问分片 1」。对象身份、远程引用、生命周期与调用语义仍需结合节点与对象挂载草案继续定义。
三类存储如何组成一个分片
示例中每个区域都有两个逻辑数据分片。每个分片展示三个协作部分,它们是逻辑数据边界,不要求一分片对应三台独占物理机器。
| 部分 | 概念职责 | 依赖关系 |
|---|---|---|
| PostgreSQL | 结构化元数据、对象索引及需要事务约束的状态;具体数据模型待定 | 提供关系数据与事务能力 |
| Aerarium Object data pool | 对象数据的逻辑组织与访问层;不是把 S3 换一个名字 | 同时依赖 PostgreSQL 与 S3 |
| S3 兼容存储 | Blob、文件、快照和适合对象存储的数据;具体格式待定 | 提供对象持久化能力 |
图中 Aerarium 向左右各画一条依赖箭头,分别连接 PostgreSQL 和 S3。它们不是三个互不相关的平行数据池。
区域内高可用
每个存储图标下面有一个小型副本图标,用点线连接,表示本区域的高可用副本。生产部署应跨独立故障域放置,具体可以是不同可用区或独立节点。
这是逻辑 HA 要求,各层的实现不同:PostgreSQL 可以使用主备复制,Aerarium 需要自己的状态协调和故障恢复设计,S3 的耐久性与副本由选定的存储系统提供。图不强制三者采用同一种同步复制机制,也不把单纯增加副本等同于已经实现故障自动切换。
每个分片都要有跨区恢复目标
区域内副本解决本地节点或故障域失效;跨区备份解决整个区域不可用。四个源分片均有独立的异地目标:
| 源分片 | 异地备份位置 | 覆盖内容 |
|---|---|---|
| NA-01、NA-02 | 亚洲区域 | 各分片的 PostgreSQL、Aerarium 状态和 S3 数据 |
| AS-01、AS-02 | 北美区域 | 各分片的 PostgreSQL、Aerarium 状态和 S3 数据 |
每个目标应保留可校验的恢复清单,将关系数据恢复点、对象池元数据版本与 S3 对象版本关联起来;不能只复制其中一种存储就宣称整个分片可恢复。图中的金色线路明确跨越区域,备份集按源分片编号标识。
“最终一定拿到数据”需要怎样的保证
设计目标是:正常访问优先本区域;本地不可用时,仍能找到异地保存的数据。需要区分两类能力:
- 异地在线副本:已有服务能读取它;追平状态、授权和路由满足要求后,才可承担故障读取。
- 异地备份:保留了恢复材料,需要恢复 PostgreSQL、重建 Aerarium 并校验对象版本后才能提供服务,通常更慢。
保证边界:异步复制与定期备份不能无条件保证最后一笔已确认写入不会丢失。若源区在复制完成前永久丢失,未到达异地的数据仍可能丢失。当前图承诺的是“已校验恢复点可恢复”的目标,而非已实现的零数据丢失保证。
要实现更强的承诺,需要明确写入确认条件。例如必须等跨区持久化成功才返回写入成功,或者以独立耐久日志作为重放来源,并设计重试、校验、告警与恢复演练。这会增加延迟或实现成本,不能只靠一条“最终一致”虚线获得。
后续设计需要分别确定 RPO(可接受的数据丢失窗口)和 RTO(恢复服务所需时间),以及备份保留、删除传播、加密密钥和数据跨区合规策略。
CDN 应该放在哪里
建议把 CDN 作为面向静态和可缓存内容的边缘路径,与动态 API 调度区分:
- 客户端请求静态前端、文档或允许缓存的对象,优先命中 CDN;命中后直接返回,无需访问 Nexus。
- 缓存未命中时,CDN 回源到指定的 S3 兼容存储,或专门的资源服务。图中仅示例回源到亚洲区域的 S3,并不把亚洲设为唯一源站。
- 私有对象可使用短时签名 URL、受控回源或独立授权服务。缓存键、过期、权限隔离和失效策略需要单独设计。
- 登录、写入、实时连接和个性化动态 API 默认不进入共享缓存。CDN 能代理这些流量,不代表应该缓存这些响应。
CDN 是可替换、可选的加速层,不是数据库副本,也不承担跨区灾难恢复的唯一责任。
身份服务是否依赖 Nexus
建议在逻辑上独立,不把它画成依赖某个业务 Nexus 的服务。 客户端向身份服务登录或刷新凭证;Nexus 验证访问凭证、项目归属和操作权限后才接受业务请求。
图中紫色线路表示公钥或认证配置的分发关系:使用适当的签名访问令牌方案时,Nexus 可以缓存 JWKS,在本地完成签名及必要声明校验。具体访问令牌格式尚未确定,不能把 OpenID Connect 的 ID Token 直接当作所有 API 的授权凭证。
如果采用不透明令牌、即时撤销或实时策略评估,可能需要在线内省或授权查询;这会引入身份服务的在线依赖,需要单独设计可用性和失败策略。已有令牌可离线验证也不意味着公钥轮换、过期、撤销和权限变化可以不处理。
身份服务本身仍可以使用 PostgreSQL、缓存和密钥管理等基础设施;逻辑独立不等于没有存储依赖。将来即使选择在通用 Nexus 基础设施上托管它,也应保留独立的故障和信任边界,避免启动、登录与业务运行时形成循环依赖。
继续确定的设计边界
- 全球入口如何发现项目与分片的归属,跨区域请求采用转发还是让客户端重连。
- Nexus 接入职责与 Aster VM 边界、连接亲和性和 Runtime 故障迁移。
- Aerarium 的数据格式、事务边界、对象版本和跨存储一致恢复点。
- 区域内 HA 的实际协议与跨区域 RPO/RTO、故障读取与恢复流程。
- 身份签发者、访问令牌验证与撤销机制,以及私有内容的 CDN 授权。
参考依据
以下资料仅用于解释通用组件的能力,不证明 Endor 已经实现本文的概念设计:
- Traefik:服务与后端负载均衡。
- OpenID Connect Discovery:配置发现和 JWKS URI。
- Amazon S3:同区与跨区异步复制。本文中的 S3 指兼容对象存储,具体部署并未指定 AWS。