jhthorsen / mojolicious-plugin-openapi

OpenAPI / Swagger plugin for Mojolicious
53 stars 41 forks source link

Plugin causes high server load when many processes launched roughly in parallel #211

Closed minusdavid closed 3 years ago

minusdavid commented 3 years ago

As I noted at https://github.com/jhthorsen/json-validator/issues/246, I'm having an issue where launching 120 processes that use Mojolicious::Plugin::OpenAPI is causing huge server load and slow application start time (about 3 minutes from start to finish instead of 30 seconds).

After a bit of experimenting, I've isolated the cause of the load and latency to be Mojolicious::Plugin::OpenAPI. Without it, the processes start rapidly and there's no load.

I need to do more in-depth profiling, but at a glance when I run a strace on one of the processes, I notice about 30 seconds is spent on about 300 brk syscalls, 1 mmap, and 1 munmap. I have 10 CPUs, which is way more than enough to handle the running workload, but it's not enough to cope with this load.

I suppose one answer would be to allocate more CPUs, but it would be overkill for the workload. It would just help with the startup time I imagine.

I'm wondering if the memory allocation is necessary.

I haven't profiled Mojolicious before so I'll have to look into that...

minusdavid commented 3 years ago

I used swagger-cli to bundle the swagger.json file into 1 file of 10891 lines instead of 53 files. (Alas, it still has 741 internal $ref pointers, although it's better than the 1151 $ref pointers we had before) and now it's taking about 70 seconds to do 763 brk syscalls... and no mmap/munmap calls.

That said... when compared en masse... it's taking about the same amount of time for the total 120 processes to startup. About 3 minutes from first to last.

I don't know that it's directly related to the spec file though since we're running a JSON::Validator->bundle() beforehand to load and validate the spec (before dynamically adding to it at runtime) and it's going super fast.

minusdavid commented 3 years ago

Used JSON_VALIDATOR_DEBUG and it doesn't look like it's related to loading any schema files...

Going to try MOJO_OPENAPI_DEBUG.

Although something weird is going on now because the Mojo processes are eating up all the memory on the server now...

minusdavid commented 3 years ago

Ahh, it's those DEBUG flags. Whatever they were doing, they changed about 30GB more RAM to be used...

minusdavid commented 3 years ago

After hacking on the plugin, it seems that $self->_validator->load_and_validate_schema() is the line in the plugin that is taking a long time to allocate memory. This is for version 1.15... with a JSON::Validator of 1.08, so I know it's ancient...

After hacking on JSON::Validator... the time and memory is being taken in the validate() method as I suspected on https://github.com/jhthorsen/json-validator/issues/246 originally. The _resolve() and schema() methods are working very quickly.

minusdavid commented 3 years ago

Yeah, the problem is definitely in JSON::Validator. I'll close this issue and re-open the one there...