Mapserver snelheid en pagination

Hoi iedereen!

Vanuit gemeente Rotterdam proberen we Mapserver te implementeren om onze data te verservicen (WMS, WFS en OGC API). We hebben inmiddels mapserver met een postgis database aan de praat gekregen, en de volgende optimalisaties gedaan:

  1. Spatial index op de postgis data
  2. SRID expliciet zetten (in postgis en mapserver)
  3. Connection pool mapserver live houden

Echter, we ziek dat mapserver zeer langzaam blijft. Dit komt mede doordat we het aantal records in 1 request niet hoger krijgen dan 5000. Vooral met grote datasets (200.000+ bomen, BGT, etc.) duurt het inladen hierdoor veel te lang. Veel langer dan een gewone DB connectie naar de postgis database.

heeft iemand hier meer kennis m.b.t. mapserver om ons te helpen deze sneller te maken en/of de pagination gewoon uit te krijgen?

Alvast bedankt!

Sjoerd

Hoi @SjoerdBraaksma,

Bij PDOK hebben we veel ervaring met het optimaliseren van mapserver. Wat is precies de use case? Wil je dat gebruikers met de WFS de volledige dataset kunnen downloaden? Of proberen gebruikers dat en wil je dit juist voorkomen? Onze ervaring is namelijk dat een WFS uitermate geschikt is om specifieke vragen aan te stellen (die een beperkte resultset opleveren), maar niet geschikt om grote hoeveelheden data mee te downloaden. Dit heeft te maken met offset/limit methode die in de WFS wordt gebruikt om te pagineren.

2 suggesties o.b.vā€¦ de beschikbare info:

  1. heb je in Mapserver in het DATA-statement niet alleen using SRID=EPSG:28992 maar ook using unique <primary key> opgenomen? (en in postgis die primairy key aangemaakt)
  2. is de index in postgis in hetzelfde SRID als wat je in Mapserver aanroept?

Dank voor jullie snelle antwoord!
@gisnederland We hebben inderdaad ook en unique primary key, en de index is in hetzelfde SRID.

Maar zoals @hulstg al zegt (was er al bang voor): Het wordt lastig om van mapserver een one-size-fits-all service oplossing te maken. Sommige analisten hebben inderdaad die bulkbevraging nodig, en sommigen een specifieke request die een beperkte set geeft.

Dan moeten we gaan nadenken over een combinatie van services voor bulkbevraging, en mapserver-type requests. Het zou mooi zijn als we een bulk API aan onze servicelaag kunnen toevoegen die alle voordelen van een OGC API biedt (technologie-agnostisch, ontkoppelpunt tussen bron en gebruik, uniforme & gestandaardiseerde interface). Als hier voor geodata specifiek goede oplossing zijn, houd ik mij graag aanbevolen!

De nieuwe OGC API Features is wel geschikt voor zowel bulk als specifieke bevraging, mits deze gebruik maakt van cursor paginering en niet limit/offset paginering. Bij PDOK hebben we van de OGC API Features een eigen implementatie gemaakt GitHub - PDOK/gokoala: Cloud Native OGC APIs server, written in Go Hierin is alleen filtering (part 3 van de specificaties) nog niet gerealiseerd. Voorbeeld van een dergelijke API: https://api.pdok.nl/lv/bgt/ogc/v1/

2 likes

Top! die ga ik bekijken.
Ik zie dat deze gebouwt is om bovenop geopackages te draaien.
Wat is jullie ervaring met APIā€™s bovenop databases? We willen ook bijvoorbeeld zoiets aps pg_featureserv uitproberen voor bovenop onze postGIS database.

Maar, zoals eerder aangegeven: We willen ook geen onnodig ingewikkeld ecosysteem opzetten, dat is wel een afweging.

Misschien goed om een keer een call op te zetten!

overigens: Als ik de mapserver WFS leegtrek met een simpel python script, haalt hij alles binnen in 17 seconden. Ergens doet Qgis iets anders.

Het zou kunnen dat je script geen paginering gebruikt, en dat je server dat toestaat. QGis leest over het algemeen het Capabilities document, en past dat vervolgens toe - en als daar paginering in staat, zal QGis dat gaan gebruiken.

Je kunt in QGis over het algemeen uitstekend zien wat er onder water gebeurt, en hoeveel tijd dat kost. Even met de Engelse UI (op mā€™n prive-laptop):

  • View ā†’ Panels ā†’ Debugging/Development Tools, laat van alle items in je project de laad-tijd zien onder andere
  • View ā†’ Panels ā†’ Log Messages, laat onder andere netwerk-requests zien.

