V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
skywatcher
V2EX  ›  Python

如何在 fastapi 的多个 app 之间共享全局变量?

  •  
  •   skywatcher · 2020-05-08 21:13:44 +08:00 · 6840 次点击
    这是一个创建于 1691 天前的主题,其中的信息可能已经有所发展或是发生改变。

    用 uvicorn 启动 fastapi,worker 数量大于 1,会启动多个服务,那如何在这些服务间共享全局变量呢? 类似如下案例:

    app = FastAPI()
    
    g_variable = 0
    
    uvicorn.run("app", host="0.0.0.0", workers=4)
    

    如何在启动的 4 个 worker 之间共享变量g_variable

    15 条回复    2020-05-09 19:19:25 +08:00
    xiongotom
        1
    xiongotom  
       2020-05-08 21:30:11 +08:00
    没用过 fastAPI,worker 是线程还是进程,如果是线程,定义一个变量就行了,注意线程安全。如果是进程,只能借助其他工具了,比如用 redis 缓存起来,所有 worker 都从里面取就是了。如果只是个常量,看看创建 worker 的时候可不可以传参,这个得查查 fastAPI 的文档了,有没有可以定义全局配置的接口
    ericls
        2
    ericls  
       2020-05-08 21:39:30 +08:00 via iPhone
    存 redis
    ClericPy
        3
    ClericPy  
       2020-05-08 21:39:39 +08:00
    多个进程, multiprocessing.shared_memory 或者 SharedMemory 貌似有些小坑, 没敢用, 我是正好内网有 Redis, 直接 Redis 里做的读写参数...

    至于 Unix domain socket 这个东西... 用过的见仁见智

    如果变量不会修改, 直接丢启动时候的环境变量或者系统变量比较省心

    如果要修改, 参考上面的...

    如果经常要通信, 进程通信那一堆, 异步 mq 同步 rpc...
    skywatcher
        4
    skywatcher  
    OP
       2020-05-08 21:40:39 +08:00
    @xiongotom
    数据量不小,通过 redis 等中间介质传输影响效率,暂未考虑
    worker 是进程,是通过 uvicorn 启动的,但是 uvicorn 没有提供传入其他参数的入口。之前用 tornado 是可以自己传入需要的参数的。
    qdzzyb
        5
    qdzzyb  
       2020-05-08 21:54:46 +08:00
    多线程 g_variable 共享吧
    qdzzyb
        6
    qdzzyb  
       2020-05-08 21:55:20 +08:00
    感觉得看看 Uvicorn 的实现了
    xiongotom
        7
    xiongotom  
       2020-05-08 23:12:31 +08:00
    @skywatcher 进程之间反正数据隔离,应该只能通过中间介质来存储了,共享变量没听说过的。担心 redis 读写和解析影响效率的话,可以每个 worker 开个线程定时读入某个变量。如果数据量大到会占用很多内存,那建议是在 redis 中就拆分数据,按需使用。如果这都不行,建议先对数据做预处理吧,api 这里不适合干这么重的活啊。
    rogwan
        8
    rogwan  
       2020-05-08 23:42:33 +08:00 via iPhone
    内存数据库怎么会影响性能?你这是多大数据量和延时要求?
    cabing
        9
    cabing  
       2020-05-08 23:52:31 +08:00
    用 python,还担心性能。

    redis 和程序在同一机器上,1ms 以内。限制 redis 内存大小就行。

    进程间共享,没有好的共享模型只能这么办。也可以自己撸一个扩展。其实还是没有 redis 方便和便捷。
    pmispig
        10
    pmispig  
       2020-05-09 10:21:22 +08:00
    高端点用共享内存,低端用 /dev/shm,更低端用磁盘文件
    skywatcher
        11
    skywatcher  
    OP
       2020-05-09 16:14:26 +08:00
    @qdzzyb 由于计算的原因,需要多进程,线程没法满足 🙏
    skywatcher
        12
    skywatcher  
    OP
       2020-05-09 16:18:16 +08:00
    @qdzzyb 是的,目前在折腾这块,所以想看看有没有经历过的,或者更好的方案😂
    skywatcher
        13
    skywatcher  
    OP
       2020-05-09 16:19:28 +08:00
    @cabing 不是不行,不优雅,公司 redis 都是中间件集群,也不允许这么安装 redis 用😂
    skywatcher
        14
    skywatcher  
    OP
       2020-05-09 16:24:45 +08:00
    @pmispig 恩恩,现在是在多进程间进行共享,但是用了 uvicorn 后,以前的方式行不通,无法传递共享的变量。可能我需要,晚上写个详细点的案例,大家更清楚
    cabing
        15
    cabing  
       2020-05-09 19:19:25 +08:00
    @skywatcher 公司内网集群也很快,我们内网 redis 集群,90%上的请求都在 1ms 以内,不过是使用 go 或者 c++代码。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4823 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 01:10 · PVG 09:10 · LAX 17:10 · JFK 20:10
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.