Bug 1726337
Summary: | Frequent clone System-Calls with Apache, Perl and CURL with Threaded Resolver | ||
---|---|---|---|
Product: | Red Hat Enterprise Linux 7 | Reporter: | Shao Miller <smiller> |
Component: | curl | Assignee: | Kamil Dudka <kdudka> |
Status: | CLOSED NOTABUG | QA Contact: | Daniel Rusek <drusek> |
Severity: | low | Docs Contact: | |
Priority: | unspecified | ||
Version: | 7.6 | CC: | kdudka |
Target Milestone: | rc | ||
Target Release: | --- | ||
Hardware: | All | ||
OS: | Linux | ||
Whiteboard: | |||
Fixed In Version: | Doc Type: | If docs needed, set a value | |
Doc Text: | Story Points: | --- | |
Clone Of: | Environment: | ||
Last Closed: | 2019-07-03 15:45:02 UTC | Type: | Bug |
Regression: | --- | Mount Type: | --- |
Documentation: | --- | CRM: | |
Verified Versions: | Category: | --- | |
oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
Cloudforms Team: | --- | Target Upstream Version: | |
Embargoed: |
Description
Shao Miller
2019-07-02 15:53:25 UTC
c-ares cannot be used for the system libcurl package because it bypasses the system Name Service Switch (NSS) stack. We tried to make libcurl use c-ares in Fedora 13 and failed, see bug #554305 for instance. Why exactly is "many clone syscalls" a problem for you? Thank you for your response, Kamil Dudka. libcurl's threaded-resolver threads' 'clone' system-calls: - Cause noise into 'strace' during analysis. (Filtering out 'clone' syscalls would then interfere with capturing non-libcurl 'clone' syscalls.) - Come and go with web-requests instead of lasting for the duration of the Apache child-process. - Seem unnecessary, as a blocking model is expected for these web-requests. Using c-ares is unimportant, but I noticed it as the alternative and it seems like a better fit, with respect to these three points, above. I've read bug #554305 and understand the other limitations that were discussed for c-ares, in that bug. I have not yet noticed a performance-problem, with respect to requests-per-second nor to web-response time. (Since the web-request blocks anyway, I can't imagine that the threaded-resolver strategy could be any faster, with its setup and tear-down.) Do you suppose that a request to curl to offer a blocking DNS resolution-mode (perhaps via environment-variable or some other mechanism) would be better than filing this bug-report for Red Hat's curl? libcurl needs a separate thread for DNS resolution to implement a non-blocking interface on top of the blocking interface provided by system's DNS resolver. The libcurl "multi" API allows you to run multiple transfers in parallel without using any threads in your application (and without using any threads in libcurl itself, except for DNS resolution). Without the threaded resolver, you would not be able to implement any timeout for DNS resolution (except the siglongjmp-based hack, which does not work reliably). If you want to lower the number of clone() syscalls, you can try sharing libcurl's DNS cache between your requests and/or reuse existing connections. libcurl's "multi" API seems to fit better with an event-driven loop, using 'epoll', 'kqueue', etc. That seems like a better fit for Apache's "event MPM". This seems modern and fast. Using Apache's "prefork MPM" (multiple child-processes) and non-threaded Perl via mod_perl, the paradigm is more like: an Apache child-process becomes occupied by a single web-request until its web-response has been completed, then becomes available for the next web-request; web-requests aren't interleaved in a child-process. (There is a case for "sub-requests," however, so this isn't strictly true.) This seems old and slow, but it is a reality for some people. Some people in this situation use SIGALRM to implement timeouts. If I'm not mistaken, if we have 256 Apache child-processes and if each one is processing a web-request (with Perl) that happens to be using libcurl, there are 256 Apache threads, 256 libcurl DNS resolver threads, 256 libcurl DNS caches and 256 libcurl connections. All 256 of those libcurl DNS resolver threads seem wasteful, since the 256 Apache threads (running Perl) are expecting to block for DNS resolution and expecting to use SIGALRM for timeouts. It seems to me that Red Hat's libcurl is assuming 'epoll' usage and assuming the cost of a libcurl thread to be cheap, but it can be one thread per process instead of one thread per server. Thank you for your two suggestions. Perhaps they will help. Nothing specific to Red Hat, it is just how upstream libcurl works. Its blocking (easy) API is implemented on top of the non-blocking (multi) API. If you build libcurl from an upstream tarball on Linux, the threaded resolver is used by default. Yes, we assume the cost of the resolver thread to be cheap, and you did not provide any data showing us the opposite. If you prefer to use SIGALRM-based timeouts for DNS resolution, you can customize your own build of libcurl. But we are not going to build libcurl with any different resolver in Fedora/RHEL. Thank you for your time. I thought it might be a bug, as the stack seems a bit odd: - Blocking DNS resolver - Non-blocking libcurl "multi" API - Blocking libcurl "easy" API - Perl expects to block on libcurl - Apache "prefork" child-process blocks on Perl One of these things is not like the others. But it's not Red Hat-specific, as you've kindly stated. |