用 uvicorn 启动 fastapi,worker 数量大于 1,会启动多个服务,那如何在这些服务间共享全局变量呢? 类似如下案例:
app = FastAPI()
g_variable = 0
uvicorn.run("app", host="0.0.0.0", workers=4)
如何在启动的 4 个 worker 之间共享变量g_variable
?
1
xiongotom 2020-05-08 21:30:11 +08:00
没用过 fastAPI,worker 是线程还是进程,如果是线程,定义一个变量就行了,注意线程安全。如果是进程,只能借助其他工具了,比如用 redis 缓存起来,所有 worker 都从里面取就是了。如果只是个常量,看看创建 worker 的时候可不可以传参,这个得查查 fastAPI 的文档了,有没有可以定义全局配置的接口
|
2
ericls 2020-05-08 21:39:30 +08:00 via iPhone
存 redis
|
3
ClericPy 2020-05-08 21:39:39 +08:00
多个进程, multiprocessing.shared_memory 或者 SharedMemory 貌似有些小坑, 没敢用, 我是正好内网有 Redis, 直接 Redis 里做的读写参数...
至于 Unix domain socket 这个东西... 用过的见仁见智 如果变量不会修改, 直接丢启动时候的环境变量或者系统变量比较省心 如果要修改, 参考上面的... 如果经常要通信, 进程通信那一堆, 异步 mq 同步 rpc... |
4
skywatcher OP @xiongotom
数据量不小,通过 redis 等中间介质传输影响效率,暂未考虑 worker 是进程,是通过 uvicorn 启动的,但是 uvicorn 没有提供传入其他参数的入口。之前用 tornado 是可以自己传入需要的参数的。 |
5
qdzzyb 2020-05-08 21:54:46 +08:00
多线程 g_variable 共享吧
|
6
qdzzyb 2020-05-08 21:55:20 +08:00
感觉得看看 Uvicorn 的实现了
|
7
xiongotom 2020-05-08 23:12:31 +08:00
@skywatcher 进程之间反正数据隔离,应该只能通过中间介质来存储了,共享变量没听说过的。担心 redis 读写和解析影响效率的话,可以每个 worker 开个线程定时读入某个变量。如果数据量大到会占用很多内存,那建议是在 redis 中就拆分数据,按需使用。如果这都不行,建议先对数据做预处理吧,api 这里不适合干这么重的活啊。
|
8
rogwan 2020-05-08 23:42:33 +08:00 via iPhone
内存数据库怎么会影响性能?你这是多大数据量和延时要求?
|
9
cabing 2020-05-08 23:52:31 +08:00
用 python,还担心性能。
redis 和程序在同一机器上,1ms 以内。限制 redis 内存大小就行。 进程间共享,没有好的共享模型只能这么办。也可以自己撸一个扩展。其实还是没有 redis 方便和便捷。 |
10
pmispig 2020-05-09 10:21:22 +08:00
高端点用共享内存,低端用 /dev/shm,更低端用磁盘文件
|
11
skywatcher OP @qdzzyb 由于计算的原因,需要多进程,线程没法满足 🙏
|
12
skywatcher OP @qdzzyb 是的,目前在折腾这块,所以想看看有没有经历过的,或者更好的方案😂
|
13
skywatcher OP @cabing 不是不行,不优雅,公司 redis 都是中间件集群,也不允许这么安装 redis 用😂
|
14
skywatcher OP @pmispig 恩恩,现在是在多进程间进行共享,但是用了 uvicorn 后,以前的方式行不通,无法传递共享的变量。可能我需要,晚上写个详细点的案例,大家更清楚
|
15
cabing 2020-05-09 19:19:25 +08:00
@skywatcher 公司内网集群也很快,我们内网 redis 集群,90%上的请求都在 1ms 以内,不过是使用 go 或者 c++代码。
|