首页 > 解决方案 > Cat unix 命令多线程安全吗?在多台主机上寻找并行 mysql 还原

问题描述

我正在尝试将 cat 文件的输出通过管道传输到外部主机。计划对同一文件的多个主机异步执行此操作。有人可以深入了解技术问题的潜在问题吗

细节

正在传输的文件:3GB 的 mysql 转储

转移到一台主机所需的时间 - 9 分钟

Python程序

async def run_command_shell(command):
    """Run command in subprocess (shell).""
    # Create subprocess
    process = await asyncio.create_subprocess_shell(
        command, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
    )

    # Status
    print("Started:", command, "(pid = " + str(process.pid) + ")", flush=True)

    # Wait for the subprocess to finish
    stdout, stderr = await process.communicate()

def main():
    commands = ["cat mysqldump | mysql -u -p -h <hostA>", "cat mysqldump | mysql -u -p -h <hostB>"]
    tasks = [
        run_command_shell(c)
        for c in commands
    ]
    loop = asyncio.get_event_loop()
    commands = asyncio.gather(*tasks)
    results = loop.run_until_complete(commands)
    print(results)

目标

我必须尽快恢复跨 20 台主机的复制。理想情况下,我需要同时恢复 20 台主机上的 mysqldump,以便我可以在大约 10 分钟内恢复复制。如果有任何潜在的限制,我需要积极地将它们分批成尽可能少的批次,以使任何主机上的复制中断时间最短。

问题

  1. Cat unix 命令线程安全吗?多个子进程(在每个子shell中)可以从同一个文件中读取而没有任何问题吗?有没有其他选择?

  2. 我应该寻找的机器性能的任何潜在上限?这样我就可以一次批处理我必须运行的命令数量。

  3. python asyncio是如何工作的,它会分成多个线程吗?这是它自己的线程?

标签: mysqlbashsubprocesspython-asyncio

解决方案


安全:是

阅读本质上不会是不安全的。 写作是线程可以互相踩踏的地方。

据我了解,您有 20 个线程“同时”读取一个文件并将内容写入网络,而其他所有内容都在 20 台其他机器上。

20个线程在读取一个转储文件时不会互相踩踏;事实上,它们可能会互相帮助,因为文件的块将被缓存用于 19 个线程。

然而,20个客户端mysqls,所有的网络冲击都可能引起那里的争用。当然,他们大多是向外“推”东西,但也有一些小动作回来了。同样,一切都是“安全的”。

一种提升

更好的是20个线程:

cat dump | ssh -h hostN ... "mysql -h localhost ..."

即远程运行20个mysql客户端。现在唯一的流量是通过网络传输的 20 个文件副本。它可能会使网络饱和,从而限​​制整体速度。

也许更快

将转储文件压缩(gzip 或其他)到一个新文件(一次)。然后是其中的 20 个:

cat dump.gz | ssh -h histN ... "(gunzip | mysql -h localhost ...)"

这可能会将网络流量减少约 3 倍。但解压缩和原始 zip 会减慢速度。我不知道它是否真的可以更快地完成工作。

(不,20 个 gzip 并不好——它会淹没你的 CPU 内核。)

(对不起,我不知道ssh等的细节。)


推荐阅读