Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Research/document gunicorn/gevent settings #4382

Closed
6 tasks
lbeaufort opened this issue May 29, 2020 · 6 comments
Closed
6 tasks

Research/document gunicorn/gevent settings #4382

lbeaufort opened this issue May 29, 2020 · 6 comments

Comments

@lbeaufort
Copy link
Member

lbeaufort commented May 29, 2020

It looks like our applications can start to suffer performance issues when the database is only around 30% CPU. This could be a concurrency issue - I don't know whether this is the best approach for addressing the issue, but we should still research/document gunicorn/gevent settings. I don't know for sure how many concurrent requests we can handle for each app instance.

Helpful article: https://medium.com/building-the-system/gunicorn-3-means-of-concurrency-efbb547674b7
Docs:

To use Async [gevent], you need to be sure that your processing is not compute bound, this means you will not be able to make use of multiple cores. Advantage you get is that the memory that multiple threads would take would not be there. But you have other issues like non monkey patched libraries. Move to Async only if the threaded worker does not meet your requirements.

With gevent:

I would be scared of what modules might not be monkey patched correctly in order to work predictably when Async worker class is used. Async for all its benefits does come with its own risks. You must make absolutely sure that all your code is monkey patched and no native code runs.

Gevent is an alternative to threading where, instead of spawning threads, it runs a libev event loop and monkey patches Python to replace most blocking IO with non-blocking IO. This allows you to write Python in a synchronous style without the complexity of managing threads, while also reaping the benefits of non-blocking IO.

Gevent achieves this concurrency using greenlets, which are a “lightweight pseudo-thread” that work cooperatively via an event loop to yield control to one another while they are waiting for IO. Looking into Gunicorn’s GeventWorker, you can see where it runs Gevent’s monkey patch on startup to replace blocking IO with non-blocking IO.

Gevent and Gunicorn try their best to monkey patch blocking IO in the Python standard library, but they can’t control external C dependencies. This becomes a serious issue in web apps; if your event loop is blocked waiting for a C libraries’ IO, you can’t respond to any requests, even though you have plenty of system resources available.

beware of blocking IO in Gevent applications! It causes non-intuitive and difficult-to-diagnose performance issues.

Completion criteria

  • Consider reaching out to cloud.gov for support hours
  • Read the docs for version we're using and most recent stable version

    openFEC/requirements.txt

    Lines 19 to 20 in ce36d69

    gunicorn==19.10.0
    gevent==1.4.0
  • Determine our concurrency capabilities
    • Identify how to measure and log - Kibana report of requests per second?
  • Consider adding gunicorn threads
  • Open up follow up tickets to test any changes using locust
@lbeaufort
Copy link
Member Author

I checked the PI planning document and this is slated for 13.2

@rfultz rfultz modified the milestones: Sprint 14.3, Sprint 14.4 Apr 6, 2021
@rfultz rfultz modified the milestones: Sprint 14.4, Sprint 14.5 Apr 16, 2021
@lbeaufort lbeaufort modified the milestones: Sprint 14.5, Sprint 14.6 Apr 29, 2021
@lbeaufort lbeaufort removed their assignment Jun 1, 2021
@lbeaufort lbeaufort modified the milestones: Sprint 15.2, Sprint 15.3 Jun 17, 2021
@lbeaufort lbeaufort modified the milestones: Sprint 15.3, Sprint 15.4 Jun 29, 2021
@lbeaufort lbeaufort modified the milestones: Sprint 15.4, Sprint 15.5 Jul 14, 2021
@patphongs
Copy link
Member

Moving to 15.6 due to resource constraints

@patphongs
Copy link
Member

Research has been done with this, however, measuring per second requests has been a blocker. We'll revisit when we have more resources in the feature.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants