2014-11-10 9 views
11

Mam aplikację Flask działającą pod kontrolą Gunicorn, używając typu procesu synchronizacji z 20 procesami roboczymi. Aplikacja odczytuje wiele danych podczas uruchamiania, co zabiera czas i wykorzystuje pamięć. Co gorsza, każdy proces ładuje swoją własną kopię, co powoduje, że trwa jeszcze dłużej i zabiera 20X pamięci. Dane są statyczne i nie ulegają zmianie. Chciałbym załadować go raz i udostępnić go wszystkim 20 pracownikom.Udostępnianie statycznych danych globalnych pomiędzy procesami w aplikacji Gunicorn/Flask

Jeśli używam ustawienia preload_app, ładuje się tylko w jednym wątku i początkowo zajmuje tylko 1X pamięci, ale wydaje się baloon do 20X, gdy żądania przychodzą. Potrzebuję szybki losowy dostęp do danych, więc " d raczej nie należy wykonywać IPC.

Czy istnieje sposób na udostępnianie danych statycznych w procesach Gunicorn?

Odpowiedz

4

Pliki mapowane w pamięci umożliwiają udostępnianie stron między procesami.

https://docs.python.org/2/library/mmap.html

Należy zauważyć, że statystyki zużycie pamięci są zwykle mylące i bezużyteczny. Zazwyczaj lepiej jest wziąć pod uwagę wyjście vmstat i zobaczyć, czy często się wymieniasz.

+0

Chyba powinienem powiedzieć, że chciałem podzielić się normalnym dyktando Pythona, a nie tylko kroplą pamięci. –

+0

@DoctorJ Więc nie masz szczęścia. Powodem jest to, że struktura danych Pythona to tylko wskaźniki do wskaźników w pamięci, które będą obejmować wiele stron. Większość z tych stron zostanie również udostępniona wraz z danymi, do których została zapisana, dlatego kopiowanie przy zapisie powoduje, że strony są duplikowane w każdym procesie. Polecam używanie magazynu obiektów lub magazynu klucz-wartość, takiego jak Redis - jest to "standardowe" rozwiązanie tego problemu. IPC na localhost jest bardzo szybki, prawdopodobnie optymalizujesz się przedwcześnie, jeśli uważasz, że będzie to wąskie gardło. – aaa90210

1

Zakładając, że priorytetem jest zachowanie danych w postaci struktury danych Pythona zamiast przenoszenia ich do bazy danych, takiej jak Redis, trzeba będzie zmienić elementy, aby można było korzystać z pojedynczego procesu dla serwera.

Gunicorn może współpracować z gevent, aby utworzyć serwer obsługujący wielu klientów w ramach jednego procesu roboczego za pomocą współprogramów, który może być dobrym rozwiązaniem dla Twoich potrzeb.

+0

Czy możesz wyjaśnić to więcej? Brzmi potencjalnie cennie, ale nie jestem pewien, jak by to działało. – Eli

+0

Nie ma dużej różnicy, Flask wyciąga cię z danych. kiedy używasz gevent, wystarczy, że upewnisz się, że funkcje widoku robią to, co trzeba, bez zajmowania dużych ilości czasu procesora (lub ustępując, jeśli są długotrwałymi zadaniami). Wielozadaniowość uzyskuje się poprzez umieszczanie każdego żądania w postaci współprowadzącej, ale wszystko to jest obsługiwane przez framework. – Miguel

+0

Mam na myśli więcej na temat uzyskiwania kodu do uruchomienia tylko w procesie nadrzędnym, który generuje dane i aktualizuje je. Bardzo podobne do tego pytania: http://stackoverflow.com/questions/13768894/run-startup-code-in-parent-z-django-and-gunicorn – Eli

Powiązane problemy