Evolusjon av arkitekturen til handels- og clearingsystemet til Moskva-børsen. Del 1

Evolusjon av arkitekturen til handels- og clearingsystemet til Moskva-børsen. Del 1

Hei alle sammen! Mitt navn er Sergey Kostanbaev, på børsen utvikler jeg kjernen i handelssystemet.

Når Hollywood-filmer viser New York Stock Exchange, ser det alltid slik ut: folkemengder, alle roper noe, vifter med papirer, fullstendig kaos skjer. Dette har aldri skjedd her på Moskva-børsen, fordi handel har foregått elektronisk helt fra starten og er basert på to hovedplattformer – Spectra (valutamarkedet) og ASTS (valuta-, aksje- og pengemarked). Og i dag vil jeg snakke om utviklingen av arkitekturen til ASTS handels- og clearingsystem, om ulike løsninger og funn. Historien blir lang, så jeg måtte dele den i to deler.

Vi er en av få børser i verden som handler aktiva i alle klasser og tilbyr et komplett utvalg av børstjenester. For eksempel ble vi i fjor rangert som nummer to i verden når det gjelder handelsvolum for obligasjoner, 25. plass blant alle børser, 13. plass i kapitalisering blant offentlige børser.

Evolusjon av arkitekturen til handels- og clearingsystemet til Moskva-børsen. Del 1

For profesjonelle handelsdeltakere er slike parametere som responstid, stabilitet i tidsfordeling (jitter) og påliteligheten til hele komplekset kritiske. Vi behandler for tiden titalls millioner transaksjoner per dag. Behandlingen av hver transaksjon av systemkjernen tar titalls mikrosekunder. Selvsagt har mobiloperatører på nyttårsaften eller søkemotorer selv en høyere arbeidsbelastning enn vår, men når det gjelder arbeidsbelastning, kombinert med de ovennevnte egenskapene, er det få som kan måle seg med oss, virker det for meg. Samtidig er det viktig for oss at systemet ikke bremser et sekund, fungerer absolutt stabilt, og alle brukere er på lik linje.

Litt historie

I 1994 ble det australske ASTS-systemet lansert på Moscow Interbank Currency Exchange (MICEX), og fra det øyeblikket kan den russiske historien om elektronisk handel telles. I 1998 ble børsarkitekturen modernisert for å introdusere internetthandel. Siden den gang har implementeringshastigheten av nye løsninger og arkitektoniske endringer i alle systemer og delsystemer bare tatt fart.

I disse årene fungerte utvekslingssystemet på hi-end maskinvare - ultrapålitelige HP Superdome 9000-servere (bygget på PA-RISIKO), der absolutt alt ble duplisert: input/output subsystemer, nettverk, RAM (faktisk var det en RAID-array med RAM), prosessorer (hot-swappable). Det var mulig å endre hvilken som helst serverkomponent uten å stoppe maskinen. Vi stolte på disse enhetene og anså dem som praktisk talt feilsikre. Operativsystemet var et Unix-lignende HP UX-system.

Men siden ca. 2010 har det dukket opp et fenomen kalt høyfrekvent handel (HFT), eller høyfrekvent handel – enkelt sagt børsroboter. På bare 2,5 år har belastningen på våre servere økt 140 ganger.

Evolusjon av arkitekturen til handels- og clearingsystemet til Moskva-børsen. Del 1

Det var umulig å tåle en slik belastning med gammel arkitektur og utstyr. Det var nødvendig å tilpasse seg på en eller annen måte.

begynner

Forespørsler til utvekslingssystemet kan deles inn i to typer:

  • Transaksjoner. Ønsker du å kjøpe dollar, aksjer eller noe annet sender du en transaksjon til handelssystemet og får svar om suksess.
  • Informasjonsforespørsler. Hvis du vil finne ut gjeldende pris, se ordreboken eller indeksene, og send deretter informasjonsforespørsler.

Evolusjon av arkitekturen til handels- og clearingsystemet til Moskva-børsen. Del 1

Skjematisk kan kjernen i systemet deles inn i tre nivåer:

  • Klientnivået, der meglere og klienter jobber. De samhandler alle med tilgangsservere.
  • Gateway-servere er caching-servere som lokalt behandler alle informasjonsforespørsler. Vil du vite hvilken pris Sberbank-aksjer nå handles til? Forespørselen går til tilgangsserveren.
  • Men hvis du ønsker å kjøpe aksjer, går forespørselen til den sentrale serveren (Trade Engine). Det er en slik server for hver type marked, de spiller en viktig rolle, det er for dem vi har laget dette systemet.

