Moskovan pörssin kaupankäynti- ja selvitysjärjestelmän arkkitehtuurin kehitys. Osa 1

Moskovan pörssin kaupankäynti- ja selvitysjärjestelmän arkkitehtuurin kehitys. Osa 1

Hei kaikki! Nimeni on Sergey Kostanbaev, Pörssissä kehitän kaupankäyntijärjestelmän ydintä.

Kun Hollywood-elokuvat näyttävät New Yorkin pörssiä, se näyttää aina tältä: väkijoukkoja, kaikki huutavat jotain, heiluttavat papereita, täydellinen kaaos tapahtuu. Tällaista ei ole koskaan tapahtunut täällä Moskovan pörssissä, koska kaupankäyntiä on käyty sähköisesti alusta alkaen ja se perustuu kahteen pääalustaan ​​- Spectra (valuuttamarkkinat) ja ASTS (valuutta-, osake- ja rahamarkkinat). Ja tänään haluan puhua ASTS-kaupankäynti- ja selvitysjärjestelmän arkkitehtuurin kehityksestä, erilaisista ratkaisuista ja havainnoista. Tarinasta tulee pitkä, joten minun piti jakaa se kahteen osaan.

Olemme yksi harvoista pörsseistä maailmassa, joka käy kauppaa kaikkien luokkien omaisuuserillä ja tarjoaa täyden valikoiman pörssipalveluita. Esimerkiksi viime vuonna sijoituimme maailman toiseksi joukkovelkakirjakaupan volyymeilla mitattuna, 25. sijalla kaikkien pörssien joukossa, 13. sijalla pörssien kapitalaatiossa.

Moskovan pörssin kaupankäynti- ja selvitysjärjestelmän arkkitehtuurin kehitys. Osa 1

Ammattimaisille kaupankäynnin osallistujille sellaiset parametrit kuin vasteaika, aikajakauman vakaus (jitter) ja koko kompleksin luotettavuus ovat kriittisiä. Käsittelemme tällä hetkellä kymmeniä miljoonia tapahtumia päivässä. Kunkin tapahtuman käsittely järjestelmäytimen toimesta kestää kymmeniä mikrosekunteja. Tietysti matkapuhelinoperaattoreilla uudenvuodenaattona tai hakukoneilla itsellään on suurempi työmäärä kuin meillä, mutta minusta näyttää siltä, ​​​​että työmäärän ja edellä mainittujen ominaisuuksien suhteen harvat voivat verrata meitä. Samalla meille on tärkeää, että järjestelmä ei hidastu hetkeksikään, toimii täysin vakaasti ja kaikki käyttäjät ovat tasa-arvoisia.

Hieman historiaa

Vuonna 1994 Australian ASTS-järjestelmä otettiin käyttöön Moskovan Interbank Currency Exchange (MICEX) -pörssissä, ja siitä hetkestä lähtien voidaan laskea Venäjän sähköisen kaupankäynnin historiaa. Vuonna 1998 pörssiarkkitehtuuria modernisoitiin Internet-kaupankäynnin käyttöön ottamiseksi. Sen jälkeen uusien ratkaisujen ja arkkitehtonisten muutosten nopeus kaikissa järjestelmissä ja osajärjestelmissä on vain kiihtynyt.

Noina vuosina vaihtojärjestelmä työskenteli huippuluokan laitteiston kanssa - erittäin luotettavilla HP Superdome 9000 -palvelimilla (rakennettu PA-RISC), jossa ehdottomasti kaikki kopioitiin: tulo-/lähtöalijärjestelmät, verkko, RAM (itse asiassa RAM-muistia oli RAID-ryhmä), prosessorit (hot-swappable). Mikä tahansa palvelinkomponentti oli mahdollista vaihtaa konetta pysäyttämättä. Luotimme näihin laitteisiin ja pitimme niitä käytännössä vikasietoisina. Käyttöjärjestelmä oli Unix-tyyppinen HP UX -järjestelmä.

Mutta noin 2010 jälkeen on ilmaantunut ilmiö, jota kutsutaan korkean taajuuden kaupankäynniksi (HFT) tai korkean taajuuden kaupankäynniksi - yksinkertaisesti sanottuna pörssirobotteiksi. Vain 2,5 vuodessa palvelimiemme kuormitus on kasvanut 140-kertaiseksi.

Moskovan pörssin kaupankäynti- ja selvitysjärjestelmän arkkitehtuurin kehitys. Osa 1

