Vývoj architektúry obchodného a zúčtovacieho systému Moskovskej burzy. Časť 1

Vývoj architektúry obchodného a zúčtovacieho systému Moskovskej burzy. Časť 1

Ahojte všetci! Volám sa Sergey Kostanbaev, na burze vyvíjam jadro obchodného systému.

Keď hollywoodske filmy ukazujú burzu v New Yorku, vždy to vyzerá takto: davy ľudí, každý niečo kričí, máva papiermi, deje sa úplný chaos. Toto sa tu na moskovskej burze nikdy nestalo, pretože obchodovanie sa od začiatku vedie elektronicky a je založené na dvoch hlavných platformách – Spectra (forexový trh) a ASTS (devízový, akciový a peňažný trh). A dnes chcem hovoriť o vývoji architektúry obchodného a zúčtovacieho systému ASTS, o rôznych riešeniach a zisteniach. Príbeh bude dlhý, preto som ho musela rozdeliť na dve časti.

Sme jednou z mála búrz na svete, ktorá obchoduje s aktívami všetkých tried a poskytuje celý rad zmenárenských služieb. Napríklad v minulom roku sme sa umiestnili na druhom mieste na svete v objeme obchodov s dlhopismi, 25. miesto medzi všetkými burzami, 13. miesto v kapitalizácii medzi verejnými burzami.

Vývoj architektúry obchodného a zúčtovacieho systému Moskovskej burzy. Časť 1

Pre profesionálnych účastníkov obchodovania sú rozhodujúce parametre ako čas odozvy, stabilita rozloženia času (jitter) a spoľahlivosť celého komplexu. V súčasnosti spracovávame desiatky miliónov transakcií denne. Spracovanie každej transakcie jadrom systému trvá desiatky mikrosekúnd. Samozrejme, mobilní operátori na Silvestra či samotné vyhľadávače majú vyššiu záťaž ako u nás, no čo sa týka vyťaženosti, spojenej s vyššie spomenutými charakteristikami sa s nami môže porovnávať málokto, zdá sa mi. Zároveň je pre nás dôležité, aby sa systém ani na sekundu nespomalil, fungoval absolútne stabilne a všetci používatelia boli na rovnakej úrovni.

Trochu histórie

V roku 1994 bol na Moskovskej medzibankovej menovej burze (MICEX) spustený austrálsky systém ASTS a od tohto momentu možno počítať ruskú históriu elektronického obchodovania. V roku 1998 bola architektúra burzy modernizovaná, aby sa zaviedlo internetové obchodovanie. Odvtedy rýchlosť implementácie nových riešení a architektonických zmien vo všetkých systémoch a podsystémoch len naberá na obrátkach.

V tých rokoch výmenný systém fungoval na špičkovom hardvéri – ultra spoľahlivých serveroch HP Superdome 9000 (postavených na PA-RISC), v ktorom bolo duplikované úplne všetko: vstupno/výstupné podsystémy, sieť, RAM (v skutočnosti existovalo pole RAID RAM), procesory (hot-swap). Bolo možné zmeniť akýkoľvek komponent servera bez zastavenia stroja. Na tieto zariadenia sme sa spoliehali a považovali sme ich za prakticky bezpečné. Operačným systémom bol systém HP UX podobný Unixu.

No približne od roku 2010 sa objavil fenomén nazývaný vysokofrekvenčné obchodovanie (HFT), alebo vysokofrekvenčné obchodovanie – zjednodušene povedané burzové roboty. Len za 2,5 roka sa zaťaženie našich serverov zvýšilo 140-krát.

Vývoj architektúry obchodného a zúčtovacieho systému Moskovskej burzy. Časť 1

Pri starej architektúre a zariadení sa nedalo vydržať takú záťaž. Bolo potrebné sa nejako prispôsobiť.

začiatok

Žiadosti do výmenného systému možno rozdeliť do dvoch typov:

  • Transakcie. Ak chcete kúpiť doláre, akcie alebo niečo iné, odošlete transakciu do obchodného systému a dostanete odpoveď o úspechu.
  • Žiadosti o informácie. Ak chcete zistiť aktuálnu cenu, pozrite si knihu objednávok alebo indexy a potom odošlite požiadavky na informácie.

Vývoj architektúry obchodného a zúčtovacieho systému Moskovskej burzy. Časť 1

