Эвалюцыя архітэктуры гандлёва-клірынгавай сістэмы Маскоўскай біржы. Частка 1

Эвалюцыя архітэктуры гандлёва-клірынгавай сістэмы Маскоўскай біржы. Частка 1

Ўсім прывітанне! Мяне клічуць Сяргей Кастанбаеў, на Біржы я займаюся распрацоўкай ядра гандлёвай сістэмы.

Калі ў галівудскіх фільмах паказваюць Нью-Йоркскую фондавую біржу, гэта заўсёды выглядае так: натоўпы людзей, усё нешта гарлапаняць, махаюць паперкамі, робіцца поўны хаос. У нас на Маскоўскай біржы такога ніколі не было, таму што таргі з самага пачатку вядуцца электронна і грунтуюцца на двух асноўных платформах – Spectra (тэрміновы рынак) і ASTS (валютны, фондавы і грашовы рынак). І сёння хачу расказаць аб эвалюцыі архітэктуры гандлёва-клірынгавай сістэмы ASTS, аб розных рашэннях і знаходках. Аповяд будзе доўгі, так што прыйшлося разбіць яго на дзве часткі.

Мы адна з нямногіх біржаў свету, на якіх праводзяцца таргі актывамі ўсіх класаў і прадастаўляецца поўны спектр біржавых паслуг. Напрыклад, летась мы займалі другое месца ў свеце па аб'ёме таргоў аблігацыямі, 25 месца сярод усіх фондавых біржаў, 13 месца па капіталізацыі сярод публічных біржаў.

Эвалюцыя архітэктуры гандлёва-клірынгавай сістэмы Маскоўскай біржы. Частка 1

Для прафесійных удзельнікаў таргоў крытычныя такія параметры, як час водгуку, стабільнасць размеркавання часоў (джытэр) і надзейнасць усяго комплексу. На бягучы момант мы апрацоўваем дзясяткі мільёнаў транзакцый у дзень. Апрацоўка кожнай транзакцыі ядром сістэмы займае дзясяткі мікрасекунд. Вядома, у сотавых аператараў пад Новы год або ў пошукавікаў нагружанасць сама па сабе вышэй за нашу, але вось па нагружанасці разам з вышэйзгаданымі характарыстыкамі з намі мала хто можа параўнацца, як мне здаецца. Пры гэтым нам важна, каб сістэма ні на секунду не падтармажвала, працавала абсалютна стабільна, і ўсе карыстачы знаходзіліся ў роўных умовах.

Крыху гісторыі

У 1994 годзе на Маскоўскай міжбанкаўскай валютнай біржы (ММВБ) была запушчана аўстралійская сістэма ASTS, і з гэтага моманту можна адлічваць расійскую гісторыю электронных таргоў. У 1998 годзе архітэктуру біржы мадэрнізавалі дзеля ўкаранення інтэрнет-трэйдзінгу. З тых часоў хуткасць укаранення новых рашэнняў і архітэктурных змен ва ўсіх сістэмах і падсістэмах толькі набірае абароты.

У тыя гады біржавая сістэма працавала на hi-end жалезе - звышнадзейных серверах HP Superdome 9000 (пабудаваных на архітэктуры PA-RISC), у якіх дублявалася абсалютна ўсё: падсістэмы ўводу-высновы, сетка, аператыўная памяць (фактычна, быў RAID-масіў з RAM), працэсары (падтрымлівалася гарачая замена). Можна было памяняць любы кампанент сервера без спынення машыны. Мы належылі на гэтыя прылады, лічылі іх фактычна безадмоўнымі. У ролі аперацыйнай сістэмы выступала Unix-падобная сістэма HP UX.

Але прыкладна з 2010 года ўзнікла такая з'ява, як high-frequency trading (HFT), або высокачашчынны гандаль – папросту кажучы, біржавыя робаты. Усяго за 2,5 гады нагрузка на нашы серверы павялічылася ў 140 разоў.

Эвалюцыя архітэктуры гандлёва-клірынгавай сістэмы Маскоўскай біржы. Частка 1

Вытрымліваць такую ​​нагрузку са старой архітэктурай і абсталяваннем было немагчыма. Трэба было неяк адаптавацца.