Beide zouden je een goed beeld moeten geven van wat er ā€˜onder waterā€™ gebeurt, en mogelijk kun je daarmee je WFS-laag aanpassen om de snelheid beter te krijgen.

Aan de serverkant kunnen we de requests zien, en daar wordt inderdaad de standaard pagination toegepast. Dat zorgt ervoor dat Qgis toch 83 seconden bezig is met het inladen van een bestand van 22MB (en het python script negeert dit inderdaad). Voor onze eindgebruikers is dat niet acceptabel, dus dat wordt kijken naar de pagination uitzetten/limiet verhogen in mapserver, of helemaal uit proberen te zetten.

Je kunt ook proberen om de paginering uit te zetten als je de WFS in QGis toevoegt. Bij mijn weten staat die standaard aan:

Mapserver ken ik niet, maar het lijkt me heel vreemd als je de paginering daar niet uit zou kunnen zetten. En als ik even google, vind ik deze documentatie, die er op lijkt te duiden dat je wfs_maxfeatures NIET moet definieren:

wfs_maxfeatures

(Optional) The maximum and default number of elements to be returned by the WFS server. If the user sets the ā€˜maxfeaturesā€™ parameter in a GetFeatureRequest, his value will be used, provided it does not exceed wfs_maxfeatures. If wfs_maxfeatures is not specified, the server will return all the features that match the query, without limit, which may make the server busy for a long time when layers with big number of features are served. Sensible values are integers greater than 0. If 0 is specified, no features will be returned. In WFS 2.0, this item is used to fill the ā€œCountDefaultā€ parameter of the response document to a GetCapabilities request, so that clients are aware of the server limit. See also the ā€œwfs_maxfeatures_ignore_for_resulttype_hitsā€ item.

Hey @sbjager ! Thanks voor het meedenken!

We proberen de pagination uit te zetten volgens allerlei manieren, maar dat is tot nu toe nog niet gelukt.
We hebben nu onderhand 3 services staan: WFS & OGC-API, een REST service, en een directe database connectie.

Directe DB connectie: <1 sec. om alle data in te laden
REST service: 17 seconden
WFS: 83 seconden (door pagination)
OGC-API: 83 seconden (idem, onderdeel van de API dus niet uit te zetten)

Natuurlijk heeft OGC & WFS een aantal voordelen (voldoen aan de OGC standaarden), maar lijken voor een beperkt aantal use-cases bruikbaar: Als er weinig data achter zit, of de gebruiker vind het niet erg om minuten te wachten.

Ik neig ernaar om voor ons de uitspraak te gaan doen: OGC services voor kleinere datasets via mapserver beschikbaar stellen, postGIS+ postREST API voor cartografisch werk met bulkbevragingen, en directe DB connectie voor data-ontwikkelaars. Hoe kijken jullie hier tegenaan?

Je kan deep pagination voorkomen door in een reverse proxy (bijvoorbeeld lighttpd) niet toe te staan dat een offset url parameter hoger is dan bijvoorbeeld 10.000. Zo doen we dat iig bij PDOK. Je voorkomt dan dat de onderliggende database overbevraagd wordt. Uiteraard kan een gebruiker dan ook nooit meer dan 10.000 + limit features downloaden.

Persoonlijk zou ik nooit een db connectie aanbieden als service aan gebruikers. Buiten dat me dit vanuit security ongewenst lijkt, heb je geen controle meer op de complexiteit van de queries die uitgevoerd worden. De stabiliteit van de database is dan niet meer te garanderen. Dit is precies de rede dat we bij PDOK voor veel van onze datasets een GPKG beschikbaar stellen. Hierop kan een gebruiker helemaal los gaan, zonder dat anderen hier last van hebben.

Het was inderdaad niet ons idee om alle gebruikers rechtstreeks te laten verbinden met de postGIS database, dat gebeurt alleen voor de producten waar dat echt voor nodig is. Voor de rest hanteren we (voor nu) de REST API bovenop die database.

We kijken inderdaad ook naar jullie OGC-API voor op geopackages! Nog niet aan toegekomen, maar het zag er heel mooi uit.

