Aeron 架构概述

1. Aeron 是什么

Aeron 是一个高效率、低延迟的可靠消息传输系统。它基于 UDP 单播/多播和共享内存 IPC,在应用层实现可靠性保证,核心设计目标是最高的吞吐量和最低、最可预测的延迟。

传统 TCP 消息中间件的根本问题:

TCP:  [消息1]→[消息2]→[消息3丢失]→[消息2重传]→...→[消息3]→  ← 队头阻塞
      必须等消息2重传成功才能发消息3,即便消息3和消息2无关

Aeron: [msg1]→[msg2]→[msg3]→[msg2 NAk]→[msg2重传]→[msg4]→  ← 无队头阻塞
       消息3不需要等待消息2完成,接收端后补丢失的消息2

Aeron 通过 Term Buffer 设计NAK 协议Lock-Free 架构 解决这些根本问题。


2. 核心创新

2.1 Term Buffer:三区段日志缓冲区

Aeron 的核心数据结构是一个划分为 3 个 term 的 log buffer:

┌──────────────────────────────┐
│          Term 0              │  ← 当前写入区(active)
├──────────────────────────────┤
│          Term 1              │  ← 已写完,等待清理
├──────────────────────────────┤
│          Term 2              │  ← 最旧的数据
├──────────────────────────────┤
│        Log Meta Data         │  ← 全局元数据(tail counter、term id、状态等)
└──────────────────────────────┘
  • 循环使用:Publisher 写到 Term 0 末尾后翻转到 Term 1(此时 Term 1 成为 active),Term 0 等待清理后复用
  • 零拷贝:数据直接写入内存映射文件,reader 直接读同一块内存
  • Lock-Free:通过原子 CAS 操作推进 tail counter,避免锁竞争

2.2 NAK 可靠性协议

不同于 TCP 的 ACK(确认每个包),Aeron 使用 NAK(Negative Acknowledgment)

Sender                               Receiver
  │                                     │
  │──Data(seq=1)──────────────────────→│ ✓ 收到
  │──Data(seq=2)──────────────────────→│ ✓ 收到
  │──Data(seq=3)──X──(丢失)             │
  │──Data(seq=4)──────────────────────→│ ✓ 收到
  │                                     │
  │←─────Status(1,2,4)+NAK(3)─────────│  "我收到了1,2,4,请重发3"
  │                                     │
  │──Data(seq=3)重传──────────────────→│ ✓ 补齐
  • 接收端只报告”丢了什么”,不确认”收到了什么”
  • 发送端不等待 ACK,持续发送,只在收到 NAK 时重传
  • 避免了 TCP 的滑动窗口队头阻塞

2.3 Lock-Free 设计哲学

所有热路径数据结构避免锁:

  • Term Buffer tail counter:CAS 原子递增,多 producer 线程安全
  • Command Queue:Ring Buffer 实现,单生产者/单消费者或一对多模式
  • Counters:基于 AtomicLong / UnsafeBuffer 的原子计数器

3. 整体架构

Aeron 采用分层架构,核心分为 Java 实现(主代码库)和 C 实现(独立但等效的客户端与驱动):

┌──────────────────────────────────────────────────────────┐
│  应用层                                                    │
│  ├─ Publication (发送消息)                                  │
│  ├─ Subscription (接收消息)                                 │
│  └─ Cluster Client / Archive Client                       │
├──────────────────────────────────────────────────────────┤
│  Client API 层 (aeron-client/)                             │
│  ├─ Aeron: 入口门面,管理 Publication/Subscription          │
│  ├─ ClientConductor: 客户端核心协调器                        │
│  ├─ Publication / ExclusivePublication: 消息发送            │
│  ├─ Subscription / Image: 消息接收                          │
│  └─ DriverProxy: 与 MediaDriver 的进程间通信                │
├──────────────────────────────────────────────────────────┤
│  IPC 通信层 (Shared Memory / Ring Buffer)                  │
│  ├─ Command Ring Buffer (to-driver / to-clients)           │
│  ├─ Broadcast Buffer (driver events → clients)            │
│  ├─ Counters Buffer (指标)                                 │
│  └─ Log Buffers (消息数据)                                  │
├──────────────────────────────────────────────────────────┤
│  Media Driver 层 (aeron-driver/)                           │
│  ├─ DriverConductor: 管理所有 Publication/Subscription     │
│  ├─ Sender: UDP 发送线程 + NAK 处理                         │
│  ├─ Receiver: UDP 接收线程 + 数据分发                        │
│  ├─ Flow Control: Min/Max/Multicast 流控                   │
│  └─ Congestion Control: 拥塞检测与窗口调整                   │
├──────────────────────────────────────────────────────────┤
│  网络传输层 (UDP / IPC)                                     │
│  ├─ UDP Unicast: 单播消息 + MDC (Multi-Destination-Cast)   │
│  ├─ UDP Multicast: 原生多播                                │
│  └─ IPC (Shared Memory): 同机进程间直接内存映射              │
├──────────────────────────────────────────────────────────┤
│  Archive 层 (aeron-archive/)                               │
│  ├─ Recording: 流持久化到磁盘                               │
│  ├─ Replay: 从磁盘回放                                     │
│  └─ Catalog: 索引和元数据管理                                │
├──────────────────────────────────────────────────────────┤
│  Cluster 层 (aeron-cluster/)                               │
│  ├─ ConsensusModule: Raft 共识引擎                         │
│  ├─ Election: Leader 选举                                  │
│  ├─ LogReplication: 日志复制                               │
│  └─ ClusterServiceExtension: 有状态服务接口                 │
└──────────────────────────────────────────────────────────┘

