Aeron UDP组播性能为何远低于原生TCP实现?
Aeron UDP组播与原生TCP性能测试疑问
测试配置
Aeron部署配置
- 每个节点运行媒体驱动(MD)进程
- 启动1个Publication和1个Subscriber
原生TCP服务器-客户端配置
- 服务器:单线程推送100万条整数消息
- 客户端:单线程消费消息
测试结果
- Aeron UDP:耗时约17秒
- 原生TCP:耗时约8秒
疑问
按常规认知,UDP组播的性能应该优于TCP,但本次测试结果相反。是否存在认知偏差或遗漏的关键配置?需要检查或调优哪些项来提升Aeron的性能?

TCP Server代码
serverSocket = new ServerSocket(port); while(true) { Socket clientSocket = serverSocket.accept(); Thread t = new Thread(){ @Override public void run() { try{ System.out.println("Starting new thread serving client"); out = new DataOutputStream(clientSocket.getOutputStream()); in = new DataInputStream(new BufferedInputStream(clientSocket.getInputStream())); for (int i = 0; i < 1_000_000; i++) { System.out.println("Server sending..." + i + "..!"); out.writeInt(i); } } catch (IOException e){ // 异常处理省略 } } }; t.start(); }
TCP Client代码
System.out.println("I'm client!"); TcpClient client = new TcpClient(); String serverHost = System.getProperty("host"); try { client.startConnection(serverHost, 6666); DataInputStream in = client.in; long st = System.currentTimeMillis(); int counter = 1_000_000; while(counter > 0) { int v = in.readInt(); // System.out.println("v: " + v); counter--; } long pt = System.currentTimeMillis() - st; System.out.println("Process time of TCP raw: " + pt); } finally { client.stopConnection(); }
性能排查与调优方向
1. Aeron核心配置检查
- 直接内存缓冲区:确认Aeron是否启用直接内存(默认配置),若回退到堆内存会显著降低性能,可通过
aeron.dir参数验证存储路径是否使用了内存映射文件。 - UDP缓冲区大小:系统默认UDP收发缓冲区通常偏小,需调整内核参数(Linux下修改
net.core.rmem_max/net.core.wmem_max至至少1MB以上),同时在Aeron配置中设置socket.send.buffer.size和socket.receive.buffer.size匹配系统值。 - 组播网络配置:确保组播地址在有效范围内,网络设备开启IGMP snooping(避免流量扩散),同时检查是否存在丢包(可通过
tcpdump抓包验证)。 - 批量消息发送:若当前是单条调用
offer()发送单个整数,改为将多条整数打包成一个Aeron消息后发送,减少系统调用和网络帧开销。
2. 测试逻辑对齐
- 消息粒度对比:TCP的
DataOutputStream.writeInt底层可能通过Nagle算法自动批量发送小消息,而Aeron单条发送小消息时,UDP的IP+UDP头部开销占比极高,有效载荷利用率远低于TCP。需调整Aeron的发送逻辑,批量打包消息。 - 计时范围确认:检查Aeron的计时是否包含了媒体驱动初始化、Publication/Subscriber创建等准备时间,而TCP仅统计了消息传输阶段的耗时,需确保两者计时范围一致。
3. 系统与线程优化
- Aeron媒体驱动线程亲和性:将媒体驱动的发送/接收线程绑定到特定CPU核心,避免线程切换开销,可通过配置
aeron.media-driver.cpu-affinity实现。 - 调整linger超时:设置
publication.linger.timeout参数(如1ms),让Aeron攒够一批消息再发送,平衡延迟和吞吐量。 - 关闭不必要的调试输出:若Aeron测试中存在调试日志,会严重影响性能,需关闭所有非必要的日志输出。
内容的提问来源于stack exchange,提问作者trunghuynh.cse
相关产品推荐
相关产品推荐

