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] 在存储桶之间移动数据。
对于 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) 获得令人难以置信的性能。那是兆位,而不是字节。尽管如此,传输率还是令人印象深刻
我是 运行 一个脚本,用于将数百万(准确地说是 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] 在存储桶之间移动数据。
对于 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) 获得令人难以置信的性能。那是兆位,而不是字节。尽管如此,传输率还是令人印象深刻