Skip to content

Use FastCGI instead of CGI #209

Closed
Closed

Description

@mmd-osm

With the current fork rate of about 50 forks/second, we might think to switch to FastCGI and reduce the overall system cpu time. Although starting the interpreter binary is quite fast, the high fork rate nevertheless adds some overhead. By using FastCGI, the interpreter binary would be serving multiple requests instead with lower overhead.

To avoid memory leaks, all locations with static buffers would have to be cleared, before handling the next request. There's one new method initialize() in scripting_core.cc for this purpose. I'm sure there are other locations, which need to be cleared in a similar way - or - even completely changed like:

  • static std::map< uint32, string > roles; in method relation_member_roles (collect_members.cc).
  • static bool is_used_; for some statements like in area_query.h
  • Coord_Query_Statement::is_used_ in coord_query.cc
  • Id_Query_Statement::area_query_exists_ in id_query.cc
  • global_read_counter() in types.cc
  • ... and similar

Settings used for the prototype:

Install libs:

sudo apt-get install libfcgi-dev
sudo apt-get install libapache2-mod-fcgid

Apache settings:

default.conf

    <Directory "/srv/overpass/fcgi-bin/">
        SetHandler fcgid-script
                AllowOverride None
                Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
                Order allow,deny
                Allow from all
                #SetOutputFilter gzip
                #Header set Content-Encoding gzip
    </Directory>

fcgid.conf: (needs to be adjusted in any case)

<IfModule mod_fcgid.c>
  FcgidConnectTimeout 60
  FcgidMaxRequestsPerProcess 500
  FcgidMaxProcessesPerClass 20
  FcgidMinProcessesPerClass 10
  FcgidProcessLifeTime 300
  FcgidMaxProcesses 20
  FcgidIOTimeout 1800

  <IfModule mod_mime.c>
    AddHandler fcgid-script .fcgi
  </IfModule>
</IfModule>

Activity

  1. mmd-osm commented on Jun 9, 2016

    @mmd-osm
    ContributorAuthor

    In addition, FastCGI can be combined with a buffer for data_files / random_files in Nonsynced_Transaction

    As FastCGI handles multiple queries anyway, the buffer can be reused for several queries in the best case.

    Same applies to User_Data_Cache: it only changes after a db update, but is re-read for every transaction in need of user data.

    This is largely improving the runtime for very short running queries, like:

    [out:csv(::lat,::lon;false;',')];node(3823744880);out;
    
    • Current runtime: 80-150ms
    • Query runtime with index already cached: 3ms.

    8 concurrent threads, no wait time. No DB updates, on dev instance: 21 calls/s.
    (includes #208, #280)

    [out:json][timeout:5][maxsize:1000000];area[name='Mainz'];
    node(area)[amenity='atm'];out count;
    
    • additional change needed for set_limits / setrlimit (set only soft limits to query provided details!)
  2. mmd-osm commented on Dec 21, 2016

    @mmd-osm
    ContributorAuthor

    Some comments on configuration:

    interpreter binary can also be managed via supervisord and the following configuration example:

    [fcgi-program:interpreter]
    socket=unix:///var/run/interpreter.socket
    socket_owner=www
    socket_mode=0660
    command=/srv/osm3s/cgi-bin/interpreter
    numprocs=16
    priority=999
    process_name=%(program_name)s_%(process_num)02d
    user=overpass-client
    autorestart=true
    autostart=true
    startsecs=1
    startretries=3
    stopsignal=QUIT
    stopwaitsecs=10
    redirect_stderr=true
    stdout_logfile=/var/log/interpreter.log
    stdout_logfile_maxbytes=10MB
    

    This way, interpreter can run under a dedicated user rather than www-data. It an instances crashes, it will be automatically restarted.

    For nginx (and also Apache), we can directly connect to the respective unix socket:

            location /api/ {
    
                if ($request_method = 'OPTIONS') {
                  add_header 'Access-Control-Allow-Origin' '*';
                  add_header 'Access-Control-Allow-Credentials' 'true';
                  add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
                  add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
                  add_header 'Access-Control-Max-Age' 3600;
                  add_header 'Content-Type' 'text/plain charset=UTF-8';
                  add_header 'Content-Length' 0;
                  return 204;
                }
    
                include        /usr/local/etc/nginx/fastcgi_params;
                fastcgi_pass   unix:/var/run/interpreter.socket;
                fastcgi_param HTTP_PROXY "";
            }
    
  3. mmd-osm commented on Nov 15, 2021

    @mmd-osm
    ContributorAuthor

    Change implemented in https://github.com/mmd-osm/Overpass-API, closing here.

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

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions