Forum: PC-Programmierung Wie kann ich meine Python-Flask-API für eine bessere Leistung optimieren?


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Jr M. (maxie21)


Lesenswert?

Ich arbeite derzeit an einem Backend-Entwicklungsprojekt, um eine 
RESTful-API mit Python und Flask zu erstellen. Die 
Backend-Entwicklerseite von Scaler war für mich die primäre Quelle der 
Hilfe, doch mit zunehmender Menge an API-Abfragen habe ich eine 
Verschlechterung der Leistung beobachtet. Besonders in Zeiten hoher 
Auslastung sind die Reaktionszeiten langsamer, als ich es mir gewünscht 
hätte.

Hier ist eine vereinfachte Version meines Flask-API-Codes:
1
from flask import Flask, jsonify
2
3
app = Flask(__name__)
4
5
# Sample data
6
data = [
7
    {"id": 1, "name": "Product A", "price": 10.99},
8
    {"id": 2, "name": "Product B", "price": 15.99},
9
    # More data entries...
10
]
11
12
@app.route('/api/products', methods=['GET'])
13
def get_all_products():
14
    return jsonify(data)
15
16
if __name__ == '__main__':
17
    app.run(debug=True)

Ich glaube, dass ich Optimierungen vornehmen kann, um die Leistung 
meiner Flask-API zu verbessern, aber ich bin mir nicht sicher, wo ich 
anfangen soll. Könnte jemand bitte meinen Code überprüfen und Best 
Practices oder Änderungen vorschlagen, die mir helfen können, bessere 
Antwortzeiten zu erreichen, insbesondere wenn die Anzahl der 
API-Anfragen zunimmt? Danke schön!

Scaler-Artikel- 
https://www.scaler.com/topics/software-engineering/backend-developer-roadmap/

von Bernd (b_b304)


Lesenswert?

Ich weiß nicht ob's bei Dir hilft: 
https://github.com/colour-science/flask-compress

Damit habe ich meine API, die sehr große/viele JSON-Objekte ausliefert, 
ziemlich stark optimieren können. Insbesondere wenn die Bandbreite der 
Flaschenhals ist (Server-Upload zu schwach? Mobiles Endgerät mit 
schlechtem Download?), kann das helfen.

von Clemens L. (c_l)


Lesenswert?

Jr M. schrieb:
> ich bin mir nicht sicher, wo ich anfangen soll

Zuerst solltest du mit einem Profiler herausfinden, was genau langsam 
ist. Es gibt z.B. flask-profiler, oder werkzeug.middleware.profiler.

: Bearbeitet durch User
von Ein T. (ein_typ)


Lesenswert?

Jr M. schrieb:
> Ich glaube, dass ich Optimierungen vornehmen kann, um die Leistung
> meiner Flask-API zu verbessern, aber ich bin mir nicht sicher, wo ich
> anfangen soll. Könnte jemand bitte meinen Code überprüfen und Best
> Practices oder Änderungen vorschlagen, die mir helfen können, bessere
> Antwortzeiten zu erreichen, insbesondere wenn die Anzahl der
> API-Anfragen zunimmt? Danke schön!

1. Wo kommen die Daten her?
2. Wie lange sind die Daten gültig, wie oft kommen neue hinzu, wie bald 
sollen die ausgeliefert werden?
3. Wieviele parallele Requests erwartest Du?
4. Wie groß sind diie Daten?
5. Was soll mit den Daten gemacht werden?
6. Ist Performance wirklich ein Problem? Warum? Woher weißt Du das?
7. Was ist eigentlich dieses "Streaming"?

von Εrnst B. (ernst)


Lesenswert?

Ich würde einen nginx oder caddy als reverse-proxy vor das Flask packen. 
Der kann sich dann um https-Verschlüsselung, Kompression usw. kümmern, 
und bei relativ statischen Sachen wie der Artikelliste auch die Anfragen 
aus einem Cache beantworten. Bei dynamischen Sachen kannst du damit auch 
ein Loadbalancing über mehrere python-Flasks machen.

von Ein T. (ein_typ)


Lesenswert?

Εrnst B. schrieb:
> Ich würde einen nginx oder caddy als reverse-proxy vor das Flask packen.
> Der kann sich dann um https-Verschlüsselung, Kompression usw. kümmern,
> und bei relativ statischen Sachen wie der Artikelliste auch die Anfragen
> aus einem Cache beantworten. Bei dynamischen Sachen kannst du damit auch
> ein Loadbalancing über mehrere python-Flasks machen.

All das würde ich womöglich auch tun -- wenn es denn sinnvoll ist. Nur 
die manchmal geradezu reflexhafte Nutzung von Nginx als Cache erscheint 
mit oft nicht ganz durchdacht -- denn wenn der Output bei NGinx ankommt, 
ist er ja schon vollständig prozessiert und erzeugt. Da können andere 
Caches, die von der Applikation gesteuert werden, viel bessere 
Ergebnisse liefern, indem sie nur jenen Teil der Daten cachen, bei dem 
sich das auch lohnt. So kann die Applikation nach meinen Erfahrungen 
häufg viel stärker entlastet, und die ausgelieferten Daten gleichzeitig 
aktueller gehalten werden. Nebenbei bemerkt: Python hat da eine 
wundervolle Möglichkeit des Cachings einzelner Funktionen im 
Standardmodul "functools", und für Flask gibt es zudem ein 
Caching-Plugin mit dem wenig überraschenden Namen "Flask-Caching".

Wie dem auch sei, gelten hier natürlich dieselben drei Leitsätze wie bei 
allen anderen Performanceoptimierungen:

1. "Premature optimization is the root of all evil" (Donald E. Knuth)
2. "Measure, don't guess" (Kirk Pepperdine)
3. "Make it work, make it right, make it fast" (Kent Beck)

Insofern halte ich es für sinnvoller, zunächst genau zu hinterfragen, 
was der TO vor hat. Danach können wir ihm etwas Konkretes empfehlen... 
und da könnten vielleicht auch gunicorn und gevent eine Rolle spielen?! 
;-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.