V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
lsk569937453
V2EX  ›  程序员

[讨论]文件从磁盘发送到网卡有 zero copy,读写文件有 mmap 这些黑科技,那么一个机器上两个 socket 的通信有没有什么加快速度的方法。

  •  
  •   lsk569937453 · 2020-06-16 16:21:15 +08:00 · 2998 次点击
    这是一个创建于 1650 天前的主题,其中的信息可能已经有所发展或是发生改变。

    架构是一台机器上两个进程, 发送请求:进程 A--->进程 B-->外部资源 可以认为 B 就是代理,A 和 B 通过 socket 通信,A 的所有请求都会请求到 B,然后 B 请求去继续请求外部的资源,将结果返回 A 。

    第 1 条附言  ·  2020-06-17 10:46:32 +08:00

    下面是我用unix socket的测试结果,感觉没有很快啊。

    架构\执行指令次数                                    1w                               5w

    old(client—>redis)                         4.8/4.2/4.2 单位秒      12.8/11.8/11.7 单位秒

    new(client-->本地proxy->redis)      6.5/6.6/6.4 单位秒     24.5/20.5/23 单位秒

    ==============================================================
    在新老架构下,使用一条连接串行执行1W条指令3次,执行5w条指令3次。

    尤其是执行5W条指令的时候,性能差了有一倍哎

    13 条回复    2020-06-19 18:50:16 +08:00
    scukmh
        1
    scukmh  
       2020-06-16 16:22:36 +08:00
    unix domain socket? 不懂,占坑等大佬。
    zhmoll
        2
    zhmoll  
       2020-06-16 16:23:49 +08:00
    UNIX Domain Socket
    xiaoxuxu
        3
    xiaoxuxu  
       2020-06-16 16:42:58 +08:00
    zeromq 有 IPC 协议
    ryd994
        4
    ryd994  
       2020-06-16 18:12:11 +08:00 via Android
    如果必须 socket,那最多就是 sendfile/splice
    用 loopback 的话还多一个网络层,好处如果今后要不同机器,那直接改地址就行

    用 Unix socket 的话更少开销。基本上可以认为用 fifo/pipe 也是一样。但是 Unix socket 能支持不同协议。而 pipe 只有字节流

    如果放开 socket 要求,那 shm 更快,而且不需要 buffer
    Cooky
        5
    Cooky  
       2020-06-16 18:22:12 +08:00 via Android
    不用 socket 直接上管道?
    zivyou
        6
    zivyou  
       2020-06-16 19:04:52 +08:00
    UNIX Domian Socket,底层也是零拷贝
    guonaihong
        7
    guonaihong  
       2020-06-16 19:54:24 +08:00
    你搜索下 dma 。不过要看网卡是否支持。
    zealot0630
        8
    zealot0630  
       2020-06-16 20:12:02 +08:00 via Android
    splice syscall
    ryd994
        9
    ryd994  
       2020-06-16 23:46:35 +08:00 via Android   ❤️ 1
    @zivyou socket 哪来的零拷贝? send recv 都要 buffer,buffer 就是一边一个拷贝
    zivyou
        10
    zivyou  
       2020-06-17 09:32:27 +08:00
    @ryd994 好的。受教了。
    codehz
        11
    codehz  
       2020-06-17 10:24:22 +08:00
    @ryd994 #9 send 可以不用拷贝。。。https://lwn.net/Articles/726917/
    xiaochun41
        12
    xiaochun41  
       2020-06-17 15:33:00 +08:00
    不考虑其他的进程间通信方式么,比如 共享内存,消息队列
    ryd994
        13
    ryd994  
       2020-06-19 18:50:16 +08:00 via Android
    @codehz 1.这不是 Unix socket 传统模型。在超算上我还用过类似的 mpi send/recv,也是发送接收完成之前不能使用 buffer 。还比你说的这个多个 recv 的能力。
    但这不是标准的 bsd socket 。

    2. 说白了就是让应用层来分配和维护 buffer

    使用 splice,效果如下
    A 有 user space 的数据 X0
    写到 pipe 里,拷贝一次得 X1
    B 从 pipe buffer splice 到 socket buffer
    内核处理完 TCP 发送后释放
    拷贝次数和 A 直接 send 一样

    使用 shm,效果如下
    A 处理数据的时候直接放到 shm 里
    B 调用 send,从 shm 拷贝到 socket buffer
    结果还是一次拷贝,但好处是 B 可以看到数据而且能进行一定的操作。splice 则必须直通


    使用你说的 zero copy send,效果如下
    A 有要发送的数据 X0
    zero copy send,没有拷贝到 send buffer
    B 从 socket 里接收,一次拷贝 X1
    B 再 zero copy send,没有拷贝
    总的来看拷贝次数也是一样,但是缺点是 A 和 B 都必须有一套逻辑来维护发送未完成的 buffer
    A 这边比较简单,因为 B 大概率立刻接收。其实加起来和 shm 也差不多。但是 B 这边是出网络,情况就复杂得多。而维护 buffer 的逻辑内核里早就有了,何必重新发明轮子?

    把 shm 和 zero copy send 结合,确实可以做到 zero copy 。缺点就是跨进程协调 buffer 的释放会非常非常蛋疼。

    考虑到各种开销,实际哪个好还真未必
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2334 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 15:55 · PVG 23:55 · LAX 07:55 · JFK 10:55
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.