sha*_*ker 5 multithreading python-multithreading python-3.x python-requests concurrent.futures
我正在尝试使用从 Amazon S3 下载大约 3,000 个文件(每个文件的大小可能为 3 MB)requests_futures,但下载速度在大约 900 个后严重减慢,并且实际上开始运行速度比基本的 for 循环慢。
我似乎没有耗尽内存或 CPU 带宽。然而,看起来我机器上的 Wifi 连接速度几乎没有变慢:我从几千个数据包/秒下降到只有 3-4 个。最奇怪的是,在 Python 进程退出并重新启动 wifi 适配器之前,我无法加载任何网站。
到底是什么原因导致了这种情况,我该如何调试它?
如果有帮助,这是我的 Python 代码:
import requests
from requests_futures.sessions import FuturesSession
from concurrent.futures import ThreadPoolExecutor, as_completed
# get a nice progress bar
from tqdm import tqdm
def download_threaded(urls, thread_pool, session):
futures_session = FuturesSession(executor=thread_pool, session=session)
futures_mapping = {}
for i, url in enumerate(urls):
future = futures_session.get(url)
futures_mapping[future] = i
results = [None] * len(futures_mapping)
with tqdm(total=len(futures_mapping), desc="Downloading") as progress:
for future in as_completed(futures_mapping):
try:
response = future.result()
result = response.text
except Exception as e:
result = e
i = futures_mapping[future]
results[i] = result
progress.update()
return results
s3_paths = [] # some big list of file paths on Amazon S3
def make_s3_url(path):
return "https://{}.s3.amazonaws.com/{}".format(BUCKET_NAME, path)
urls = map(make_s3_url, s3_paths)
with ThreadPoolExecutor() as thread_pool:
with requests.session() as session:
results = download_threaded(urls, thread_pool, session)
Run Code Online (Sandbox Code Playgroud)
使用我尝试过的各种方法进行编辑:
time.sleep(0.25)每一次之后future.result()(性能在 900 左右急剧下降)raise_for_status()每当状态大于 200 时调用抛出异常,然后通过将其打印为警告来捕获此异常(不出现警告)print(response.status_code)显示 200,并且没有捕获异常。就其价值而言,我以前能够使用类似的方法在大约 4 秒内从 S3 下载约 1500 个文件,尽管文件要小一个数量级
我今天有时间会尝试的事情:
编辑:看起来线程数是稳定的,但是当性能开始变差时,“空闲唤醒”的数量似乎从几百个飙升到几千个。这个数字是什么意思,我可以用它来解决这个问题吗?
来自未来的编辑 2:我从来没有弄清楚这个问题。我没有在一个应用程序中完成所有工作,而是将文件列表分块,并在单独的终端窗口中使用单独的 Python 调用运行每个块。丑但有效!问题的原因永远是个谜,但我认为这是我当时工作机器网络堆栈深处的某种问题。
| 归档时间: |
|
| 查看次数: |
624 次 |
| 最近记录: |