使用uWSGI解封文件的性能很差

问题描述 投票:0回答:1

我必须解压大约 200 个文件,每个文件都包含一个自定义类,其中包含一个

numpu.ndarray
(形状 500x32)和一些元数据(少量 int 和 str)。 每个文件的大小约为50ko。

这是简化的代码:

#!venv/bin/python3


import random
import pickle

from pathlib import Path


# real live : around 200 files
filenames = ["file1.pickle", "file2.pickle"]
filepaths = [Path(fn) for fn in filenames]


# read all the files and keep them in a list of bytes
# This is for debug purposes : I want to be sure that the unpicking is 
# the time-consuming line.
str_datas = []
for filename in filepaths:
    str_data = filename.read_bytes()
    str_datas.append(str_data)

# shuffle for a reason, see below
random.shuffle(str_datas)

# unpickle the read data
datas = []
num = 0
for str_data in str_datas:
    num += 1
    print(num)
    data = pickle.loads(str_data)  # <---- this line takes 0.02s or 5s !! (see bellow)
    datas.append(data)

因此,此代码运行良好,每次拆取大约需要 0.02 秒。

但是。在我真实的应用程序中,它嵌入在 uWSGI 中,我有一个非常奇怪的行为。

每次运行代码时,一次(且只有一次)unpickle 需要 5 秒而不是 0.02 秒。由于字符串被打乱,所以它总是不同的。

更奇怪的是:每次长拆都是在第55次和第63次拆之间。

我不并行进行 unpickling。也许 uwsgi 可以吗?

有什么想法吗?

python-3.x pickle uwsgi
1个回答
0
投票

uWSGI 不能影响 Python 的 pickling 行为。您的系统中的其他原因可能会导致该问题,例如 IO 性能不佳或缺少缓存。因为问题缺乏细节,比如如何重复问题或使用 Profiler 进行性能分析,所以无法判断。

无论如何,您不应该在 HTTP 请求/响应处理程序中执行长时间运行的操作。 Unpickle 200 个文件听起来像是您不想做的事情。

相反

  • 运行一次性批处理作业或 cron(Dramatiq、Celery)进程来准备数据并将其存储在例如Redis 或临时文件
  • uWSGI 处理程序直接读取数据,并且在 HTTP 请求处理期间不会尝试进行任何处理
  • 设计你的 API,以便 uWSGI 不需要在一次请求中解封 200 个文件
  • 使用酸洗以外的替代数据格式。如果只是数据,您可以使用 Parquet、CSV 等格式。
© www.soinside.com 2019 - 2024. All rights reserved.