Kjernen i handelssystemet er en smart in-memory database der alle transaksjoner er byttetransaksjoner. Basen ble skrevet i C, de eneste eksterne avhengighetene var libc-biblioteket og det var ingen dynamisk minneallokering i det hele tatt. For å redusere behandlingstiden starter systemet med et statisk sett med arrays og med statisk dataflytting: først blir alle data for gjeldende dag lastet inn i minnet, og ingen ytterligere disktilgang utføres, alt arbeid utføres kun i minnet. Når systemet starter er alle referansedata allerede sortert, så søket fungerer svært effektivt og tar kort tid i kjøretid. Alle tabeller er laget med påtrengende lister og trær for dynamiske datastrukturer slik at de ikke krever minnetildeling ved kjøring.

La oss kort gå gjennom historien til utviklingen av vårt handels- og clearingsystem.
Den første versjonen av handels- og clearingsystemarkitekturen ble bygget på den såkalte Unix-interaksjonen: delt minne, semaforer og køer ble brukt, og hver prosess besto av en enkelt tråd. Denne tilnærmingen var utbredt på begynnelsen av 1990-tallet.

Den første versjonen av systemet inneholdt to nivåer av Gateway og en sentral server for handelssystemet. Arbeidsflyten var slik:

  • Klienten sender en forespørsel, som når gatewayen. Den sjekker gyldigheten av formatet (men ikke selve dataene) og avviser feil transaksjoner.
  • Hvis en informasjonsforespørsel er sendt, utføres den lokalt; hvis vi snakker om en transaksjon, blir den omdirigert til den sentrale serveren.
  • Handelsmotoren behandler deretter transaksjonen, modifiserer lokalt minne og sender et svar til transaksjonen og selve transaksjonen for replikering ved hjelp av en separat replikeringsmotor.
  • Gatewayen mottar svaret fra den sentrale noden og videresender det til klienten.
  • Etter en tid mottar gatewayen transaksjonen gjennom replikeringsmekanismen, og denne gangen utfører den den lokalt, og endrer datastrukturene slik at de neste informasjonsforespørslene viser de nyeste dataene.

Faktisk beskriver den en replikeringsmodell der Gatewayen fullstendig replikerte handlingene utført i handelssystemet. En separat replikeringskanal sørget for at transaksjoner ble utført i samme rekkefølge på tvers av flere tilgangsnoder.

Siden koden var entrådet, ble et klassisk opplegg med prosessgafler brukt for å betjene mange klienter. Det var imidlertid veldig dyrt å dele hele databasen, så det ble brukt lette tjenesteprosesser som samlet inn pakker fra TCP-sesjoner og overførte dem til én kø (SystemV Message Queue). Gateway og Trade Engine fungerte bare med denne køen, og tok transaksjoner derfra for utførelse. Det var ikke lenger mulig å sende svar på den, fordi det ikke var klart hvilken tjenesteprosess som skulle lese den. Så vi tydde til et triks: hver splittet prosess skapte en svarkø for seg selv, og når en forespørsel kom inn i den innkommende køen, ble det umiddelbart lagt til en kode for svarkøen.

Konstant kopiering av store mengder data fra kø til kø skapte problemer, spesielt typiske for informasjonsforespørsler. Derfor brukte vi et annet triks: i tillegg til svarkøen skapte hver prosess også delt minne (SystemV Shared Memory). Selve pakkene ble plassert i den, og bare et merke ble lagret i køen, slik at man kunne finne den originale pakken. Dette bidro til å lagre data i prosessorens cache.

SystemV IPC inkluderer verktøy for å se tilstanden til kø-, minne- og semaforobjekter. Vi brukte dette aktivt for å forstå hva som skjedde i systemet i et bestemt øyeblikk, hvor pakker samlet seg, hva som ble blokkert osv.

Første moderniseringer

