在 Docker 个容器之间传输数据的最有效方式是什么
What is the most efficient way to stream data between Docker containers
我每秒有大量字节来自传感器设备(例如视频),这些字节正在被 Docker 容器中的进程读取和处理。
我有第二个 Docker 容器想要读取已处理的字节流(每秒仍然有大量字节)。
读取此流的有效方法是什么?理想情况下,我想让第一个容器写入某种共享内存缓冲区,第二个容器可以从中读取,但我不认为单独的 Docker 容器可以共享内存。也许有一些共享文件指针的解决方案,将文件保存到内存文件系统?
我的目标是最大限度地提高性能并尽可能减少从一个缓冲区到另一个缓冲区的无用数据副本。
编辑:很想为 Linux 和 Windows 提供解决方案。同样,我有兴趣在 C++ 和 python.
中寻找解决方案
使用 mkfifo /tmp/myfifo
创建一个 fifo。与两个容器共享:--volume /tmp/myfifo:/tmp/myfifo:rw
可以直接使用:
来自容器 1:echo foo >>/tmp/myfifo
在容器 2 中:read var </tmp/myfifo
缺点:容器 1 被阻塞,直到容器 2 读取数据并清空缓冲区。
避免阻塞:在两个容器中,运行 在 bash exec 3<>/tmp/myfifo
中。
来自容器 1:echo foo >&3
在容器 2 中:read var <&3
(或例如 cat <&3
)
此解决方案使用来自 bash
的 exec
文件描述符处理。我不知道怎么做,但当然也可以使用其他语言。
使用简单的 TCP 套接字将是我的第一选择。仅当测量表明我们绝对需要从我将回退到的系统或管道或共享内存中榨取最后一点性能时。
根据问题陈述,该进程似乎受限于本地 CPU/mem 资源,限制因素不是外部服务。在那种情况下,生产者和消费者都在同一台机器上(作为 docker 容器)可能会先绑定 CPU 资源——但我会先测量再行动。
开发代码的大部分精力都花在了维护上。所以我赞成主流做法。 TCP 堆栈具有坚如磐石的基础,并尽可能针对性能进行了优化。此外,它还具有更多(完全?)跨平台和框架的可移植性。 Docker 同一主机上的容器在通过 TCP 通信时未命中。如果有一天进程确实达到了资源限制,您可以通过将生产者和消费者拆分到物理主机上来水平扩展——手动或使用 Kubernetes。在这种情况下,TCP 将无缝工作。如果您永远不需要那种级别的吞吐量,那么您也不需要进程间通信的系统级复杂性。
通过 TCP 进行。
我每秒有大量字节来自传感器设备(例如视频),这些字节正在被 Docker 容器中的进程读取和处理。
我有第二个 Docker 容器想要读取已处理的字节流(每秒仍然有大量字节)。
读取此流的有效方法是什么?理想情况下,我想让第一个容器写入某种共享内存缓冲区,第二个容器可以从中读取,但我不认为单独的 Docker 容器可以共享内存。也许有一些共享文件指针的解决方案,将文件保存到内存文件系统?
我的目标是最大限度地提高性能并尽可能减少从一个缓冲区到另一个缓冲区的无用数据副本。
编辑:很想为 Linux 和 Windows 提供解决方案。同样,我有兴趣在 C++ 和 python.
中寻找解决方案使用 mkfifo /tmp/myfifo
创建一个 fifo。与两个容器共享:--volume /tmp/myfifo:/tmp/myfifo:rw
可以直接使用:
来自容器 1:
echo foo >>/tmp/myfifo
在容器 2 中:
read var </tmp/myfifo
缺点:容器 1 被阻塞,直到容器 2 读取数据并清空缓冲区。
避免阻塞:在两个容器中,运行 在 bash exec 3<>/tmp/myfifo
中。
来自容器 1:
echo foo >&3
在容器 2 中:
read var <&3
(或例如cat <&3
)
此解决方案使用来自 bash
的 exec
文件描述符处理。我不知道怎么做,但当然也可以使用其他语言。
使用简单的 TCP 套接字将是我的第一选择。仅当测量表明我们绝对需要从我将回退到的系统或管道或共享内存中榨取最后一点性能时。
根据问题陈述,该进程似乎受限于本地 CPU/mem 资源,限制因素不是外部服务。在那种情况下,生产者和消费者都在同一台机器上(作为 docker 容器)可能会先绑定 CPU 资源——但我会先测量再行动。
开发代码的大部分精力都花在了维护上。所以我赞成主流做法。 TCP 堆栈具有坚如磐石的基础,并尽可能针对性能进行了优化。此外,它还具有更多(完全?)跨平台和框架的可移植性。 Docker 同一主机上的容器在通过 TCP 通信时未命中。如果有一天进程确实达到了资源限制,您可以通过将生产者和消费者拆分到物理主机上来水平扩展——手动或使用 Kubernetes。在这种情况下,TCP 将无缝工作。如果您永远不需要那种级别的吞吐量,那么您也不需要进程间通信的系统级复杂性。
通过 TCP 进行。