Tällaista kuormitusta oli mahdotonta kestää vanhalla arkkitehtuurilla ja laitteilla. Oli pakko sopeutua jotenkin.

alku

Vaihtojärjestelmään osoitetut pyynnöt voidaan jakaa kahteen tyyppiin:

  • Tapahtumat. Jos haluat ostaa dollareita, osakkeita tai jotain muuta, lähetät kaupankäynnin kaupankäyntijärjestelmään ja saat vastauksen onnistumisesta.
  • Tietopyynnöt. Jos haluat tietää nykyisen hinnan, katso tilauskirjaa tai indeksejä ja lähetä sitten tietopyyntöjä.

Moskovan pörssin kaupankäynti- ja selvitysjärjestelmän arkkitehtuurin kehitys. Osa 1

Kaavamaisesti järjestelmän ydin voidaan jakaa kolmeen tasoon:

  • Asiakastaso, jolla välittäjät ja asiakkaat työskentelevät. Ne kaikki ovat vuorovaikutuksessa pääsypalvelimien kanssa.
  • Yhdyskäytäväpalvelimet ovat välimuistipalvelimia, jotka käsittelevät kaikki tietopyynnöt paikallisesti. Haluatko tietää, mihin hintaan Sberbankin osakkeet tällä hetkellä käydään kauppaa? Pyyntö menee pääsypalvelimelle.
  • Mutta jos haluat ostaa osakkeita, pyyntö menee keskuspalvelimelle (Trade Engine). Jokaiselle markkinatyypille on yksi tällainen palvelin, niillä on tärkeä rooli, ja loimme tämän järjestelmän heille.

Kaupankäyntijärjestelmän ydin on älykäs muistitietokanta, jossa kaikki tapahtumat ovat vaihtotapahtumia. Pohja oli kirjoitettu C-kielellä, ainoat ulkoiset riippuvuudet olivat libc-kirjasto eikä dynaamista muistin varausta ollut ollenkaan. Käsittelyajan lyhentämiseksi järjestelmä aloittaa staattisen taulukon joukon ja staattisen tiedon siirtämisen: ensin kaikki kuluvan päivän tiedot ladataan muistiin, eikä enää suoriteta levyn käyttöä, kaikki työ suoritetaan vain muistissa. Kun järjestelmä käynnistyy, kaikki viitetiedot on jo lajiteltu, joten haku toimii erittäin tehokkaasti ja vie vain vähän aikaa ajon aikana. Kaikki taulukot on tehty tunkeilevilla listoilla ja puilla dynaamisia tietorakenteita varten, jotta ne eivät vaadi muistin varaamista ajon aikana.

Käydään lyhyesti läpi kaupankäynti- ja selvitysjärjestelmämme kehityksen historiaa.
Ensimmäinen versio kaupankäynti- ja selvitysjärjestelmäarkkitehtuurista rakennettiin ns. Unix-vuorovaikutukselle: käytettiin jaettua muistia, semaforeja ja jonoja, ja jokainen prosessi koostui yhdestä säikeestä. Tämä lähestymistapa oli laajalle levinnyt 1990-luvun alussa.

Järjestelmän ensimmäinen versio sisälsi kaksi Gateway-tasoa ja kaupankäyntijärjestelmän keskuspalvelimen. Työnkulku meni näin:

  • Asiakas lähettää pyynnön, joka saavuttaa yhdyskäytävän. Se tarkistaa muodon oikeellisuuden (mutta ei itse dataa) ja hylkää virheelliset tapahtumat.
  • Jos tietopyyntö on lähetetty, se suoritetaan paikallisesti; jos puhumme tapahtumasta, se ohjataan uudelleen keskuspalvelimelle.
  • Kaupankäyntimoottori käsittelee sitten tapahtuman, muokkaa paikallista muistia ja lähettää vastauksen tapahtumaan ja itse tapahtumaan replikoitavaksi käyttämällä erillistä replikointimoottoria.
  • Yhdyskäytävä vastaanottaa vastauksen keskussolmusta ja välittää sen asiakkaalle.
  • Jonkin ajan kuluttua yhdyskäytävä vastaanottaa tapahtuman replikointimekanismin kautta, ja tällä kertaa se suorittaa sen paikallisesti muuttamalla tietorakenteita niin, että seuraavat tietopyynnöt näyttävät uusimmat tiedot.