Schematicky možno jadro systému rozdeliť do troch úrovní:

  • Úroveň klienta, na ktorej pracujú makléri a klienti. Všetky interagujú s prístupovými servermi.
  • Servery brány sú vyrovnávacie servery, ktoré lokálne spracúvajú všetky požiadavky na informácie. Chcete vedieť, za akú cenu sa aktuálne obchodujú akcie Sberbank? Požiadavka smeruje na prístupový server.
  • Ale ak chcete kúpiť akcie, potom žiadosť ide na centrálny server (Trade Engine). Pre každý typ trhu existuje jeden takýto server, zohrávajú dôležitú úlohu, práve pre nich sme vytvorili tento systém.

Jadrom obchodného systému je šikovná in-memory databáza, v ktorej sú všetky transakcie výmennými transakciami. Základ bol napísaný v C, jedinými vonkajšími závislosťami bola knižnica libc a vôbec neexistovala dynamická alokácia pamäte. Aby sa skrátil čas spracovania, systém začína so statickou sadou polí a so statickým premiestňovaním údajov: najprv sa všetky údaje za aktuálny deň načítajú do pamäte a nevykonáva sa žiadny ďalší prístup na disk, všetka práca sa vykonáva iba v pamäti. Keď sa systém spustí, všetky referenčné údaje sú už zoradené, takže vyhľadávanie funguje veľmi efektívne a zaberie len málo času. Všetky tabuľky sú vytvorené s rušivými zoznamami a stromami pre dynamické dátové štruktúry, takže nevyžadujú alokáciu pamäte za behu.

Poďme si v krátkosti prejsť históriou vývoja nášho obchodného a zúčtovacieho systému.
Prvá verzia architektúry systému obchodovania a zúčtovania bola postavená na takzvanej unixovej interakcii: využívala sa zdieľaná pamäť, semafory a fronty a každý proces pozostával z jedného vlákna. Tento prístup bol rozšírený začiatkom 1990. rokov.

Prvá verzia systému obsahovala dve úrovne Gateway a centrálny server obchodného systému. Pracovný postup bol takýto:

  • Klient odošle požiadavku, ktorá sa dostane do brány. Kontroluje platnosť formátu (nie však samotných údajov) a odmieta nesprávne transakcie.
  • Ak bola odoslaná žiadosť o informácie, vykoná sa lokálne; ak hovoríme o transakcii, tak je presmerovaná na centrálny server.
  • Obchodný mechanizmus potom spracuje transakciu, upraví lokálnu pamäť a odošle odpoveď na transakciu a samotnú transakciu na replikáciu pomocou samostatného replikačného motora.
  • Brána prijme odpoveď z centrálneho uzla a odošle ju klientovi.
  • Po určitom čase brána prijme transakciu prostredníctvom mechanizmu replikácie a tentoraz ju vykoná lokálne, pričom zmení svoje dátové štruktúry tak, aby ďalšie požiadavky na informácie zobrazovali najnovšie dáta.

V skutočnosti popisuje replikačný model, v ktorom brána úplne replikovala akcie vykonávané v obchodnom systéme. Samostatný replikačný kanál zaisťoval, že transakcie boli vykonávané v rovnakom poradí medzi viacerými prístupovými uzlami.

Keďže kód bol jednovláknový, na obsluhu mnohých klientov sa použila klasická schéma s procesnými vidličkami. Forkovať celú databázu však bolo veľmi drahé, preto sa používali odľahčené servisné procesy, ktoré zbierali pakety z TCP relácií a prenášali ich do jedného frontu (SystemV Message Queue). Gateway a Trade Engine pracovali iba s týmto frontom a brali odtiaľ transakcie na vykonanie. Na to už nebolo možné odoslať odpoveď, pretože nebolo jasné, ktorý proces služby ju má čítať. Takže sme sa uchýlili k triku: každý rozvetvený proces si vytvoril front odpovedí sám pre seba a keď do prichádzajúceho frontu prišla požiadavka, okamžite sa k nemu pridala značka pre front odpovedí.

Neustále kopírovanie veľkého množstva údajov z frontu do frontu vytváralo problémy, najmä typické pre požiadavky na informácie. Preto sme použili ďalší trik: okrem frontu odpovedí každý proces vytvoril aj zdieľanú pamäť (SystemV Shared Memory). Boli do nej umiestnené samotné balíky a do frontu bola uložená iba značka, ktorá umožňovala nájsť originálny balík. To pomohlo ukladať údaje do vyrovnávacej pamäte procesora.

SystemV IPC obsahuje pomocné programy na prezeranie stavu frontu, pamäte a objektov semaforu. Aktívne sme to využili, aby sme pochopili, čo sa v konkrétnom okamihu deje v systéme, kde sa hromadia pakety, čo bolo zablokované atď.

Prvé modernizácie

V prvom rade sme sa zbavili jednoprocesovej brány. Jeho významnou nevýhodou bolo, že dokázal spracovať buď jednu replikačnú transakciu alebo jednu informačnú požiadavku od klienta. A ako sa zaťaženie zvyšuje, Gateway bude trvať dlhšie, kým spracuje požiadavky a nebude schopná spracovať tok replikácie. Navyše, ak klient odoslal transakciu, tak stačí skontrolovať jej platnosť a poslať ďalej. Preto sme jeden proces brány nahradili viacerými komponentmi, ktoré môžu bežať paralelne: viacvláknové informačné a transakčné procesy bežiace nezávisle od seba v oblasti zdieľanej pamäte pomocou uzamykania RW. A zároveň sme zaviedli procesy odosielania a replikácie.

Vplyv vysokofrekvenčného obchodovania

Vyššie uvedená verzia architektúry existovala do roku 2010. Medzitým sme už neboli spokojní s výkonom serverov HP Superdome. Okrem toho architektúra PA-RISC bola prakticky mŕtva, predajca neponúkol žiadne významné aktualizácie. V dôsledku toho sme začali prechádzať z HP UX/PA RISC na Linux/x86. Prechod sa začal prispôsobením prístupových serverov.

Prečo sme museli opäť meniť architektúru? Faktom je, že vysokofrekvenčné obchodovanie výrazne zmenilo profil zaťaženia na jadre systému.

Povedzme, že máme malú transakciu, ktorá spôsobila výraznú zmenu ceny – niekto kúpil pol miliardy dolárov. Po niekoľkých milisekúndách si to všimnú všetci účastníci trhu a začnú robiť nápravu. Prirodzene, požiadavky sa zoradia do obrovského frontu, ktorého vymazanie bude systému trvať dlho.

Vývoj architektúry obchodného a zúčtovacieho systému Moskovskej burzy. Časť 1

Pri tomto intervale 50 ms je priemerná rýchlosť približne 16 tisíc transakcií za sekundu. Ak znížime okno na 20 ms, dostaneme priemernú rýchlosť 90 200 transakcií za sekundu s XNUMX XNUMX transakciami na vrchole. Inými slovami, zaťaženie nie je konštantné, s náhlymi výbuchmi. A front žiadostí musí byť vždy rýchlo spracovaný.

Ale prečo je tam vôbec rad? Takže v našom príklade si mnohí používatelia všimli zmenu ceny a podľa toho odosielali transakcie. Prídu do brány, tá ich zoradí, nastaví určité poradie a odošle do siete. Smerovače zamiešajú pakety a posielajú ich ďalej. Koho balíček dorazil ako prvý, táto transakcia „vyhrala“. V dôsledku toho si klienti burzy začali všímať, že ak bola tá istá transakcia odoslaná z niekoľkých Gateway, potom sa zvýšila šanca na jej rýchle spracovanie. Čoskoro začali výmenné roboty bombardovať Gateway požiadavkami a vznikla lavína transakcií.

Vývoj architektúry obchodného a zúčtovacieho systému Moskovskej burzy. Časť 1

Nové kolo evolúcie

Po rozsiahlom testovaní a výskume sme prešli na jadro operačného systému v reálnom čase. Na tento účel sme si vybrali RedHat Enterprise MRG Linux, kde MRG znamená mriežku pre zasielanie správ v reálnom čase. Výhodou záplat v reálnom čase je, že optimalizujú systém pre čo najrýchlejšiu realizáciu: všetky procesy sú zoradené do FIFO frontu, jadrá môžu byť izolované, žiadne vyhadzovanie, všetky transakcie sú spracovávané v prísnom poradí.

Vývoj architektúry obchodného a zúčtovacieho systému Moskovskej burzy. Časť 1
Červená - práca s frontom v bežnom jadre, zelená - práca v jadre v reálnom čase.

Dosiahnutie nízkej latencie na bežných serveroch však nie je také jednoduché:

  • Veľmi ruší režim SMI, ktorý je v architektúre x86 základom pre prácu s dôležitými perifériami. Spracovanie všetkých druhov hardvérových udalostí a správu komponentov a zariadení vykonáva firmvér v takzvanom transparentnom SMI režime, v ktorom operačný systém vôbec nevidí, čo firmvér robí. Všetci hlavní dodávatelia spravidla ponúkajú špeciálne rozšírenia pre servery firmvéru, ktoré umožňujú znížiť množstvo spracovania SMI.
  • Nemalo by existovať žiadne dynamické riadenie frekvencie procesora, čo vedie k dodatočným prestojom.
  • Keď sa vyprázdni protokol súborového systému, v jadre sa vyskytnú určité procesy, ktoré spôsobujú nepredvídateľné oneskorenia.
  • Musíte venovať pozornosť veciam ako CPU Affinity, Interrupt Affinity, NUMA.

Musím povedať, že téma nastavenia linuxového hardvéru a jadra na spracovanie v reálnom čase si zaslúži samostatný článok. Strávili sme veľa času experimentovaním a skúmaním, kým sme dosiahli dobrý výsledok.

Pri prechode z PA-RISC serverov na x86 sme prakticky nemuseli veľmi meniť systémový kód, len sme ho prispôsobili a prekonfigurovali. Zároveň sme opravili niekoľko chýb. Napríklad dôsledky skutočnosti, že PA RISC bol Big endian systém a x86 bol Little endian systém, rýchlo vyplávali na povrch: napríklad dáta sa čítali nesprávne. Zložitejšia chyba bola, že PA RISC používa dôsledne konzistentné (Postupne konzistentné) prístup k pamäti, zatiaľ čo x86 môže zmeniť poradie operácií čítania, takže kód, ktorý bol absolútne platný na jednej platforme, sa na druhej pokazil.

Po prechode na x86 sa výkon zvýšil takmer trojnásobne, priemerný čas spracovania transakcie sa znížil na 60 μs.

Poďme sa teraz bližšie pozrieť na to, aké kľúčové zmeny sa udiali v architektúre systému.

Epos s horúcou rezervou

Pri prechode na komoditné servery sme si uvedomovali, že sú menej spoľahlivé. Preto sme pri tvorbe novej architektúry a priori predpokladali možnosť zlyhania jedného alebo viacerých uzlov. Preto bol potrebný horúci pohotovostný systém, ktorý by mohol veľmi rýchlo prejsť na záložné stroje.

Okrem toho existovali ďalšie požiadavky:

  • Za žiadnych okolností by ste nemali prísť o spracované transakcie.
  • Systém musí byť absolútne transparentný pre našu infraštruktúru.
  • Klienti by nemali vidieť prerušené pripojenia.
  • Rezervácie by nemali spôsobiť výrazné oneskorenie, pretože ide o kritický faktor pre výmenu.

Pri vytváraní horúceho pohotovostného systému sme takéto scenáre nepovažovali za dvojité zlyhania (napríklad sieť na jednom serveri prestala fungovať a hlavný server zamrzol); nezohľadnil možnosť chýb v softvéri, pretože sa zistia počas testovania; a nezohľadnil nesprávnu činnosť hardvéru.

V dôsledku toho sme dospeli k nasledujúcej schéme:

Vývoj architektúry obchodného a zúčtovacieho systému Moskovskej burzy. Časť 1

  • Hlavný server interagoval priamo so servermi brány.
  • Všetky transakcie prijaté na hlavnom serveri boli okamžite replikované na záložný server prostredníctvom samostatného kanála. Rozhodca (guvernér) koordinoval zmenu, ak sa vyskytli nejaké problémy.

    Vývoj architektúry obchodného a zúčtovacieho systému Moskovskej burzy. Časť 1

  • Hlavný server spracoval každú transakciu a čakal na potvrdenie zo záložného servera. Aby sme udržali latenciu na minime, vyhli sme sa čakaniu na dokončenie transakcie na záložnom serveri. Keďže čas potrebný na prechod transakcie cez sieť bol porovnateľný s časom vykonania, nepridala sa žiadna dodatočná latencia.
  • Mohli sme skontrolovať iba stav spracovania na hlavnom a záložnom serveri predchádzajúcej transakcie a stav spracovania aktuálnej transakcie bol neznámy. Keďže sme stále používali jednovláknové procesy, čakanie na odpoveď od Backup by spomalilo celý proces spracovania, preto sme urobili rozumný kompromis: skontrolovali sme výsledok predchádzajúcej transakcie.

Vývoj architektúry obchodného a zúčtovacieho systému Moskovskej burzy. Časť 1

Schéma fungovala nasledovne.

Povedzme, že hlavný server prestane reagovať, ale brány naďalej komunikujú. Na záložnom serveri dôjde k vypršaniu časového limitu, kontaktuje guvernéra, ktorý mu pridelí úlohu hlavného servera a všetky brány sa prepnú na nový hlavný server.

Ak sa hlavný server vráti späť do režimu online, spustí sa aj interný časový limit, pretože určitý čas na server neprichádzali žiadne hovory z brány. Potom sa obráti aj na guvernéra a ten ho vylúči zo schémy. Výsledkom je, že burza funguje s jedným serverom až do konca obdobia obchodovania. Keďže pravdepodobnosť zlyhania servera je pomerne nízka, táto schéma bola považovaná za celkom prijateľnú, neobsahovala zložitú logiku a dala sa ľahko otestovať.

Bude pokračovať.

Zdroj: hab.com

Pridať komentár