Пачатак

Запыты да біржавой сістэмы можна падзяліць на два тыпы:

  • Транзакцыі. Калі вы жадаеце купіць даляры, акцыі ці нешта яшчэ, то адпраўляеце ў гандлёвую сістэму транзакцыю і атрымліваеце адказ аб паспяховасці.
  • Інфармацыйныя запыты. Калі вы хочаце даведацца пра бягучую цану, паглядзець кнігу заявак або індэксы, то адпраўляеце інфармацыйныя запыты.

Эвалюцыя архітэктуры гандлёва-клірынгавай сістэмы Маскоўскай біржы. Частка 1

Схематычна ядро ​​сістэмы можна падзяліць на тры ўзроўні:

  • Кліенцкі ўзровень, на якім працуюць брокеры, кліенты. Усе яны ўзаемадзейнічаюць з серверамі доступу.
  • Серверы доступу (Gateway) – гэта серверы, якія кэшуюць, якія лакальна апрацоўваюць усе інфармацыйныя запыты. Хочаце даведацца, па якім кошце зараз гандлююцца акцыі «Ашчадбанка»? Запыт сыходзіць на сервер доступу.
  • Але калі вы жадаеце купіць акцыі, то запыт ідзе ўжо на цэнтральны сервер (Trade Engine). Такіх сервераў па адным на кожны від рынку, яны гуляюць найважную ролю, менавіта дзеля іх мы і стваралі дадзеную сістэму.

Ядро гандлёвай сістэмы ўяўляе сабой хітрую in-memory базу дадзеных, у якой усе транзакцыі - гэта біржавыя транзакцыі. База была напісана на З, з вонкавых залежнасцяў мелася толькі бібліятэка libc і цалкам адсутнічала дынамічнае вылучэнне памяці. Каб паменшыць час апрацоўкі, сістэма запускаецца са статычным наборам масіваў і са статычнай рэлакацыяй дадзеных: спачатку ўсе дадзеныя на бягучы дзень загружаюцца ў памяць, і далей зваротаў да дыска не выконваецца, уся праца вядзецца толькі ў памяці. Пры запуску сістэмы ўсе даведачныя дадзеныя ўжо адсартаваны, таму пошук працуе вельмі эфектыўна і займаюць мала часу ў runtime. Усе табліцы зроблены з інтрузіўным спісамі і дрэвамі для дынамічных структур дадзеных, каб яны не патрабавалі вылучэння памяці ў runtime.

Давайце сцісла прабяжымся па гісторыі развіцця нашай гандлёва-клірынгавай сістэмы.
Першая версія архітэктуры гандлёва-клірынгавай сістэмы была пабудавана на так званым Unix-ўзаемадзеянні: прымяняліся падзяляемая памяць, семафоры і чэргі, а кожны працэс складаўся з аднаго патоку. Гэты падыход быў шырока распаўсюджаны на пачатку 1990-х.

Першая версія сістэмы змяшчала два ўзроўню Gateway і цэнтральны сервер гандлёвай сістэмы. Схема працы была такая:

  • Кліент дасылае запыт, які трапляе на Gateway. Той правярае валіднасць фармату (але не саміх дадзеных) і не прымае няправільныя транзакцыі.
  • Калі быў дасланы інфармацыйны запыт, то ён выконваецца лакальна; калі гаворка ідзе аб транзакцыі, то яна перанакіроўваецца на цэнтральны сервер.
  • Затым гандлёвы рухавічок апрацоўвае транзакцыю, змяняе лакальную памяць і адпраўляе адказ на транзакцыю, а яе саму - на рэплікацыю з дапамогай асобнага механізму рэплікацыі.
  • Gateway атрымлівае ад цэнтральнага вузла адказ і перанакіроўвае яго кліенту.
  • Праз некаторы час Gateway атрымлівае транзакцыю па рэплікацыйным механізме, і на гэты раз ён выконвае яе лакальна, змяняючы свае структуры дадзеных, каб наступныя інфармацыйныя запыты адлюстроўвалі актуальныя дадзеныя.