Itse asiassa se kuvaa replikointimallia, jossa Gateway toisti täysin kauppajärjestelmässä suoritetut toiminnot. Erillinen replikointikanava varmisti, että tapahtumat suoritettiin samassa järjestyksessä useissa tukisolmuissa.

Koska koodi oli yksisäikeinen, monien asiakkaiden palvelemiseen käytettiin klassista menetelmää prosessihaarukoilla. Koko tietokannan haarukka oli kuitenkin erittäin kallista, joten käytettiin kevyitä palveluprosesseja, jotka keräsivät paketteja TCP-istunnoista ja siirsivät ne yhteen jonoon (SystemV Message Queue). Gateway ja Trade Engine toimivat vain tämän jonon kanssa ja ottivat sieltä tapahtumia suoritettaviksi. Siihen ei ollut enää mahdollista lähettää vastausta, koska ei ollut selvää, minkä palveluprosessin se pitäisi lukea. Joten turvauduimme temppuun: jokainen haarautunut prosessi loi itselleen vastausjonon, ja kun pyyntö tuli saapuvaan jonoon, siihen lisättiin välittömästi vastausjonon tagi.

Jatkuva suurten tietomäärien kopioiminen jonosta jonoon aiheutti ongelmia, jotka ovat erityisen tyypillisiä tietopyynnöille. Siksi käytimme toista temppua: vastausjonon lisäksi jokainen prosessi loi myös jaetun muistin (SystemV Shared Memory). Itse pakkaukset laitettiin siihen, ja jonoon talletettiin vain tagi, jonka avulla alkuperäinen pakkaus löydettiin. Tämä auttoi tietojen tallentamista prosessorin välimuistiin.

SystemV IPC sisältää apuohjelmia jonon, muistin ja semaforiobjektien tilan tarkasteluun. Käytimme tätä aktiivisesti ymmärtääksemme, mitä järjestelmässä tapahtui tietyllä hetkellä, mihin paketteja kertyi, mitä estettiin jne.

Ensimmäiset päivitykset

Ensinnäkin pääsimme eroon yhden prosessin yhdyskäytävästä. Sen merkittävä haittapuoli oli, että se pystyi käsittelemään joko yhden replikointitapahtuman tai yhden tietopyynnön asiakkaalta. Ja kuorman kasvaessa Gatewaylla kestää kauemmin käsitellä pyyntöjä, eikä se pysty käsittelemään replikointikulkua. Lisäksi, jos asiakas lähetti tapahtuman, sinun tarvitsee vain tarkistaa sen voimassaolo ja lähettää se eteenpäin. Siksi korvasimme yhden yhdyskäytäväprosessin useilla komponenteilla, jotka voivat toimia rinnakkain: monisäikeiset tiedot ja tapahtumaprosessit, jotka toimivat toisistaan ​​riippumatta jaetulla muistialueella RW-lukituksen avulla. Ja samaan aikaan otimme käyttöön lähetys- ja replikointiprosessit.

Korkean taajuuden kaupankäynnin vaikutus

Yllä oleva arkkitehtuuriversio oli olemassa vuoteen 2010 asti. Sillä välin emme olleet enää tyytyväisiä HP Superdome -palvelimien suorituskykyyn. Lisäksi PA-RISC-arkkitehtuuri oli käytännössä kuollut, eikä toimittaja tarjonnut merkittäviä päivityksiä. Tämän seurauksena aloimme siirtyä HP UX/PA RISC:stä Linux/x86:een. Siirtyminen alkoi pääsypalvelinten mukauttamisella.

Miksi meidän piti muuttaa arkkitehtuuria uudelleen? Tosiasia on, että korkean taajuuden kauppa on muuttanut merkittävästi järjestelmän ytimen kuormitusprofiilia.

Oletetaan, että meillä on pieni kauppa, joka aiheutti merkittävän hinnanmuutoksen - joku osti puoli miljardia dollaria. Muutaman millisekunnin jälkeen kaikki markkinaosapuolet huomaavat tämän ja alkavat tehdä korjauksia. Luonnollisesti pyynnöt joutuvat valtavaan jonoon, jonka tyhjentäminen kestää kauan.

Moskovan pörssin kaupankäynti- ja selvitysjärjestelmän arkkitehtuurin kehitys. Osa 1

