Performance issues with dynamic/static multi process management
Recently I faced issues with significant latency and delays during periods of scaling or when new requests arrive after periods of processes idleness.
Environment:
- Unit version: 1.31.1 (Alpine 3.18 - php82)
- Application type: PHP (Symfony)
- Traffic: ~5K requests/minute
- Resources: 5 pods - 1 core / 512mb memory per instance
Details:
- Dynamic Process Configuration:
First I configured Unit to dynamically manage processes (scaling up from idle), I noticed considerable latency in processing incoming requests. This is particularly evident after deployments, processes scaling operations or when new requests hit a pod with a process that has been idle. The process latency manifests as delays and lags in request processing, leading to sporadic timeout errors (more than 3 seconds).
"applications": {
"symfony": {
"type": "php",
"processes":{
"max":10,
"spare":5,
"idle_timeout":500
},
"limits": {
"timeout": 10,
"requests": 10000
},
"targets": {
"direct": {
"root": "/app/public/"
},
"index": {
"root": "/app/public/",
"script": "index.php"
}
}
}
}
- Static Process Configuration:
Adjusting the configuration to use a static number of processes reduces the frequency of these issues but does not eliminate them. The problem persists, particularly during deployment and scaling operations, where the initial requests to a newly started pod experience significant delays.
"applications": {
"symfony": {
"type": "php",
"processes": 10,
"limits": {
"timeout": 10
},
"targets": {
"direct": {
"root": "/app/public/"
},
"index": {
"root": "/app/public/",
"script": "index.php"
}
}
}
}
- Single Process Per Pod:
Configuring it to run only one process per pod seems to resolve these latency issues. However, this approach is really a resource-intensive especially considering amount of pods to create / memory consumption I need to allocate per pod.
Steps to Reproduce:
- Deploy a a very simple PHP application on Docker/Kubernetes with nginx Unit, configured for dynamic process management (2 or more)
- Simulate traffic (10 req/sec)
- Observe the latency in processing the initial batch of requests after running the container
- Stop traffic (and wait till you reach the
processes.idle_timeout) and try again
Please let me know if you need more details or I miss something in the configuration.
Thanks for reporting this to us. We are currently working on some enhancements to our PHP implementation and I am more than happy to put this one to the list of things we are looking into.
Would you mind sharing the Dockerfile you are using?
Unit version: 1.31.1 (Alpine 3.18 - php82)