Фактычна, тут апісана рэплікацыйная мадэль, у якой Gateway цалкам паўтараў дзеянні, якія выконваюцца ў гандлёвай сістэме. Асобны канал рэплікацыі забяспечваў адзін і той жа парадак выканання транзакцый на мностве вузлоў доступу.

Паколькі код быў аднаструменным, для абслугоўвання мноства кліентаў выкарыстоўвалася класічная схема з fork-амі працэсаў. Аднак рабіць fork для ўсёй базы дадзеных было вельмі накладна, таму прымяняліся легкаважныя працэсы-сэрвісы, якія збіралі пакеты з TCP-сесій і перакладалі іх у адну чаргу (SystemV Message Queue). Gateway і Trade Engine працавалі толькі з гэтай чаргой, забіраючы адтуль транзакцыі на выкананне. Адправіць у яе адказ ужо было нельга, таму што незразумела, які сэрвіс-працэс павінен яго прачытаць. Так што мы звярнуліся да выкруту: кожны fork-нуты працэс ствараў для сябе чарга адказаў, і калі ва ўваходную чаргу прыходзіў запыт, да яго адразу дадаваўся тэг для чаргі адказаў.

Пастаяннае капіраванне з чаргі ў чаргу вялікіх аб'ёмаў даных стварала праблемы, асабліва характэрныя для інфармацыйных запытаў. Таму мы скарысталіся яшчэ адным трукам: акрамя чаргі адказаў кожны працэс ствараў таксама і агульную памяць (SystemV Shared Memory). У яе змяшчаліся самі пакеты, а ў чарзе захоўваўся толькі тэг, які дазваляе знайсці зыходны пакет. Гэта дапамагло захоўваць дадзеныя ў кэш-памяці працэсара.

SystemV IPC уключае ў сябе ўтыліты для прагляду стану аб'ектаў чэргаў, памяці і семафораў. Мы актыўна гэтым карысталіся, каб разумець, што адбываецца ў сістэме ў пэўны момант, дзе запасяцца пакеты, што знаходзіцца ў блакіроўцы і да т.п.

Першыя мадэрнізацыі

У першую чаргу мы пазбавіліся ад аднапрацэсавага Gateway. Яго істотным недахопам было тое, што ён мог апрацоўваць або адну рэплікацыйную транзакцыю, або адзін інфармацыйны запыт ад кліента. І з ростам нагрузкі Gateway будзе ўсё даўжэй апрацоўваць запыты і не зможа апрацоўваць рэплікацыйную плынь. Да таго ж, калі кліент адправіў транзакцыю, то трэба толькі праверыць яе валіднасць і пераадрасаваць далей. Таму мы замянілі адзін працэс Gateway на мноства кампанентаў, якія могуць працаваць раўналежна: шматструменныя інфармацыйныя і транзакцыйныя працэсы, якія працуюць незалежна сябар ад сябра з агульнай вобласцю памяці з ужываннем RW-блакаванні. І заадно ўкаранілі працэсы дыспетчарызацыі і рэплікацыі.

Уплыў высокачашчыннага гандлю

Вышэйапісаная версія архітэктуры праіснавала аж да 2010 года. Тым часам нас ужо перастала задавальняць прадукцыйнасць сервераў HP Superdome. Да таго ж архітэктура PA-RISC фактычна памерла, вендар не прапаноўваў ніякіх істотных абнаўленняў. У выніку мы сталі пераходзіць з HP UX/PA RISC на Linux/x86. Пераход пачаўся з адаптацыі да сервераў доступу.

Чаму нам зноў прыйшлося мяняць архітэктуру? Справа ў тым, што высокачашчынны гандаль значна змяніў профіль нагрузкі на ядро ​​сістэмы.

Дапушчальны, у нас ёсць невялікая транзакцыя, якая выклікала значную змену кошту — хтосьці купіў паўмільярда даляраў. Праз пару мілісекунд усе ўдзельнікі рынка гэта заўважаюць і пачынаюць даваць карэкцыю. Натуральна, запыты выбудоўваюцца ў вялікую чаргу, якую сістэма будзе доўга разграбаць.

Эвалюцыя архітэктуры гандлёва-клірынгавай сістэмы Маскоўскай біржы. Частка 1