Tällä 50 ms:n aikavälillä keskinopeus on noin 16 tuhatta tapahtumaa sekunnissa. Jos lyhennämme ikkunaa 20 ms:iin, saamme keskinopeudeksi 90 tuhatta tapahtumaa sekunnissa ja 200 tuhatta tapahtumaa huipussaan. Toisin sanoen kuorma ei ole vakio, äkillisillä purskeilla. Ja pyyntöjonot on aina käsiteltävä nopeasti.

Mutta miksi ylipäätään on jono? Joten esimerkissämme monet käyttäjät huomasivat hinnanmuutoksen ja lähettivät tapahtumat sen mukaisesti. Ne tulevat Gatewaylle, se sarjoittaa ne, asettaa tietyn järjestyksen ja lähettää ne verkkoon. Reitittimet sekoittavat paketit ja välittävät ne eteenpäin. Kenen paketti saapui ensin, kauppa "voitti". Tämän seurauksena pörssiasiakkaat alkoivat huomata, että jos sama tapahtuma lähetettiin usealta yhdyskäytävältä, sen nopean käsittelyn mahdollisuudet lisääntyivät. Pian vaihtorobotit alkoivat pommittaa Gatewayta pyynnöillä, ja liiketoimien vyöry nousi.

Moskovan pörssin kaupankäynti- ja selvitysjärjestelmän arkkitehtuurin kehitys. Osa 1

Uusi evoluution kierros

Laajan testauksen ja tutkimuksen jälkeen siirryimme reaaliaikaiseen käyttöjärjestelmän ytimeen. Tätä varten valitsimme RedHat Enterprise MRG Linuxin, jossa MRG tarkoittaa reaaliaikaista viestintää. Reaaliaikaisten patch-päivitysten etuna on, että ne optimoivat järjestelmän mahdollisimman nopeaan suoritukseen: kaikki prosessit ovat rivissä FIFO-jonossa, ytimet voidaan eristää, ei poistoa, kaikki tapahtumat käsitellään tiukassa järjestyksessä.

Moskovan pörssin kaupankäynti- ja selvitysjärjestelmän arkkitehtuurin kehitys. Osa 1
Punainen - työskentelee jonon kanssa tavallisessa ytimessä, vihreä - työskentelee reaaliaikaisessa ytimessä.

Mutta alhaisen latenssin saavuttaminen tavallisilla palvelimilla ei ole niin helppoa:

  • SMI-tila, joka on x86-arkkitehtuurissa tärkeiden oheislaitteiden kanssa työskentelyn perusta, häiritsee suuresti. Kaikenlaisten laitteistotapahtumien käsittely ja komponenttien ja laitteiden hallinta suoritetaan laiteohjelmistolla niin sanotussa läpinäkyvässä SMI-tilassa, jossa käyttöjärjestelmä ei näe ollenkaan, mitä laiteohjelmisto tekee. Yleensä kaikki suuret toimittajat tarjoavat laiteohjelmistopalvelimille erityisiä laajennuksia, jotka mahdollistavat SMI-käsittelyn määrän vähentämisen.
  • Prosessorin taajuutta ei pitäisi hallita dynaamisesti, mikä johtaa lisäseisokkeihin.
  • Kun tiedostojärjestelmän loki tyhjennetään, ytimessä tapahtuu tiettyjä prosesseja, jotka aiheuttavat arvaamattomia viiveitä.
  • Sinun on kiinnitettävä huomiota asioihin, kuten CPU Affinity, Interrupt affinity, NUMA.

Minun on sanottava, että aihe Linux-laitteiston ja ytimen asettamisesta reaaliaikaista käsittelyä varten ansaitsee erillisen artikkelin. Vietimme paljon aikaa kokeiluun ja tutkimiseen ennen kuin saavutimme hyvän tuloksen.

Kun siirryimme PA-RISC-palvelimista x86:een, meidän ei käytännössä tarvinnut paljon muuttaa järjestelmäkoodia, vaan sovitimme ja konfiguroimme sen uudelleen. Samalla korjasimme useita bugeja. Esimerkiksi seuraukset siitä, että PA RISC oli Big endian -järjestelmä ja x86 oli Little endian -järjestelmä, tulivat nopeasti esille: esimerkiksi dataa luettiin väärin. Hankalin bugi oli PA RISC:n käyttämä vika johdonmukaisesti johdonmukaisesti (Peräkkäin johdonmukainen) muistin käyttö, kun taas x86 voi järjestää lukutoiminnot uudelleen, joten yhdellä alustalla ehdottoman kelvollinen koodi rikkoutui toisella.

