You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在FastAPI多Worker场景下共享大内存缓存?

可行解决方案

1. 启用Gunicorn预加载模式(推荐,改动最小)

直接给Gunicorn添加--preload参数启动服务,命令示例:

gunicorn --workers 4 --preload main:app

核心逻辑是Gunicorn会在fork子Worker进程前加载应用及8GB数据。由于你的数据是只读的,Linux写时复制(Copy-On-Write)机制会让所有Worker共享同一份内存页,不会重复占用内存。这样4个Worker仅需8GB内存,同时能利用多CPU核心提升请求处理能力。

注意:若后续业务会修改内存中的数据,会触发写时复制导致内存占用上升,但你的场景是只读数据,完全适配。

2. 单Worker+多线程模式

如果预加载模式存在兼容性问题(比如部分第三方库不支持进程fork),可采用单Worker配合多线程的方式:

gunicorn --workers 1 --threads 4 main:app

单个进程内的多线程会共享内存数据,内存占用仍为8GB。虽然Python的GIL会限制纯Python代码的并行性,但如果你的第三方库是C实现的(多数数据处理类库都是),计算时会主动释放GIL,此时多线程可实现真正的并行处理,有效提升QPS。

3. 进程间共享内存映射

若预加载模式不适用,可通过内存映射(mmap)将大文件直接映射到内存,让所有Worker共享该映射:

import mmap

# 应用启动时完成文件映射
with open("large_data_file.bin", "rb") as f:
    # 映射整个文件到内存,所有进程共享此映射
    mapped_data = mmap.mmap(f.fileno(), length=0, access=mmap.ACCESS_READ)

# 让第三方库从mapped_data读取数据(多数支持类文件对象的库均可直接适配)

这种方式下内存仅保留一份文件映射,所有Worker无需重复加载数据。只要第三方库支持从类文件对象读取数据,几乎无需修改库的内部逻辑,仅需调整数据加载入口即可。

4. 异步Worker+线程池处理CPU任务

若你的端点可改为异步接口,可使用Uvicorn异步Worker配合线程池处理CPU密集任务:

from fastapi import FastAPI
import asyncio
from concurrent.futures import ThreadPoolExecutor

app = FastAPI()
# 根据CPU核心数设置线程池大小
executor = ThreadPoolExecutor(max_workers=4)

# 单进程加载共享的8GB数据,所有线程共享
large_data = load_data_with_third_party_lib()

@app.get("/cpu-intensive")
async def cpu_intensive_task():
    # 将同步CPU任务提交到线程池执行
    result = await asyncio.get_event_loop().run_in_executor(
        executor, process_data, large_data
    )
    return {"result": result}

启动命令使用异步Worker:

gunicorn --workers 2 --worker-class uvicorn.workers.UvicornWorker main:app

若配合--preload参数,多个Worker仍可共享一份内存数据,进一步优化内存占用。

内容的提问来源于stack exchange,提问作者Oleksandr Havrylchyk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 16:55:27