На гэтым інтэрвале 50 мс сярэдняя хуткасць складае каля 16 тыс. транзакцый у секунду. Калі зменшыць акно да 20 мс, то атрымаем сярэднюю хуткасць ужо 90 тыс. транзакцый у секунду, прычым на піку будзе 200 тыс. транзакцый. Іншымі словамі, нагрузка нясталая, з рэзкімі воплескамі. А чарга запытаў трэба заўсёды апрацоўваць хутка.

Але чаму ўвогуле ўзнікае чарга? Такім чынам, у нашым прыкладзе мноства карыстачоў заўважылі змену кошту і адпраўляюць адпаведныя транзакцыі. Тыя прыходзяць у Gateway, ён іх серыялізуе, задае нейкі парадак і адпраўляе ў сетку. Маршрутызатары змешваюць пакеты і адпраўляюць іх далей. Чый пакет прыйшоў раней, тая транзакцыя і "выйграла". У выніку кліенты біржы сталі заўважаць, што калі адну і тую ж транзакцыю адпраўляць з некалькіх Gateway, то шанцы на яе хуткую апрацоўку ўзрастаюць. Неўзабаве біржавыя робаты пачалі закідваць Gateway запытамі, і ўзнікла лавіна транзакцый.

Эвалюцыя архітэктуры гандлёва-клірынгавай сістэмы Маскоўскай біржы. Частка 1

Новы віток эвалюцыі

Пасля працяглага тэсціравання і даследаванняў мы перайшлі на real-time ядро ​​аперацыйнай сістэмы. Для гэтага абралі RedHat Enterprise MRG Linux, дзе MRG расшыфроўваецца як messaging real-time grid. Перавага real-time-патчаў у тым, што яны аптымізуюць сістэму пад максімальна хуткае выкананне: усе працэсы выбудоўваюцца ў FIFO-чаргу, можна ізаляваць ядры, ніякіх выкідванняў, усе транзакцыі апрацоўваюцца ў строгай паслядоўнасці.

Эвалюцыя архітэктуры гандлёва-клірынгавай сістэмы Маскоўскай біржы. Частка 1
Чырвоны - праца з чаргой у звычайным ядры, зялёны - праца ў real-time ядры.

Але дасягнуць нізкага ўзроўню затрымкі на звычайных серверах не так проста:

  • Моцна замінае рэжым SMI, які ў архітэктуры x86 ляжыць у аснове працы з важнай перыферыяй. Апрацоўка разнастайных апаратных падзей і кіраванне кампанентамі і прыладамі выконваецца прашыўкай у так званым празрыстым SMI-рэжыме, пры якім аперацыйная сістэма наогул не бачыць, што робіць прашыўку. Як правіла, усе буйныя вендары прапануюць спецыяльныя пашырэнні для firmware-сервераў, якія дазваляюць паменшыць аб'ём SMI-апрацоўкі.
  • Не павінна быць дынамічнага кіравання частатой працэсара, гэта прыводзіць да дадатковага прастою.
  • Калі скідаецца часопіс файлавай сістэмы, у ядры ўзнікаюць нейкія працэсы, якія прыводзяць да непрадказальных затрымак.
  • Трэба зважаць на такія рэчы, як CPU Affinity, Interrupt affinity, NUMA.

Трэба сказаць, тэма налады жалеза і ядры Linux пад realtime-апрацоўку заслугоўвае асобнага артыкула. Мы шмат часу патрацілі на эксперыменты і даследаванні, перш чым дасягнулі добрага выніку.

Пры пераходзе з PA-RISC-сервераў на x86 нам практычна не прыйшлося моцна змяняць код сістэмы, мы толькі адаптавалі і пераналадзілі яе. Заадно паправілі некалькі багаў. Напрыклад, хутка ўсплылі наступствы таго, што PA RISC з'яўлялася Big endian-сістэмай, а x86 – Little endian: напрыклад, няправільна счытваліся дадзеныя. Больш хітры баг заключаўся ў тым, што PA RISC выкарыстоўвае паслядоўна кансістэнтны (Sequential consistent) доступ да памяці, тады як x86 можа пераўпарадкоўваць аперацыі на чытанне, таму код, абсалютна валідны на адной платформе, стаў непрацоўным на іншы.