Kun vaihdettiin x86:een, suorituskyky kasvoi lähes kolminkertaiseksi, keskimääräinen tapahtuman käsittelyaika lyheni 60 μs:iin.

Tarkastellaan nyt tarkemmin, mitä tärkeitä muutoksia järjestelmäarkkitehtuuriin on tehty.

Kuuma varaeepos

Kun vaihdoimme peruspalvelimiin, tiesimme, että ne olivat vähemmän luotettavia. Siksi luodessamme uutta arkkitehtuuria oletimme a priori yhden tai useamman solmun epäonnistumisen. Siksi tarvittiin hot standby -järjestelmä, joka kykenisi hyvin nopeasti siirtymään varakoneisiin.

Lisäksi oli muita vaatimuksia:

  • Älä missään tapauksessa menetä käsiteltyjä tapahtumia.
  • Järjestelmän on oltava täysin avoin infrastruktuurimme kannalta.
  • Asiakkaiden ei pitäisi nähdä katkenneita yhteyksiä.
  • Varaukset eivät saa aiheuttaa merkittäviä viivästyksiä, koska tämä on kriittinen tekijä vaihdon kannalta.

Kun luotiin kuumaa valmiustilajärjestelmää, emme pitäneet tällaisia ​​skenaarioita kaksoisvikaina (esimerkiksi yhden palvelimen verkko lakkasi toimimasta ja pääpalvelin jumiutui); ei ottanut huomioon ohjelmiston virheiden mahdollisuutta, koska ne tunnistetaan testauksen aikana; eikä ottanut huomioon laitteiston virheellistä toimintaa.

Tuloksena päädyimme seuraavaan kaavioon:

Moskovan pörssin kaupankäynti- ja selvitysjärjestelmän arkkitehtuurin kehitys. Osa 1

  • Pääpalvelin oli suoraan vuorovaikutuksessa Gateway-palvelimien kanssa.
  • Kaikki pääpalvelimelle vastaanotetut tapahtumat replikoitiin välittömästi varapalvelimelle erillisen kanavan kautta. Välimies (kuvernööri) koordinoi vaihtamista, jos ongelmia ilmeni.

    Moskovan pörssin kaupankäynti- ja selvitysjärjestelmän arkkitehtuurin kehitys. Osa 1

  • Pääpalvelin käsitteli jokaisen tapahtuman ja odotti vahvistusta varapalvelimelta. Jotta viive olisi mahdollisimman pieni, vältimme odottamasta tapahtuman valmistumista varmuuskopiopalvelimella. Koska aika, joka kului tapahtuman kulkemiseen verkossa, oli verrattavissa suoritusaikaan, ylimääräistä latenssia ei lisätty.
  • Pystyimme tarkistamaan vain edellisen tapahtuman pää- ja varapalvelimen käsittelytilan, ja nykyisen tapahtuman käsittelytila ​​ei ollut tiedossa. Koska käytimme edelleen yksisäikeisiä prosesseja, vastauksen odottaminen Backupilta olisi hidastanut koko käsittelykulkua, joten teimme kohtuullisen kompromissin: tarkistimme edellisen tapahtuman tuloksen.

Moskovan pörssin kaupankäynti- ja selvitysjärjestelmän arkkitehtuurin kehitys. Osa 1

Kaava toimi seuraavasti.

Oletetaan, että pääpalvelin lakkaa vastaamasta, mutta yhdyskäytävät jatkavat viestintää. Varapalvelimessa tapahtuu aikakatkaisu, se ottaa yhteyttä Governoriin, joka antaa sille pääpalvelimen roolin, ja kaikki yhdyskäytävät siirtyvät uuteen pääpalvelimeen.

Jos pääpalvelin palaa verkkoon, se laukaisee myös sisäisen aikakatkaisun, koska yhdyskäytävästä ei ole tullut puheluita palvelimelle tiettyyn aikaan. Sitten hän kääntyy myös kuvernöörin puoleen, ja hän sulkee hänet järjestelmästä. Tämän seurauksena pörssi toimii yhden palvelimen kanssa kaupankäyntikauden loppuun asti. Koska palvelinvian todennäköisyys on melko pieni, tätä mallia pidettiin varsin hyväksyttävänä, se ei sisältänyt monimutkaista logiikkaa ja oli helppo testata.

Jatkettava.

Lähde: will.com

Lisää kommentti