4. 一次消息发送的完整生命周期

结合 初始化流程Client API 的分析,一次消息从发送到接收的完整路径:

┌──────────┐    ┌──────────────┐    ┌─────────┐    ┌──────────┐    ┌───────────┐
│ 启动阶段  │───→│ 消息发送      │───→│ UDP传输  │───→│ 消息接收  │───→│ 可靠性处理 │
│ (一次)   │    │ (每条消息)    │    │ (每帧)  │    │ (每帧)   │    │ (按需)    │
└──────────┘    └──────────────┘    └─────────┘    └──────────┘    └───────────┘

启动阶段(进程启动时执行一次):
  1. MediaDriver 启动:创建 Conductor/Sender/Receiver 线程
  2. 创建共享内存区域(CNC: Command and Control)
  3. Client 通过 Ring Buffer 发送 ADD_PUBLICATION 命令
  4. Driver 创建 Log Buffer(3 个 term + metadata)
  5. Driver 返回 publication 参数给 Client

消息发送:
  1. Publication.offer(buffer) -> 写入 term buffer 的 active term
  2. CAS 推进 tail counter
  3. Sender 线程扫描 term buffer 中的脏数据
  4. Sender 组装 UDP 数据帧并发送
  5. 重复直到消息发送完毕

网络传输:
  1. UDP 帧通过 OS 网络栈发送
  2. 多播场景: 单次 send 到多播组
  3. MDC(单播多目标): 分别发送到每个目标地址

消息接收:
  1. Receiver 线程 poll UDP socket
  2. 解析 DataHeader,提取 streamId/sessionId/position
  3. 将数据写入本地 Image 的 term buffer(重建)
  4. Subscriber 的 poll 回调中读取 term buffer 中的消息

可靠性处理:
  1. Receiver 检测到 gap(seq 跳跃)
  2. Receiver 发送 Status Message + NAK
  3. Sender 收到 NAK,从 term buffer 找到对应数据重传
  4. 数据流持续,不阻塞

5. 关键设计决策

决策 说明 代价
UDP + 应用层可靠 避免 TCP 队头阻塞,可控的重传策略 需要自己实现可靠性
3 个 term 循环 最小化内存占用,term 写完即翻转 term 必须够大以容纳飞行中的数据
NAK 而非 ACK 减少反向流量,只报告丢失 丢包检测有延迟(等后续包到达)
Lock-Free CAS 消除上下文切换,极低延迟 CPU 自旋消耗,单线程吞吐有限
Flyweight 协议帧 直接在 UnsafeBuffer 上读字段,零反序列化 字段顺序和大小固定,扩展性受限
Java + C 双实现 Java 易于开发,C 避免 GC 停顿 两套代码需保持协议兼容
共享内存 IPC 同机进程间延迟极低(~100ns) 仅限同机

6. 各子系统文档入口

子系统 文档 核心类
代码结构 02-代码结构分析 module 布局、Gradle 构建
MediaDriver 03-MediaDriver分析 MediaDriver, DriverConductor, Sender, Receiver
LogBuffer 与协议 04-LogBuffer与协议 LogBufferDescriptor, DataHeaderFlyweight
Client API & IPC 05-ClientAPI与IPC Aeron, Publication, Subscription, ClientConductor
流控与拥塞控制 06-流控与拥塞控制 FlowControl, CongestionControl, LossDetector
Archive 07-Archive分析 ArchiveConductor, Catalog, RecordingSession, ReplaySession
Cluster 08-Cluster分析 ConsensusModuleAgent, Election, RecordingLog, SessionManager
C/C++ 实现 09-C与C++实现 aeronc.h, aeronmd.h, aeron_driver_conductor.c
性能优化技巧 10-性能优化技巧 Lock-Free CAS、堆外内存、VarHandle、缓存行对齐、sendmmsg、热路径无分配

本站访问量

This site uses Just the Docs, a documentation theme for Jekyll.