202511262222 unix socket 与传统的 tcp 本地通信的异同
202511262222 unix socket 与传统的 tcp 本地通信的异同
在同一台机器里,Unix Socket 和 本地 TCP(127.0.0.1) 都能让两个进程把信息塞进内核,然后再被对方捞出来。但它们的“路径”和“行李检查”不太一样——一个像是走家里的侧门,一个像是走正式大门。
聊聊两者差异时,最好从原理出发,避免落入“因为更快所以更快”这种循环论。下面按特性说清楚:
核心相同点(都是内核里的高速通道)
两者都属于 本地 IPC(进程间通信),数据不会离开本机,不会上网,也不会经过物理网卡。
它们都经历:
- 用户态 → 内核态
- 内核缓冲区里传数据
- 内核态 → 用户态
所以带宽最终也都受制于 CPU、内存带宽、内核协议栈效率,而不是网卡。
关键差异
1. 协议栈层级不同:TCP 比 Unix Socket 多走一大圈
TCP(即便是 127.0.0.1)依然遵守完整 TCP/IP 协议栈:
- TCP 流控
- 拥塞控制(虽然 loopback 几乎没有)
- 序列号
- 校验和
- 包装成 pseudo packet
- 收发队列
- 端口绑定
- 状态机(SYN、ACK)
Unix Socket 则直接在内核里 内存结构体对拷,完全没有报文封装。
结果是:
- Unix Socket 延迟更低
- 系统调用开销更小
- CPU 占用更少
- TCP 在本地仍然有上下文切换、协议处理成本
一个更形象的说法:
TCP 即便在家里走路也要“戴头盔、过安检、检查车票”。
Unix Socket 则是“直接从客厅走到厨房”。
2. 带宽:Unix Socket 一般更高
本地 TCP 的最大带宽常见在 5–12 GB/s
Unix Socket 常见能达到 10–20+ GB/s
这不是固定值,要看内核版本和 CPU 架构,但整体趋势是:
- Unix Socket ≈ TCP 的 1.5–3 倍速度
- 延迟差距更明显:Unix Socket 可缩短几十微秒到 1 微秒级
3. 文件系统 vs 端口
Unix Socket 用文件路径 /var/run/redis.sock 来表示。
TCP 用端口 127.0.0.1:6379。
影响:
- Unix Socket 可以靠文件权限控制访问(chmod、chown)
- TCP 必须靠防火墙或 listen 限制
4. 可扩展性:TCP 更强
Unix Socket:
- 只能本机使用
TCP:
- 本地用着用着,你也可以轻松扩展到远程(换 IP 就行)
- 生态工具多(Wireshark、iptables、所有网络库都能用)
如果将来服务要横向扩展到多机,Unix Socket 就完全没法用了。
5. 连接建立成本
TCP:三次握手
Unix Socket:直接建立进程间管道
影响是:
- 用大量短连接时,Unix Socket 更快
- 长连接场景差距会缩小
6. 调试工具不同
TCP:tcpdump、ss、netstat 都能看
Unix Socket:只能看 ss -x、lsof
什么时候应该用谁?
尽量用 Unix Socket 的场景
- 同机通信
- 高 QPS、高并发
- 服务之间需要极低延迟(比如 nginx → php-fpm、Redis)
- 不需要跨机扩展
Reddit、Stack Overflow、Redis 官方文档都强调:
本地通信优先 unix socket,性能差距可达 30%+
必须用 TCP 的场景
- 未来可能扩到多台机器
- 需要远程调试
- 需要跨容器或 namespace 通信(k8s 里多数情况 TCP 更方便)
- 要用通用的负载均衡、代理工具(iptables、haproxy)
小结(简洁版)
- 性能:Unix Socket > 本地 TCP(更低延迟,更高吞吐)
- 开销:Unix Socket 更小
- 协议:TCP 多一堆逻辑,Unix Socket 直接内核对拷
- 可扩展性:TCP 更强,Unix Socket 只能本地
- 安全性:Unix Socket 可以文件权限更细粒度控制
- 调试性:TCP 更容易抓包调试