Hmmm. Uit ervaring bij ons blijkt dat dat enorm meevalt. Wij bieden onze gebruikers direct DB-verbindingen aan in QGis, waar standaard al filters in verwerkt zitten (zodat een gebruiker uit een eenheiod alleen de gegevens ziet van die eenheid, en niet van het hele land). Deze verbinding zijn alleen-lezen, dus men kan niks terugschrijven naar de database, en de details van de verbinding zijn encrypted - dus de gebruiker ziet ook geen wachtwoorden of zo, en kan die ook niet ontdekken. Wij hebben een 200 - 300 gebruikers die op die manier de database benaderen, tegelijkertijd met de originele front-end applicatie, en een web-applicatie (en dan zit ik er meestal ook nog in te rotzooien met FME :wink: ), en dat alles levert geen enkel probleem op met performance. De database is heel stabiel, als er al hiccups zijn of vertragingen, dan is dat altijd een netwerk-dingetje, nooit van de database.
Uiteraard heeft PDOK veel meer gebruikers, maar tot pak 'm beet 500 gebruikers binnen 1 organisatie (lees: binnen 1 domein, en niet publiekelijk van buitenaf benaderbaar) zou ik er geen enkele moeite mee hebben om direct een DB-connectie aan te bieden. We hebben deze oplossing nu al minstens 8 jaar staan, en initieel wel wat performance problemen, maar na onderzoek en de nodige verbeteringen her en der (met name op het gebied van indexen en zo) loopt alles als een zonnetje.

Ja, bij ons hetzelfde. We hebben hoogstens X00 gebruikers, voornamelijk data op gemeentelijk niveau. Voor eindgebruikers die weten hoe het werkt kunnen ze bij specifieke views en thatā€™s it. Het is ook geen ā€œserviceā€ die we voor jan en alleman beschikbaar stellen. het liefst hebben we gewoon dat mensen de OGC en REST APIā€™s bevragen, simpel en gestandaardiseerd.

maar nog een leuke: we hebben ook pointcloud en luchtfoto data. Voor de echt high-performance computing/geo-data science zien we daar nu databricks voor, en voor eindgebruikers een eigen service.

Altijd moeilijk om het applicatielandschap zo klein mogelijk te houden, maar we proberen het.

PDOK heeft een heel ander soort dienstverlening uiteraard, als je de gebruikersgroep goed in beeld hebt dan zou het misschien kunnen. Hoe doen jullie dat met lifecycle management? Bij een major upgrade kan je niet garanderen dat de database blijft werken zoals voorheen (al lijkt dit bij Postgres de laatste jaren erg mee te vallen). Kan me voorstellen dat gebruikers zelf implementaties bouwen op de database die kapot gaan bij een upgrade. Je kan niet echt een API-First achtige methodiek hanteren als de backend rechtstreeks wordt benaderd.

Goed testen op separate omgevingen. Maar zulke hele grote wijzigingen zijn er, aan de database-kant, niet geweest (onze DB is SQL Server).

Nee, dat kunnen ze niet. En vrijwel alles wat wij in QGis aanbieden, is gebaseerd op views - dus als er ergens een upgrade iets in de tabellen omver gooit, dan vangen we dat meestal af in de views.

Nee, maar dat is ook niet nodig. Waarom zouden we er een laag tussen zetten, als dat niets toevoegt (voor ons dan)? Die extra laag zorgt dan alleen maar voor extra performance-verlies en complexiteit bij root-cause analyse van problemen.

Idem aan onze kant, je vangt de meeste zaken inderdaad op met views.
We willen echter zeker wel naar een OGC API-first strategie toe bewegen. De voordelen van een aparte service layer die gestandaardiseerd data beschikbaar stelt, en toe te voegen is aan gegevenscatalogi is top voor vindbaarheid, en de verschillende opties (REST API, mapserver, PDOK API) dekken vast het merendeel van de behoefte af.

Voor dat kleine beetje speciale, high performance werk is een database verbinding 1 laag erachter best te doen. Daarnaast hebben we dan nog een databricks omgeving waar file-based data science gebeurt, maar dan hebben we het over de meer unieke usecases.

Overigens: Ik ben echt blij met deze discussie, wat andere visies en methoden om onze ideeen mee te toetsen is echt top, thanks daarvoor!

5 likes

Helemaal mee eens! :slightly_smiling_face:
Ook voor ons is het altijd goed om alles af en toe weer onder de loep te nemen, en dan zijn dit soort discussies heel goed.

2 likes

Zeker goed dit soort discussies. Voor ons ook goed om te weten op welke manieren er nog meer gebruik wordt gemaakt van geodata.

1 like