Koppelvlak 6 benchmark

In de vorige blogpost stelde we ons zelf de volgende vraag:

Zouden we misschien de complete realtime distributie op een Raspberry Pi kunnen draaien?

Gedreven door een academische vraag, zijn we vandaag op onderzoek uit gegaan. De randvoorwaarden van het onderzoek zijn: KV6 data die Reisinformatiegroep B.V. van Arriva, Connexxion en HTM publiceert, een Ziggo-internetverbinding en het snelste hardware platform op dit moment voorhanden is: de Raspberry Pi 😉

Raspberry Pi in transparante box

De daadwerkelijk gebruikte Raspberry Pi

De Raspberry Pi bestaat uit een ARMv6 700MHz, draaiende op Raspbian met Linux kernel 2.3.27, 256MB geheugen en een 100Mbit smsc95xx ethernet interface die via USB is aangesloten op de SoC. Verder hebben wij gebruik gemaakt van de standaard loket software:

Wat we in een korte bewoording hebben gedaan: een afnemer van KV6 data heeft deze opgevangen en hieruit doorgestuurd naar de Raspberry Pi. Hiermee is de afnemer een transparant loket geworden.

De data bevatte dus standaard de reisinformatie van de drie vervoerders, op een typische zondagavond. Natuurlijk niet het drukste moment in het OV. We hebben er daarom voor gekozen om niet met KV6 data van 3 vervoerders te gaan testen, maar data van 126 vervoerders. Ja, we hebben tot 42x meer data in het systeem gestopt dan er nu in zou gaan. De problemen die we in de tussentijd tegen zijn gekomen:

  • De eerste bottleneck die werd bereikt heeft te maken met TCP TIME_WAIT. Standaard wacht een Linux kernel 60 seconden om een afgesloten verbinding op te ruimen. We hebben dit gereduceerd tot 10 seconden (ver onder de geadviseerde minimale limiet, niet zelf doen dus) om te voorkomen dat onze sockets op zouden raken. Onder het netwerk diagram staat de reden van het enorme socket gebruik.
  • De tweede bottleneck wordt eigenlijk niet binnen afzienbare tijd bereikt, het heeft te maken met de manier hoe de netwerkkaart op het platform is aangesloten, via USB. Op het moment dat een hardware platform geen interrupts kan alloceren voor specifieke randapparatuur worden er software interrupts gebruikt, het is een dure manier van polling dat zich in de kernel zelf manifesteert.

Simultaan met 42 inkomende datastromen was er ook een systeem dat 42 keer die 42 data stromen ophaalde. In het heetst van de strijd werd ook nog een keer gewisseld tussen de oude “pubsub” implementatie en de nieuwe “xpubxsub”. Het blijkt dat de clients geen verschil merkten, zelfs de broncode is niet aangepast. In totaal zijn dus 1764 streams aan data ontvangen op het afnemende systeem, dat het daar best warm van kreeg, omdat het de data ook uitpakte en op het scherm toonde. Hieronder een schematisch overzicht van de situatie. De highlights: 1764 streams aan data past in 32Mbit en resulteert in maximaal 2000 inkomende pakketten per seconde. Na de test realiseerde wij ons dat we feitelijk ook het aanleverende systeem hadden gebenchmarkt: ook de ZeroMQ naar TMI HTTP-POST had geen enkel probleem met het bevoorraden van 42 afnemers, het staat natuurlijk in geen verhouding met het werk van de Raspberry Pi deed.

Netwerkdiagram

Waarom gebruikt jullie implementatie zoveel sockets?
Er zijn een aantal netwerkmodellen om data van programma naar programma te krijgen. De meest relevante modellen zijn hier Push/Pull en Publish/Subscribe. In principe is ZeroMQ compleet transparant aan welke kant een serversocket of clientsocket zich bevindt. De webserver zou dus als push kunnen verbinden, maar een verbinding naar een ander systeem kan ook als publish gemaakt worden.

Wij hebben gekozen voor het Push/Pull model, hiermee zal de webserver altijd direct verbinding kunnen maken met universal. Op de webserver komen KV6 berichten binnen, deze zijn van een zekere grootte, en worden, zover dat nog niet is gedaan, direct gecomprimeerd. De omvang van een bericht bepaalt dat de webserver deze berichten in blokken binnen krijgt. Onze implementatie gebruikt dat effect om in blokken te comprimeren en direct in blokken te verzenden. Er komt dus geen buffering van data aan te pas. ZeroMQ vereist dat opvolgende blokken in een bericht achter elkaar worden verstuurd, dit kan alleen gegarandeerd worden door een heel bericht in 1 keer te versturen (dus te bufferen) of per bericht een nieuwe socket verbinding aan te maken.

Er zijn drie uitwegen:

  1. Voor lief nemen dat in een normale situatie nooit zo’n enorme berg verbindingen wordt gemaakt.
  2. Inkomende berichten niet direct versturen, maar het gecomprimeerde resultaat cachen en in een keer versturen.
  3. Een connectie pool in de webserver aanmaken, dat verbindingen kan hergebruiken.

Voor nu weten we dat optie 1 de meest realistische is, optie 2 een blamage en optie 3 wat programmeerwerk vereist. Dat laatste is natuurlijk ook een mooie opstap naar een blog post in de toekomst.

Advertenties
Dit bericht werd geplaatst in Loket, NDOV en getagged met , , , , , . Maak dit favoriet permalink.

3 reacties op Koppelvlak 6 benchmark

  1. Pingback: Minder systeembronnen gebruiken bij KV6 | NDOV Loket

  2. Pingback: Goed voorbereid zijn op een DDoS: onvermijdelijk | NDOV Loket

  3. Pingback: Decentrale infrastructuur en CC0 | NDOV Loket

Geef een reactie

Vul je gegevens in of klik op een icoon om in te loggen.

WordPress.com logo

Je reageert onder je WordPress.com account. Log uit / Bijwerken )

Twitter-afbeelding

Je reageert onder je Twitter account. Log uit / Bijwerken )

Facebook foto

Je reageert onder je Facebook account. Log uit / Bijwerken )

Google+ photo

Je reageert onder je Google+ account. Log uit / Bijwerken )

Verbinden met %s