gsutil 多处理和多线程不维持 GCP 实例上的 cpu 使用率和复制率

gsutil multiprocessing and multithreaded does not sustain cpu usage & copy rate on GCP instance

我是 运行 一个脚本,用于将数百万(准确地说是 240 万)图像从几个 gcs 存储桶复制到一个中央存储桶中,所有存储桶都在同一区域中。我最初是从一个 csv 文件开始工作,但将其分成 64 个较小的文件,这样每个进程都可以遍历自己的文件,而不用等待其他文件。当脚本在 GCP 上的 64 vCPU、240 GB 内存实例上启动时,它可以正常运行大约一个半小时。在 75 分钟内复制了 15.5 万个文件。 CPU 使用率持续保持在 99%。此后,CPU 使用率急剧下降至 2%,传输率大幅下降。我真的不确定为什么会这样。我通过在错误目录中创建空白文件来跟踪失败的文件。这样在写入中央错误文件时就没有写锁。代码如下。这不是间距或语法错误,当我复制到 post 时,一些间距被弄乱了。非常感谢任何帮助。

谢谢, 扎克

 import os
 import subprocess
 import csv
 from multiprocessing.dummy import Pool as ThreadPool
 from multiprocessing import Pool as ProcessPool
 import multiprocessing

 gcs_destination = 'gs://dest-bucket/'
 source_1 = 'gs://source-1/'
 source_2 = 'gs://source-2/'
 source_3 = 'gs://source-3/'
 source_4 = 'gs://source-4/'

 def copy(img):
    try:
            imgID = img[0] # extract name
            imgLocation = pano[9] # extract its location on gcs
            print pano[0] + "   " + panoLocation
            source = ""
            if imgLocation == '1':
                    source = source_1 
            elif imgLocation == '2':
                    source = source-2 
            elif imgLocation == '3':
                    source = source_3 
            elif imgLocation == '4':
                    source = source_4 
            print str(os.getpid())
            command = "gsutil -o GSUtil:state_dir=.{} cp {}{}.tar.gz {}".format(os.getpid(), source, imgID , g
            prog = subprocess.call(command, shell="True")
            if prog != 0:
                    command = "touch errors/{}_{}".format(imgID, imgLocation)
                    os.system(command)
    except:
            print "Doing nothing with the error"

def split_into_threads(csv_file):
  with open(csv_file) as f:
            csv_f = csv.reader(f)
            pool = ThreadPool(15)
            pool.map(copy, csv_f)

if __name__ == "__main__":

    file_names = [None] * 64
    # Read in CSV file of all records
    for i in range(0,64):
            file_names[i] = 'split_origin/origin_{}.csv'.format(i)

    process_pool = ProcessPool(multiprocessing.cpu_count())
    process_pool.map(split_into_threads, file_names)

我强烈建议您在 gsutil 上使用“-m”标志来启用多线程复制。

此外,您还可以使用存储传输服务 [1] 在存储桶之间移动数据。

[1] https://cloud.google.com/storage/transfer/

对于 gsutil,我非常同意添加 -m 的多线程建议。此外,复合上传,-o,可能是不必要的和不受欢迎的,因为每个图像的大小不是 GB 并且不需要分成碎片。它们可能在 X-XXMB 范围内。

在您的 python 函数中,您正在调用 gsutil 命令,这些命令又会进一步调用 python 函数。利用 google 为 python 制作的客户端库应该更简洁、更高效,可用 [如下]。 Gsutil 是为交互式 CLI 使用而构建的,而不是以编程方式调用。
https://cloud.google.com/storage/docs/reference/libraries#client-libraries-install-python

此外,对于 gsutil,请查看您的 ~/.boto 文件并查看多处理和多线程值。更强大的机器可以处理更大的线程和进程。作为参考,我使用带有 1 个进程和 24 个线程的 Macbook Pro。我使用以太网适配器和硬线连接到我的办公室,并通过内部 SSD (>450 Mbps) 获得令人难以置信的性能。那是兆位,而不是字节。尽管如此,传输率还是令人印象深刻