Først og fremst ble vi kvitt enkeltprosess-gatewayen. Den betydelige ulempen var at den kunne håndtere enten én replikeringstransaksjon eller én informasjonsforespørsel fra en klient. Og etter hvert som belastningen øker, vil Gateway ta lengre tid å behandle forespørsler og vil ikke være i stand til å behandle replikeringsflyten. I tillegg, hvis klienten sendte en transaksjon, trenger du bare å sjekke gyldigheten og videresende den. Derfor erstattet vi den enkle Gateway-prosessen med flere komponenter som kan kjøre parallelt: flertrådsinformasjon og transaksjonsprosesser som kjører uavhengig av hverandre på et delt minneområde ved hjelp av RW-låsing. Og samtidig introduserte vi ekspedisjons- og replikeringsprosesser.

Effekten av høyfrekvent handel

Ovennevnte versjon av arkitekturen eksisterte til 2010. I mellomtiden var vi ikke lenger fornøyd med ytelsen til HP Superdome-servere. I tillegg var PA-RISC-arkitekturen praktisk talt død; leverandøren tilbød ingen vesentlige oppdateringer. Som et resultat begynte vi å gå fra HP UX/PA RISC til Linux/x86. Overgangen begynte med tilpasning av tilgangsservere.

Hvorfor måtte vi endre arkitekturen igjen? Faktum er at høyfrekvent handel har endret belastningsprofilen på systemkjernen betydelig.

La oss si at vi har en liten transaksjon som forårsaket en betydelig prisendring – noen kjøpte en halv milliard dollar. Etter et par millisekunder merker alle markedsaktører dette og begynner å gjøre en korreksjon. Naturligvis står forespørsler i en enorm kø, som systemet vil ta lang tid å fjerne.

Evolusjon av arkitekturen til handels- og clearingsystemet til Moskva-børsen. Del 1

Ved dette 50 ms-intervallet er gjennomsnittshastigheten omtrent 16 tusen transaksjoner per sekund. Hvis vi reduserer vinduet til 20 ms, får vi en gjennomsnittshastighet på 90 tusen transaksjoner per sekund, med 200 tusen transaksjoner på toppen. Med andre ord, belastningen er ikke konstant, med plutselige utbrudd. Og køen av forespørsler skal alltid behandles raskt.

Men hvorfor er det i det hele tatt kø? Så i vårt eksempel la mange brukere merke til prisendringen og sendte transaksjoner deretter. De kommer til Gateway, den serialiserer dem, setter en bestemt rekkefølge og sender dem til nettverket. Rutere blander pakkene og videresender dem. Hvis pakken ankom først, den transaksjonen "vant". Som et resultat begynte utvekslingsklienter å legge merke til at hvis den samme transaksjonen ble sendt fra flere gatewayer, økte sjansene for rask behandling. Snart begynte utvekslingsroboter å bombardere Gateway med forespørsler, og et snøskred av transaksjoner oppsto.

Evolusjon av arkitekturen til handels- og clearingsystemet til Moskva-børsen. Del 1

En ny runde med evolusjon

Etter omfattende testing og forskning, byttet vi til sanntids operativsystemkjernen. Til dette valgte vi RedHat Enterprise MRG Linux, der MRG står for messaging real-time grid. Fordelen med sanntidspatcher er at de optimerer systemet for raskest mulig utførelse: alle prosesser er stilt opp i en FIFO-kø, kjerner kan isoleres, ingen utkast, alle transaksjoner behandles i streng rekkefølge.

Evolusjon av arkitekturen til handels- og clearingsystemet til Moskva-børsen. Del 1
Rød - jobber med en kø i en vanlig kjerne, grønn - jobber i en sanntidskjerne.

Men å oppnå lav ventetid på vanlige servere er ikke så lett:

  • SMI-modusen, som i x86-arkitekturen er grunnlaget for å jobbe med viktig periferiutstyr, forstyrrer kraftig. Behandling av alle slags maskinvarehendelser og styring av komponenter og enheter utføres av fastvaren i den såkalte transparente SMI-modusen, der operativsystemet ikke ser hva fastvaren gjør i det hele tatt. Som regel tilbyr alle større leverandører spesielle utvidelser for fastvareservere som gjør det mulig å redusere mengden SMI-behandling.
  • Det skal ikke være noen dynamisk kontroll av prosessorfrekvensen, dette fører til ytterligere nedetid.
  • Når filsystemloggen tømmes, forekommer visse prosesser i kjernen som forårsaker uforutsigbare forsinkelser.
  • Du må ta hensyn til ting som CPU-tilhørighet, avbruddsaffinitet, NUMA.

