【发布时间】:2021-08-06 23:55:33
【问题描述】:
我手头有一项特殊的小任务,但我不知道如何最好地实施解决方案。
我有三个工作站通过带宽为 40gbps 的 InfiniBand 连接到运行 Ubuntu 20.04 LTS 的 NAS。此 NAS 配备 2TB NVMe SSD 作为写入缓存,以及 7 个 RAID0 单元作为主存储。
这些工作站会将原始数据输出到此 NAS 以供以后使用,每台机器每天都会输出大约 6TB 的数据文件,每个文件的大小在 100 到 300 GB 之间。为了防止网络过于拥挤,我让他们先将数据输出到 NVMe 缓存,然后我计划从那里分发数据文件 - 每个 RAID0 单元同时分配一个文件以最大化磁盘 IO。例如,file1 到 array0,file2 到 array1,file3 到 array2,等等。
现在我正在 NAS 端编写一个脚本(最好是 systemd 服务,但我可以使用 nohup)来监控缓存,并将文件发送到这些 RAID 阵列。
这是我想出的,感谢this post,它非常接近我的目标。
import queue, threading, os, time
import shutil
bfr_drive = '/home/test_folder' # cache
ext = ".dat" # data file extension
array = 0 # simluated array as t0-t6
fileList = [] # list of files to be moved from cache to storage
destPath = '/home/test_folder/t'
fileQueue = queue.Queue()
class ThreadedCopy:
totalFiles = 0
copyCount = 0
array = 0
lock = threading.Lock()
def __init__(self):
for file_name in os.listdir(bfr_drive):
if file_name.endswith(ext):
fileList.append(os.path.join(bfr_drive, file_name))
fileList.sort()
self.totalFiles = len(fileList)
print (str(self.totalFiles) + " files to copy.")
self.threadWorkerCopy(fileList)
def CopyWorker(self):
global array
while True:
fileName = fileQueue.get()
shutil.copy(fileName, destPath+str(array))
array += 1
if array > 6:
array = 0
fileQueue.task_done()
with self.lock:
self.copyCount += 1
percent = (self.copyCount * 100) / self.totalFiles
print (str(percent) + " percent copied.")
def threadWorkerCopy(self, fileNameList):
# global array
for i in range(4):
t = threading.Thread(target=self.CopyWorker)
t.daemon = True
t.start()
# array += 1
# if array > 6:
# array = 0
print ("current array is:" + str(array)) # output prints array0 for 4 times, did not iterate
for fileName in fileNameList:
fileQueue.put(fileName)
fileQueue.join()
ThreadedCopy()
现在,Python 脚本可以成功分发文件,但只能在 for i in range(4) 中的数字之后。例如,如果我将它设置为 4,那么工作人员将对前 4 个文件使用相同的路径(array0),然后他们才会开始遍历数组到 1、2、3 等。
有人能指出我如何分发这些文件吗?我认为我正朝着正确的方向前进,但是,我无法理解为什么这些工人一开始就被困在同一个目录中。
编辑:我有早期版本的代码,其中路径迭代处于生成过程threadWorkerCopy。我现在把它移到了实际的工作函数CopyWorker。问题仍然存在。
【问题讨论】:
-
我是否理解正确,您要将第一个文件复制到
t0,将第二个文件复制到t1,将第三个文件复制到t2等等,将第7个文件复制到t68th文件到t0等等?请edit您的问题澄清这一点。 -
当我测试你的代码时,
print ("current array is:" + str(array))的输出会从 1 迭代到 4,但所有CopyWorker线程随后将使用值 4 并且 not 稍后开始迭代. -
@Bodo 是的。我想让file1到array0,file2到array1,file3到array2等等。
-
请edit您的问题添加此说明。有关您的问题的所有信息都应该在问题中,而不是在 cmets 中。
-
@Bodo 这让它更奇怪了。我认为发生的事情是迭代路径没有传递给
CopyWorker。但即使是产生工作者本身的过程也是一个迭代循环。真的,真的很奇怪。
标签: python python-3.x linux multithreading