EnerOS v0.29.0 版本说明
发布日期:2025-12-07 版本代号:Distributed Git Tag:v0.29.0 支持状态:稳定(Stable) Crate 总数:78(新增 4 个) 测试用例数:10000+(新增 500+)
概述
EnerOS v0.29.0「Distributed」是分布式部署专项版本,使 EnerOS 能够跨多节点运行。省级调度中心的电网规模可达数万节点,单机无法承载完整的拓扑、潮流、时序负载。v0.29.0 将 EnerOS 从单机系统升级为分布式系统,通过节点发现、数据分片、分布式事务、一致性保证四大能力,实现水平扩展。
本版本引入了五大核心能力:分布式部署(Distributed Deployment)、节点发现(Node Discovery)、数据分片(Data Sharding)、分布式事务(Distributed Transaction)、一致性保证(Consistency Guarantee)。集群可从 3 节点扩展至 64 节点,支撑 10 万级电网节点的实时运行。
设计哲学上,v0.29.0 坚持「分区容忍优先」——在网络分区时优先保证可用性(AP),关键操作通过 quorum 保证一致性;「数据本地性」——按电气拓扑分片,使大部分计算在本地完成;「透明扩展」——应用层 API 不变,分布式细节由内核处理。
关键数据
| 指标 | 数值 | 说明 |
|---|---|---|
| 最大集群规模 | 64 节点 | 水平扩展 |
| 节点发现延迟 | < 2s | 新节点加入 |
| 分片迁移时间 | < 30s | 单分片 |
| 分布式事务延迟 | 15ms | 2PC |
| 数据本地性 | 92% | 本地访问率 |
| 新增 Crate | 4 | 分布式相关 |
新特性
1. 分布式部署
引入 eneros-distributed Crate,提供分布式集群管理。多节点组成集群,共享拓扑、潮流、时序数据。
集群创建
use eneros_distributed::{Cluster, ClusterConfig, NodeRole};
let cluster = Cluster::new("dispatch-cluster")
.config(ClusterConfig {
seed_nodes: vec!["node-1:7946", "node-2:7946"],
data_dir: "/var/lib/eneros",
replication_factor: 3,
shard_count: 32,
})
.join("node-1:7946").await?;
// 查看集群状态
let status = cluster.status().await?;
println!("节点数: {}", status.node_count);
println!("分片数: {}", status.shard_count);
println!("健康节点: {}", status.healthy_nodes);
节点角色
| 角色 | 职责 | 数量 | 说明 |
|---|---|---|---|
| Coordinator | 协调事务 | 3-5 | 通过选举 |
| DataNode | 存储分片 | 全部 | 承载数据 |
| ComputeNode | 计算节点 | 全部 | 执行计算 |
| Gateway | 入口网关 | 2+ | 负载均衡 |
2. 节点发现
引入 eneros-distributed-discovery Crate,提供节点自动发现与成员管理。基于 SWIM 协议(Gossip 改进),实现高效的成员关系维护。
节点加入
use eneros_distributed_discovery::{Discovery, NodeInfo};
let discovery = Discovery::new(&cluster)
.gossip_interval(Duration::milliseconds(200))
.probe_timeout(Duration::milliseconds(500));
// 新节点加入
let node = NodeInfo::new("node-5")
.address("10.0.1.5:7946")
.roles(vec![NodeRole::DataNode, NodeRole::ComputeNode])
.capacity(Capacity {
cpu: 32,
memory_gb: 128,
disk_gb: 2000,
});
discovery.join(node).await?;
// 自动广播至全集群,2s 内所有节点感知
故障检测
// SWIM 协议故障检测
discovery.on_node_failure(|node| async move {
log::warn!("节点 {} 失联", node.id);
// 自动触发分片迁移
cluster.rebalance_on_failure(node).await?;
// 通知智能体重编排
swarm.on_node_failure(node).await?;
});
发现协议对比
| 协议 | 检测延迟 | 网络开销 | 适用规模 |
|---|---|---|---|
| 心跳 | 3-15s | O(n) | < 10 节点 |
| Gossip | 1-5s | O(log n) | < 100 节点 |
| SWIM | 1-3s | O(log n) | < 1000 节点 |
3. 数据分片
引入 eneros-distributed-sharding Crate,提供数据分片能力。按电气拓扑分片,使大部分计算在本地完成。
分片策略
use eneros_distributed_sharding::{ShardManager, ShardStrategy};
let sharding = ShardManager::new(&cluster)
.strategy(ShardStrategy::TopologyBased)
.shard_count(32);
// 按电气区域分片
sharding.assign(&network).await?;
// 区域 A 的设备 → 分片 0-7
// 区域 B 的设备 → 分片 8-15
// ...
// 查询分片位置
let location = sharding.locate(BusId::from(42))?;
println!("母线 42 在分片 {} (节点 {})", location.shard, location.node);
分片迁移
// 节点故障时自动迁移分片
sharding.migrate(
from: "node-3",
to: "node-5",
shards: vec![8, 9, 10],
).await?;
// 在线迁移,不中断服务
分片策略对比
| 策略 | 数据本地性 | 迁移频率 | 适用场景 |
|---|---|---|---|
| 哈希分片 | 50% | 低 | 通用 |
| 范围分片 | 70% | 中 | 时序 |
| 拓扑分片 | 92% | 高 | 电网 |
| 一致性哈希 | 60% | 低 | 弹性 |
4. 分布式事务
引入 eneros-distributed-tx Crate,提供跨节点事务保证。支持 2PC(两阶段提交)与 Saga 两种模式。
2PC 事务
use eneros_distributed_tx::{Transaction, TxCoordinator};
let coordinator = TxCoordinator::new(&cluster);
// 跨节点事务:同时操作多个分片
let mut tx = Transaction::new();
tx.add(Operation::UpdateBus(42, voltage: 1.02)); // 分片 3
tx.add(Operation::OpenSwitch(15)); // 分片 7
tx.add(Operation::AdjustGen(1, mw: 200.0)); // 分片 2
match coordinator.commit_2pc(tx).await {
Ok(_) => println!("事务提交成功"),
Err(TxError::ParticipantAbort { node, reason }) => {
println!("节点 {} 拒绝: {}", node, reason);
// 自动回滚
}
}
Saga 模式
// 长事务:Saga 模式(补偿事务)
let saga = Saga::new("fault-recovery")
.step(Step::new("isolate")
.action(|ctx| isolate_fault(ctx))
.compensation(|ctx| restore_isolated(ctx)))
.step(Step::new("transfer")
.action(|ctx| transfer_load(ctx))
.compensation(|ctx| restore_load(ctx)))
.step(Step::new("restore")
.action(|ctx| restore_power(ctx))
.compensation(|ctx| cut_power(ctx)));
saga.execute().await?;
事务特性
| 模式 | 一致性 | 延迟 | 可用性 | 适用场景 |
|---|---|---|---|---|
| 2PC | 强 | 15ms | 低 | 关键操作 |
| Saga | 最终 | 5ms | 高 | 长流程 |
| TCC | 强 | 8ms | 中 | 资源预留 |
5. 一致性保证
引入 eneros-distributed-consistency Crate,提供多级一致性保证。不同数据类型采用不同一致性级别。
一致性级别
use eneros_distributed_consistency::{Consistency, ReadOptions};
// 强一致性读(总是读最新值)
let bus = cluster.read(BusId::from(42), ReadOptions {
consistency: Consistency::Strong,
}).await?;
// 因果一致性读(读到因果上最新的值)
let event = cluster.read_event(event_id, ReadOptions {
consistency: Consistency::Causal,
}).await?;
// 最终一致性读(读任意副本)
let metric = cluster.read_metric("load", ReadOptions {
consistency: Consistency::Eventual,
}).await?;
复制策略
// 数据复制
let replication = Replication::new()
.factor(3) // 3 副本
.mode(ReplicationMode::Sync) // 同步复制
.placement(PlacementPolicy::rack_aware()); // 跨机架
cluster.set_replication(replication).await?;
一致性矩阵
| 数据类型 | 一致性 | 复制 | 写入延迟 | 适用场景 |
|---|---|---|---|---|
| 拓扑数据 | 强 | 同步 3 副本 | 15ms | 开关状态 |
| 潮流结果 | 强 | 同步 3 副本 | 15ms | 计算结果 |
| 时序数据 | 最终 | 异步 3 副本 | 1ms | 遥测数据 |
| 审计日志 | 强 | 同步 3 副本 | 15ms | 合规要求 |
| 缓存 | 最终 | 单副本 | 0.1ms | 性能优先 |
改进
- 网络层:从 TCP 切换至 QUIC,多路复用降低连接建立延迟 60%
- 序列化:从 JSON 切换至 MessagePack,序列化体积减少 50%
- 压缩:时序数据传输启用 Zstandard 压缩,带宽占用减少 70%
- 负载均衡:新增自适应负载均衡器,根据节点负载动态调整分片
Bug 修复
- 修复
eneros-distributed-discovery在网络分区时的脑裂问题(#2908) - 修复
eneros-distributed-sharding分片迁移时的数据丢失风险(#2913) - 修复
eneros-distributed-tx2PC 协调者故障时的事务悬挂问题(#2918) - 修复
eneros-distributed-consistency同步复制在慢节点下的超时问题(#2923)
破坏性变更
Cluster::new:新增ClusterConfig参数,需提供分片与副本配置read/writeAPI:新增ReadOptions/WriteOptions参数,指定一致性级别
升级指南
- 执行
cargo update -p eneros-distributed - 为
Cluster::new提供ClusterConfig - 为读写操作添加一致性级别参数
- 参考
docs/migration/v0.29.0.md获取详细迁移步骤