Jeg må si at emnet for å sette opp Linux-maskinvare og -kjerne for sanntidsbehandling fortjener en egen artikkel. Vi brukte mye tid på å eksperimentere og undersøke før vi oppnådde et godt resultat.

Da vi flyttet fra PA-RISC-servere til x86, trengte vi praktisk talt ikke å endre systemkoden mye, vi bare tilpasset og rekonfigurerte den. Samtidig fikset vi flere feil. For eksempel dukket konsekvensene av det faktum at PA RISC var et Big endian-system, og x86 var et Little endian-system, raskt opp: data ble for eksempel lest feil. Den vanskeligere feilen var at PA RISC bruker konsekvent konsekvent (Sekvensielt konsistent) minnetilgang, mens x86 kan omorganisere leseoperasjoner, så kode som var absolutt gyldig på en plattform ble ødelagt på en annen.

Etter bytte til x86 økte ytelsen nesten tre ganger, den gjennomsnittlige transaksjonsbehandlingstiden gikk ned til 60 μs.

La oss nå se nærmere på hvilke viktige endringer som er gjort i systemarkitekturen.

Hot reserve-epos

Da vi byttet til vareservere, var vi klar over at de var mindre pålitelige. Derfor, når vi opprettet en ny arkitektur, antok vi på forhånd muligheten for feil på en eller flere noder. Derfor var det nødvendig med et hot standby-system som svært raskt kunne bytte til backup-maskiner.

I tillegg var det andre krav:

  • Under ingen omstendigheter skal du miste behandlede transaksjoner.
  • Systemet må være helt transparent for vår infrastruktur.
  • Klienter skal ikke se tapte tilkoblinger.
  • Reservasjoner bør ikke medføre betydelig forsinkelse fordi dette er en kritisk faktor for utvekslingen.

Når vi opprettet et varmt standby-system, vurderte vi ikke slike scenarier som doble feil (for eksempel sluttet nettverket på en server å fungere og hovedserveren frøs); vurderte ikke muligheten for feil i programvaren fordi de blir identifisert under testing; og vurderte ikke feil drift av maskinvaren.

Som et resultat kom vi til følgende opplegg:

Evolusjon av arkitekturen til handels- og clearingsystemet til Moskva-børsen. Del 1

  • Hovedserveren samhandlet direkte med Gateway-serverne.
  • Alle transaksjoner mottatt på hovedserveren ble umiddelbart replikert til backupserveren via en egen kanal. Voldgiftsdommeren (guvernøren) koordinerte byttet dersom det skulle oppstå problemer.

    Evolusjon av arkitekturen til handels- og clearingsystemet til Moskva-børsen. Del 1

  • Hovedserveren behandlet hver transaksjon og ventet på bekreftelse fra backupserveren. For å holde ventetiden på et minimum, unngikk vi å vente på at transaksjonen skulle fullføres på backupserveren. Siden tiden det tok for en transaksjon å reise på tvers av nettverket var sammenlignbar med utførelsestiden, ble ingen ekstra ventetid lagt til.
  • Vi kunne bare sjekke behandlingsstatusen til hoved- og backupserveren for den forrige transaksjonen, og behandlingsstatusen til den gjeldende transaksjonen var ukjent. Siden vi fortsatt brukte entrådede prosesser, ville vente på svar fra Backup ha bremset hele behandlingsflyten, så vi inngikk et rimelig kompromiss: vi sjekket resultatet av forrige transaksjon.

Evolusjon av arkitekturen til handels- og clearingsystemet til Moskva-børsen. Del 1

Ordningen fungerte som følger.

La oss si at hovedserveren slutter å svare, men gatewayene fortsetter å kommunisere. En timeout oppstår på backupserveren, den kontakter guvernøren, som tildeler den rollen som hovedserveren, og alle gatewayer bytter til den nye hovedserveren.

Hvis hovedserveren kommer tilbake på nett, utløser det også en intern timeout, fordi det ikke har vært anrop til serveren fra Gatewayen på en viss tid. Da henvender han seg også til Sysselmannen, og han ekskluderer ham fra ordningen. Som et resultat fungerer børsen med én server til slutten av handelsperioden. Siden sannsynligheten for en serverfeil er ganske lav, ble denne ordningen ansett som ganske akseptabel; den inneholdt ikke kompleks logikk og var lett å teste.

Skal videreføres.

Kilde: www.habr.com

Legg til en kommentar