is it possible to share memory between uwsgi proce

2020-06-16 08:52发布

问题:

I want to know whether a flask app running on uwsgi with multiple processes+threads can access a common memory data structure defined inside the Flask app class.

What I am trying to do: I have a flask app which will run on nginx + uwsgi. I want every http request to access some data which is lying in an etcd DB. However, this is slow. To speed up the http responses, I am thinking of loading the data from DB into the flask app's memory when the flask app starts. Therefore, on every request, this data can be quickly accessed from local memory instead of asking etcd.

How I am trying to do this: I have defined my own Flaskapp class and inherited it from "Flask" and have overridden "init" to load pre-appstart state:

class FlaskApp(Flask):

    def __init__(self, *args, **kwargs):
        self.populate_info() # This function will load stuff
        super(FlaskApp, self).__init__(*args, **kwargs)
    def populate_info(self):
        self.stuff = []
        #load stuff from db to self.stuff

Will every flask request be able to read self.stuff? Coming from a C++ background, as per my understanding, this depends on how uwsgi runs the flask app. So I need the answer to: 1) Does every uwsgi process instantiate the Flask App ? 2) Or does uwsgi instantiates the Flask App instance once in memory, shares it between every process, and then every process calls only the http request handlers of this instance on every request? I tried searching docs to understand how uwsgi schedules this, but could not find enough information to understand this. So will appreciate any help. If this memory sharing won't work(which is my hunch), what is an alternative way to do so? Thanks.

回答1:

After digging a bit deeper into the uwsgi docs, I found that there are 2 modes of function of uwsgi:

  1. Pre-forking: This is the default mode. In this mode, one main process loads the application and the worker processes are then forked from this main process. This results in the workers having the same memory as the main process until they modify the memory. copy-on-write semantics are followed in this case. So in this context, referring to my code, the state I am loading at app start will be shared by all the workers until they modify it.
  2. Lazy-apps: In this mode, each worker process loads its own application and hence in the context of my code, the populate_info will be called by every worker. But this is of-course not very memory efficient.

I found this link helpful: https://engineering.ticketea.com/uwsgi-preforking-lazy-apps/