Пасля пераходу на х86 прадукцыйнасць вырасла амаль у тры разы, сярэдняя працягласць апрацоўкі транзакцыі знізілася да 60 мкс.

Давайце зараз падрабязней разгледзім, якія ключавыя змены былі ўнесены ў архітэктуру сістэмы.

Эпапея з гарачым рэзерваваннем

Пераходзячы на ​​commodity-серверы мы аддавалі сабе справаздачу, што яны менш надзейныя. Таму пры стварэнні новай архітэктуры мы апрыёры меркавалі магчымасць выхаду са строю аднаго або некалькіх вузлоў. Таму патрэбна была сістэма гарачага рэзервавання, здольная вельмі хутка пераключыцца на рэзервовыя машыны.

Акрамя таго, былі і іншыя патрабаванні:

  • Нельга ні ў якім разе губляць апрацаваныя транзакцыі.
  • Сістэма мусіць быць абсалютна празрыстай для нашай інфраструктуры.
  • Кліенты не павінны бачыць парывы ​​злучэнняў.
  • Рэзерваванне не павінна ўносіць істотную затрымку, таму што гэта крытычны фактар ​​для біржы.

Пры стварэнні сістэмы гарачага рэзервавання мы не разглядалі такія сцэнары, як падвойныя адмовы (напрыклад, перастала працаваць сетку на адным серверы і завіс асноўны сервер); не разглядалі магчымасць памылак у ПЗ, таму што яны выяўляюцца падчас тэсціравання; і не разглядалі няправільную працу жалеза.

У выніку мы дашлі да наступнай схемы:

Эвалюцыя архітэктуры гандлёва-клірынгавай сістэмы Маскоўскай біржы. Частка 1

  • Галоўны сервер непасрэдна ўзаемадзейнічаў з серверамі Gateway.
  • Усе транзакцыі, якія паступалі на галоўны сервер, маментальна рэплікаваліся на рэзервовы сервер па асобным канале. Арбітр (Governor) каардынаваў пераключэнне пры ўзнікненні якіх-небудзь праблем.

    Эвалюцыя архітэктуры гандлёва-клірынгавай сістэмы Маскоўскай біржы. Частка 1

  • Галоўны сервер апрацоўваў кожную транзакцыю і чакаў пацверджання ад рэзервовага сервера. Каб затрымка была мінімальнай, мы адмовіліся ад чакання выкананні транзакцыі на рэзервовым серверы. Паколькі працягласць перамяшчэння транзакцыі па сетцы была параўнальная з працягласцю выканання, дадатковай затрымкі не дадавалася.
  • Звяраць стан апрацоўкі галоўным і рэзервовым серверам мы маглі толькі для папярэдняй транзакцыі, а статут апрацоўкі бягучай транзакцыі быў невядомы. Паколькі тут усё яшчэ выкарыстоўваліся аднаструменныя працэсы, чаканне адказу ад Backup затармазіла б увесь паток апрацоўкі, і таму мы пайшлі на разумны кампраміс: звяралі вынік папярэдняй транзакцыі.

Эвалюцыя архітэктуры гандлёва-клірынгавай сістэмы Маскоўскай біржы. Частка 1

Схема працавала наступным чынам.

Дапушчальны, галоўны сервер перастаў адказваць, але Gateway працягваюць узаемадзейнічаць. На рэзервовым серверы спрацоўвае таймаўт, ён звяртаецца да Governor, а той прызначае яму роля галоўнага сервера, і ўсе Gateway перамыкаюцца на новы галоўны сервер.

Калі галоўны сервер зноў уваходзіць у строй, на ім таксама спрацоўвае ўнутраны таймаўт, таму што на працягу пэўнага часу да сервера не было зваротаў ад Gateway. Тады ён таксама звяртаецца да Governor, і той выключае яго са схемы. У выніку біржа да канца гандлёвага перыяду працуе з адным серверам. Паколькі верагоднасць выйсця сервера з ладу досыць нізкая, такая схема лічылася суцэль прымальнай, яна не ўтрымоўвала складанай логікі і лёгка тэставалася.

Працяг будзе.

Крыніца: habr.com

Дадаць каментар