HighLoad++, Міхаіл Цюленеў (MongoDB): Causal consistency: ад тэорыі да практыкі

Наступная канферэнцыя HighLoad++ пройдзе 6 і 7 красавіка 2020 гады ў Санкт-Пецярбургу.
Падрабязнасці і білеты па спасылцы. HighLoad++ Siberia 2019. Зала «Краснаярск». 25 чэрвеня, 12:00. Тэзісы і прэзентацыя.

HighLoad++, Міхаіл Цюленеў (MongoDB): Causal consistency: ад тэорыі да практыкі

Бывае, што практычныя патрабаванні канфліктуюць з тэорыяй, дзе не ўлічаны важныя для камерцыйнага прадукта аспекты. У гэтым дакладзе прадстаўлены працэс выбару і камбінавання розных падыходаў да стварэння кампанентаў Causal consistency на аснове акадэмічных даследаванняў зыходзячы з патрабаванняў камерцыйнага прадукта. Слухачы даведаюцца аб існуючых тэарэтычных падыходах да logical clocks, dependency tracking, system security, clock synchronization, і чаму MongoDB спыніліся на тых ці іншых рашэннях.

Міхаіл Цюленеў (далей - МТ): - Я буду распавядаць аб Causal consistency - гэта фіча, над якой мы працавалі ў MongoDB. Я працую ў групе размеркаваных сістэм, мы яе зрабілі прыкладна два гады таму.

HighLoad++, Міхаіл Цюленеў (MongoDB): Causal consistency: ад тэорыі да практыкі

У працэсе прыйшлося азнаёміцца ​​з вялікай колькасцю акадэмічнага Research, таму што гэтая фіча дастаткова добра вывучана. Высветлілася, што ніводны артыкул не ўпісваецца ў тое, што патрабуецца ў прадакшне, базе дадзеных на ўвазе вельмі спецыфічных патрабаванняў, якія ёсць, мусіць, у любым production applications.

Я буду расказваць аб тым, як мы, з'яўляючыся спажыўцом акадэмічнага Research, рыхтуем з яго нешта такое, што мы потым можам паднесці нашым карыстальнікам у якасці гатовай стравы, якім зручна, бяспечна карыстацца.

Прычынная ўзгодненасць (Causal consistency). Вызначымся з паняццямі

Для пачатку я хачу ў агульных рысах сказаць, што ж такое Causal consistency. Ёсць два персанажа - Леанард і Пені (серыял "Тэорыя вялікага выбуху"):

HighLoad++, Міхаіл Цюленеў (MongoDB): Causal consistency: ад тэорыі да практыкі

Дапусцім, што Пені ў Еўропе, а Леанард хоча зрабіць для яе які-небудзь сюрпрыз, тусоўку. І ён нічога лепш не прыдумляе, чым выкінуць яе з фрэнд-ліста, паслаць усім сябрам апдэйт на feed: «Давайце парадуем Пені!» (яна ў Еўропе, пакуль спіць, не бачыць гэтага ўсяго і не можа ўбачыць, бо яна не там). У канчатковым моманце выдаляе гэтую пасаду, сцірае з «Фіда» і аднаўляе access, каб яна нічога не заўважыла і скандалу не было.
Гэта ўсё выдатна, але давайце выкажам здагадку, што сістэма размеркаваная, і падзеі пайшлі не крыху не так. Можа, напрыклад, здарыцца, што абмежаванне access Пені адбылося пасля таго, як з'явіўся гэты пост, калі падзеі не звязаныя паміж сабой прычынна-выніковымі сувязямі. Уласна, гэта - прыклад таго, калі патрабуецца наяўнасць Causal consistency для таго, каб выканаць бізнэс-функцыю (у дадзеным выпадку).

Насамрэч гэта досыць нетрывіяльныя ўласцівасці базы дадзеных - вельмі мала хто іх падтрымлівае. Давайце пяройдзем да мадэляў.

Мадэлі ўзгодненасці (Consistency Models)

Што такое ўвогуле мадэль кансістэнцыі ў базах дадзеных? Гэта некаторыя гарантыі, якія размеркаваная сістэма дае наконт таго, якія дадзеныя і ў якой паслядоўнасці кліент можа атрымаць.

У прынцыпе ўсе мадэлі кансістэнцыі зводзяцца да таго, наколькі размеркаваная сістэма падобная на сістэму, якая працуе, напрыклад, на адным nod'е на лэптопе. І вось наколькі сістэма, якая працуе на тысячах геаразмеркаваных «Надоў», падобная на лэптоп, у якім усе гэтыя ўласцівасці выконваюцца ў прынцыпе аўтаматычна.

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

Мадэль Strong

Уласна, самая першая мадэль - гэта Strong (або лінія rise ability, як яе часта называюць). Гэта мадэль кансістэнцыі, якая гарантуе, што кожная змена, як толькі атрымліваецца пацверджанне аб тым, што яно адбылося, становіцца відаць усім карыстачам сістэмы.

Гэта стварае глабальны парадак усіх падзеяў у БД. Гэта вельмі моцная ўласцівасць кансістэнцыі, і яна ўвогуле вельмі дарагая. Тым не менш яно вельмі добрае падтрымліваецца. Яно проста вельмі дарагое і павольнае - ім проста рэдка карыстаюцца. Гэта называецца rise ability.

Ёсць яшчэ адна, мацнейшая ўласцівасць, якое падтрымліваецца ў «Спанеры» - завецца External Consistency. Мы пра яго пагаворым крыху пазней.

Прычынна-выніковы

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

Causals - гэта ўласна сітуацыя, пры якой падзеі звязаныя прычынна-следчай сувяззю. Вельмі часта іх успрымаюць як Read your on rights з пункта гледжання кліента. Калі кліент назіраў нейкія значэння, ён не можа ўбачыць значэння, якія былі ў мінулым. Ён ужо пачынае бачыць прэфіксныя чытанні. Гэта ўсё зводзіцца да аднаго і таго ж.
Causals як мадэль кансістэнцыі - частковае парадкаванне падзей на серверы, пры якім падзеі з усіх кліентаў назіраюцца ў адной і той жа паслядоўнасці. У дадзеным выпадку - Леанард і Пені.

Падзей

Трэцяя мадэль - гэта Eventual Consistency. Гэта тое, што падтрымлівае абсалютна ўсе размеркаваныя сістэмы, мінімальная мадэль, якая ўвогуле мае сэнс. Яна азначае наступнае: калі ў нас адбываюцца некаторыя змены ў дадзеных, яны ў нейкі момант становяцца кансістэнтнымі.

У такі момант яна нічога не кажа, інакш яна ператварылася б у External Consistency - была б зусім іншая гісторыя. Тым не менш гэта вельмі папулярная мадэль, самая распаўсюджаная. Па змаўчанні ўсе карыстачы размеркаваных сістэм выкарыстоўваюць менавіта Eventual Consistency.

Я хачу прывесці некаторыя параўнальныя прыклады:

HighLoad++, Міхаіл Цюленеў (MongoDB): Causal consistency: ад тэорыі да практыкі

Што гэтыя стрэлачкі азначаюць?

  • Затрымка. Пры павелічэнні сілы кансістэнцыі яна становіцца больш па зразумелых прычынах: трэба зрабіць больш запісаў, атрымаць пацвярджэнне ад усіх хастоў і нодаў, якія ўдзельнічаюць у кластары, што дадзеныя там ужо ёсць. Адпаведна ў Eventual Consistency самы хуткі адказ, таму што тамака, як правіла, можна нават у memory закаміціць і гэтага будзе ў прынцыпе досыць.
  • Даступнасць. Калі гэта разумець як магчымасць сістэмы адказаць пры наяўнасці парываў сеткі, partitions, ці нейкіх адмоваў - адмоваўстойлівасць узрастае пры памяншэнні мадэлі кансістэнцыі, паколькі нам дастаткова таго, каб адзін хост жыў і пры гэтым выдаваў нейкія дадзеныя. Eventual Consistency наогул нічога не гарантуе з нагоды дадзеных - гэта можа быць усё, што заўгодна.
  • Anomalies. Пры гэтым, вядома, узрастае колькасць анамалій. У Strong Consistency іх наогул практычна не павінна быць, а Eventual Consistency яны могуць быць якія заўгодна. Узнікае пытанне: чаму ж людзі выбіраюць Eventual Consistency, калі яна змяшчае анамаліі? Адказ у тым заключаецца, што Eventual Consistency-мадэлі дастасавальныя, а анамаліі існуюць, напрыклад, у кароткі прамежак часу; існуе магчымасць выкарыстоўваць майстар для чытання і больш-менш чытаць кансістэнтныя дадзеныя; часта ёсць магчымасць выкарыстоўваць моцныя мадэлі кансістэнцыі. Практычна гэта працуе, і часта колькасць анамалій абмежавана па часе.

Тэарэма CAP

Калі вы бачыце словы consistency, availability - што вам прыходзіць на розум? Правільна - CAP theorem! Я зараз хачу развеяць міф… Гэта не я – ёсць Марцін Клеппман, які напісаў цудоўны артыкул, цудоўную кніжку.

HighLoad++, Міхаіл Цюленеў (MongoDB): Causal consistency: ад тэорыі да практыкі

Тэарэма CAP - гэта прынцып, сфармуляваны ў 2000-х гадах, аб тым, што Consistency, Availability, Partitions: take any two, і нельга абраць тры. Гэта быў нейкі прынцып. Ён быў даказаны як тэарэма некалькі гадоў праз, гэта зрабілі Джылберт і Лінч. Затым гэта стала выкарыстоўвацца, як мантра - сістэмы сталі дзяліцца на CA, CP, AP і гэтак далей.

Гэтая тэарэма была даказаная насамрэч вось для якіх выпадкаў… Па-першае, Availability разглядалася не як бесперапыннае значэнне ад нуля да сотні (0 – сістэма "мёртвая", 100 – адказвае хутка; мы яе так абвыклі разглядаць), а як уласцівасць алгарытму які гарантуе, што пры ўсіх яго executions ён вяртае дадзеныя.

Пра час адказу там увогуле няма ні слова! Ёсць алгарытм, які вяртае дадзеныя праз 100 гадоў - зусім выдатны available-алгарытм, якія з'яўляецца часткай тэарэмы CAP.
Другое: даказвалася тэарэма для змен у значэннях аднаго і таго ж ключа, прытым што гэтыя змены – лінія resizable. Гэта азначае тое, што насамрэч яны практычна не выкарыстоўваюцца, таму што мадэлі іншыя Eventual Consistency, Strong Consistency (можа быць).

Навошта гэта ўсё? Да таго, што тэарэма CAP менавіта ў той форме, у якой яна даказаная, практычна не дастасавальная, рэдка выкарыстоўваецца. У тэарэтычнай форме яна нейкім чынам усё абмяжоўвае. Атрымліваецца нейкі прынцып, які інтуітыўна дакладны, але ніяк, увогуле, не даказаны.

Causal consistency самая моцная мадэль

Тое, што зараз адбываецца - можна атрымаць усе тры рэчы: Consistency, Availability атрымаць з дапамогай Partitions. У прыватнасці Causal consistency - наймацнейшая мадэль кансістэнцыі, якая пры наяўнасці Partitions (разрываў у сетцы) усё роўна працуе. Таму яна і ўяўляе такую ​​вялікую цікавасць, таму мы ёю і заняліся.

HighLoad++, Міхаіл Цюленеў (MongoDB): Causal consistency: ад тэорыі да практыкі

Яна, па-першае, спрашчае працу распрацоўшчыкаў дадаткаў. У прыватнасці, наяўнасць вялікай падтрымкі з боку сервера: калі ўсе запісы, якія адбываюцца ўсярэдзіне аднаго кліента, гарантавана прыйдуць у такой паслядоўнасці на іншым кліенце. Па-другое, яна вытрымлівае partitions.

Унутраная кухня MongoDB

Памятаючы аб тым, што ланч, мы перамяшчаемся на кухню. Я раскажу пра мадэль сістэмы, а менавіта - што такое MongoDB для тых, хто ўпершыню чуе аб такой базе дадзеных.

HighLoad++, Міхаіл Цюленеў (MongoDB): Causal consistency: ад тэорыі да практыкі

HighLoad++, Міхаіл Цюленеў (MongoDB): Causal consistency: ад тэорыі да практыкі

MongoDB (далей – «МангаБД») – гэта размеркаваная сістэма, якая падтрымлівае гарызантальнае маштабаванне, гэта значыць шардынг; і ўсярэдзіне кожнага шарда яна таксама падтрымлівае надмернасць дадзеных, гэта значыць рэплікацыю.

Шардынг у «МангаБД» (не рэляцыйная БД) выконвае аўтаматычнае балансаванне, гэта значыць кожная калекцыя дакументаў (або «табліца» у тэрмінах рэляцыйных дадзеных) на кавалачкі, і ўжо сервер аўтаматычна рухае іх паміж шардамі.

Query Router, які размяркоўвае запыты, для кліента з'яўляецца некаторым кліентам, праз які ён працуе. Ён ужо ведае, дзе і якія дадзеныя знаходзяцца, накіроўвае ўсе запыты да правільнага шарду.

Яшчэ адзін важны момант: MongoDB - гэта single master. Ёсць адзін Primary - ён можа браць запісы, якія падтрымліваюць тыя ключы, якія ён у сабе змяшчае. Нельга зрабіць Multi-master write.

Мы зрабілі рэліз 4.2 - там з'явіліся новыя цікавыя рэчы. У прыватнасці, уставілі Lucene -пошук - менавіта executable java прама ў «Монга», і там стала магчымым выконваць пошук праз Lucene, такі ж, як у «Эластыкі».

І зрабілі новы прадукт – Charts, ён таксама даступны на "Атласе" (уласны Cloud "Монга"). У іх ёсць Free Tier - можна пагуляцца з гэтым. Charts мне вельмі спадабаўся візуалізацыя дадзеных, вельмі інтуітыўная.

Інгрэдыенты Causal consistency

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

HighLoad++, Міхаіл Цюленеў (MongoDB): Causal consistency: ад тэорыі да практыкі

Усё пачалося з артыкула Леслі Ламперта, які быў напісаны ў 1970-х гадах. Як бачыце, да гэтага часу працягваюцца нейкія даследаванні ў гэтай тэме. Цяпер Causal consistency перажывае цікавасць у сувязі з развіццём менавіта размеркаваных сістэм.

Абмежаванні

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

HighLoad++, Міхаіл Цюленеў (MongoDB): Causal consistency: ад тэорыі да практыкі

  • Па-першае, «МонгаДБ» - гэта single master, як я ўжо казаў (гэта моцна спрашчае).
  • Мы лічым, што каля 10 тысяч шардаў сістэма павінна падтрымліваць. Мы не можам прымаць нейкія архітэктурныя рашэнні, якія будуць відавочна абмяжоўваць гэтае значэнне.
  • Ёсць у нас воблака, але мы мяркуем, што ў чалавека павінна заставацца магчымасць, калі ён спампоўвае binary, запускае ў сябе на лэптопе, і ўсё выдатна працуе.
  • Мы мяркуем тое, што ў Research рэдка выкарыстоўваецца: вонкавыя кліенты могуць рабіць што заўгодна. «МангаДБ» - гэта апенсорс. Адпаведна, кліенты могуць быць такія разумныя, злыя - могуць хацець усё зламаць. Мы мяркуем, што візантыйскія Фейлары могуць адбывацца.
  • Для знешніх кліентаў, якія за межамі перыметра - важнае абмежаванне: калі гэтая фіча выключана, то ніякіх performance degradation не павінна назірацца.
  • Яшчэ адзін момант - наогул антыакадэмічны: сумяшчальнасць папярэдніх версій і будучых. Старыя драйверы павінны падтрымліваць новыя апдэйты, і БД павінна падтрымліваць старыя драйверы.

Увогуле, усё гэта накладае абмежаванні.

Кампаненты Causal consistency

Я зараз раскажу пра некаторыя кампаненты. Калі разглядаць увогуле Causal consistency, можна вылучыць блокі. Мы выбіралі з работ, якія адносяцца да нейкага блока: Dependency Tracking, выбар гадзін, як гэтыя гадзіннікі можна паміж сабой сінхранізаваць, і як мы забяспечваем бяспеку – гэта прыкладны план таго, пра што я буду казаць:

HighLoad++, Міхаіл Цюленеў (MongoDB): Causal consistency: ад тэорыі да практыкі

Поўнае адсочванне залежнасцяў (Full Dependency Tracking)

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

HighLoad++, Міхаіл Цюленеў (MongoDB): Causal consistency: ад тэорыі да практыкі

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

Чаму мы вырашылі не карыстацца такім падыходам (поўны трэкінг)? Відавочна, таму што гэты падыход непрактычны: любая змена ў сацыяльнай сетцы залежыць ад усіх папярэдніх змен у гэтай сацсетцы, перадаючы, скажам, «Фэйсбук» або «Вконтакте» у кожным абнаўленні. Тым не менш ёсць шмат даследаванняў менавіта Full Dependency Tracking - гэта прэсацыяльныя сеткі, для нейкіх сітуацый гэта сапраўды працуе.

Відавочнае адсочванне залежнасцяў (Explicit Dependency Tracking)

Наступны - больш абмежаваны. Тут таксама разглядаецца перадача інфармацыі, але толькі той, якая яўна залежыць. Што ад чаго залежыць, як правіла, вызначае ўжо Application. Калі дадзеныя рэпліцыруюцца, пры запыце выдаюцца толькі адказы, калі папярэднія залежнасці былі задаволены, гэта значыць паказаны. У гэтым і сутнасць таго, як Causal consistency працуе.

HighLoad++, Міхаіл Цюленеў (MongoDB): Causal consistency: ад тэорыі да практыкі

Яна бачыць, што запіс 5 залежыць ад запісаў 1, 2, 3, 4 - адпаведна, ён чакае, перш чым кліент атрымлівае доступ да змен, унесеным пастановай access'а Пені, калі ўсе папярэднія змены ўжо прайшлі ў базе дадзеных.

Гэта таксама нас не задавальняе, таму што ўсё роўна інфармацыі зашмат, і гэта будзе запавольваць. Ёсць іншы падыход…

Гадзіны Лэмпарта (Lamport Clock)

Яны вельмі старыя. Lamport Clock мае на ўвазе тое, што гэтыя dependency згортваюцца ў скалярную функцыю, якая і завецца Lamport Clock.

Скалярная функцыя - гэта некаторы абстрактнае лік. Часта яго называюць лагічным часам. Пры кожнай падзеі гэты Counter павялічваецца. Counter, які ў сапраўдны момант вядомы працэсу, пасылае кожнае паведамленне. Зразумела, што працэсы могуць быць рассінхранізаваныя, у іх можа быць зусім розны час. Тым не менш такім абменам паведамленнямі сістэма неяк балансуе гадзіннік. Што адбываецца ў дадзеным выпадку?

Я разбіў той вялікі шард напалам, каб было зразумела: Friends могуць жыць у адным нодзе, які змяшчае кавалак калекцыі, а Feed - наогул у іншым нодзе, у якім змяшчаецца кавалак гэтай калекцыі. Зразумела, як яны могуць патрапіць не ў чаргу? Спачатку Feed скажа: "Рэпліцыраваўся", а потым - Friends. Калі сістэма не забяспечвае нейкіх гарантый, што Feed не будзе паказаны, пакуль залежнасці Friends у калекцыі Friends таксама не будуць дастаўлены, то ў нас як раз узнікне сітуацыя, пра якую я згадаў.

Вы бачыце, як павялічваецца лагічна час counter на Feed'е:

HighLoad++, Міхаіл Цюленеў (MongoDB): Causal consistency: ад тэорыі да практыкі

Такім чынам, асноўная ўласцівасць гэтага Lamport Clock і Causal consistency (тлумачанага праз Lamport Clock) заключаецца ў наступным: калі ў нас ёсць падзеі A і B, і падзея B залежыць ад падзеі A*, то з гэтага вынікае, што LogicalTime ад Event A менш , чым LogicalTime ад Event B.

* Часам яшчэ кажуць, што A happened before B, гэта значыць A здарылася раней B - гэта нейкае стаўленне, якое часткова парадкуе ўсё мноства падзей, якія наогул адбыліся.

У адваротны бок няслушна. Гэта на самай справе адзін з асноўных мінусаў Lamport Clock - частковы парадак. Там ёсць паняцце аб адначасовых падзеях, гэта значыць падзей, у якіх ні (A happened before B), ні (A happened before B). Прыкладам можа служыць паралельнае даданне Леанардам у сябры каго-небудзь яшчэ (нават не Леанардам, а Шэлданам, напрыклад).
Гэта і ёсць уласцівасць, якім часта карыстаюцца пры працы Lamport-гадзінамі: глядзяць менавіта на функцыю і з гэтага робяць выснову - можа быць, гэтыя падзеі залежныя. Таму што ў адзін бок гэта дакладна: калі LogicalTime A менш за LogicalTime B, то B не можа happened before A; а калі болей, дык можа быць.

Вектарны гадзіннік (Vector Clock)

Лагічнае развіццё гадзін Лэмпарта - гэта Вектарныя гадзіны. Яны адрозніваюцца тым, што кожны нод, які тут ёсць, утрымоўвае ў сабе свой, асобны гадзіннік, і яны перадаюцца як вектар.
У дадзеным выпадку вы бачыце, што нулявы азначнік вектара адказвае за Feed, а першы азначнік вектара – за Friends (кожны з гэтых нодаў). І вось яны зараз будуць павялічвацца: нулявы індэкс "Фіда" павялічваецца пры запісе - 1, 2, 3:

HighLoad++, Міхаіл Цюленеў (MongoDB): Causal consistency: ад тэорыі да практыкі

Чым вектарныя гадзіны лепш? Тым, што дазваляюць разабрацца, якія падзеі адначасовыя і калі яны адбываюцца на розных нодах. Гэта вельмі важна для сістэмы шардзіравання, як «МангаБД». Аднак мы гэта не абралі, хоць гэта і цудоўная штука, і выдатна працуе, і нам падышла б, напэўна…

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

Spanner TrueTime. Атамны гадзіннік

Я казаў, што будзе апавяданне пра «Спанера». Гэта крутая штука, прамы XXI стагоддзе: атамныя гадзіны, GPS-сінхранізацыя.

Ідэя якая? «Спанэр» – гэта гуглаўская сістэма, якая нядаўна нават стала даступная для людзей (яны прымайстравалі да яе SQL). Кожная транзакцыя тамака мае некаторы time stamp. Паколькі час сінхранізаваны *, кожнай падзеі можна прызначыць пэўны times - у атамных гадзін ёсць час чакання, пасля якога гарантавана «адбываецца» ужо іншы час.

HighLoad++, Міхаіл Цюленеў (MongoDB): Causal consistency: ад тэорыі да практыкі

Такім чынам, проста запісваючы ў БД і чакаючы нейкі перыяд часу, аўтаматычна гарантуецца Serializability падзеі. У іх наймацнейшая Consistency-мадэль, якую ў прынцыпе можна прадставіць яна External Consistency.

* Гэта асноўная праблема гадзін Лэмпарта - яны ніколі не сінхронныя на размеркаваных сістэмах. Яны могуць разыходзіцца, нават пры наяўнасці NTP усё роўна працуюць не вельмі добра. "Спанэр" мае атамныя гадзіны і сінхранізацыю, здаецца, то мікрасекунд.

Чаму мы не абралі? Мы не мяркуем, што ў нашых карыстачоў у наяўнасці ёсць убудаваныя атамныя гадзіны. Калі яны з'явяцца, будучы ўбудаванымі ў кожны лэптоп, будзе нейкая суперкрутая GPS-сінхранізацыя - тады так… А пакуль што лепшае, што магчыма - гэта "Амазон", Base Stations - для фанатыкаў ... Таму мы выкарыстоўвалі іншыя гадзіны.

Гібрыдны гадзіннік (Hybrid Clock)

Гэта фактычна тое, што цікае ў «МангаБД» пры забеспячэнні Causal consistency. Гібрыдныя яны ў чым? Гібрыд - гэта скалярнае значэнне, але яно складаецца з двух кампанентаў:

HighLoad++, Міхаіл Цюленеў (MongoDB): Causal consistency: ад тэорыі да практыкі

  • Першае - гэта unix'вая эпоха (колькі секунд прайшло з "пачатку кампутарнага свету").
  • Другое - некаторы інкрымент, таксама 32-бітны unsigned int.

Гэта ўласна, і ўсё. Ёсць такі падыход: частка, якая адказвае за час, увесь час сінхранізуецца з гадзіннікам; кожны раз, калі адбываецца абнаўленне, гэтая частка сінхранізуецца з гадзіннікам і атрымліваецца, што час заўсёды больш-менш правільны, а increment дазваляе адрозніваць падзеі, якія адбыліся ў адзін і той жа момант часу.

Чаму гэта важна для «МангаБД»? Таму што дазваляе рабіць нейкія бэкап-рэстары на пэўны момант часу, гэта значыць падзея індэксуецца часам. Гэта важна, калі патрэбны некаторыя падзеі; для БД падзеі - гэта змены ў БД, якія адбыліся ў пэўныя прамежкі момант часу.

Самую галоўную прычыну я скажу толькі вам (калі ласка, толькі нікому не кажыце)! Мы так зрабілі таму, што так выглядаюць спарадкаваныя, індэксавацца дадзеныя ў MongoDB OpLog. OpLog - гэта структура дадзеных, якая змяшчае ў сабе абсалютна ўсе змены ў базе: яны спачатку трапляюць у OpLog, а потым ужо прымяняюцца ўжо ўласна да Storage у тым выпадку, калі гэта рэплікаваная дата або шард.

Гэта была галоўная прычына. Усё-ткі існуюць яшчэ і практычныя патрабаванні да распрацоўкі базы, а гэта значыць, што павінна быць проста - мала кода, як мага менш зламаных рэчаў, якія трэба перапісваць і тэставаць. Тое, што ў нас аплогі аказаліся праіндэксаваныя гібрыднымі гадзінамі, моцна дапамагло, і дазволіла зрабіць правільны выбар. Гэта сапраўды апраўдала сябе і неяк чароўна зарабіла, на першым жа прататыпе. Было вельмі крута!

Сінхранізацыя гадзін

Існуе некалькі спосабаў сінхранізацыі, апісаных у навуковай літаратуры. Я кажу аб сінхранізацыі, калі ў нас ёсць два розных шарда. Калі адна рэпліка-сэт - там ніякай сінхранізацыі не трэба: гэта "сінгл-майстар"; у нас ёсць OpLog, у які ўсе змены пападаюць – у гэтым выпадку ўсё ўжо sequentially ordered у самім «Аплозе». Але калі ў нас ёсць два розныя шарды, тут сінхранізацыя часу важная. Вось тут вектарныя гадзіны больш дапамаглі! Але ў нас іх няма.

HighLoad++, Міхаіл Цюленеў (MongoDB): Causal consistency: ад тэорыі да практыкі

Другі падыходзіць - гэта "Хартбіты" (Heartbeats). Можна абменьвацца некаторымі сыгналамі, якія адбываецца кожную адзінку часу. Але "Хартбіты" - занадта павольныя, мы не можам latency забяспечыць нашаму кліенту.

True time вядома, выдатная штука. Але, ізноў жа, гэта, мусіць, будучыня… Хоць у «Атласе» ужо можна зрабіць, ужо ёсць хуткія «амазонаўскія» сінхранізатары часу. Але гэта не будзе даступна для ўсіх.

Gossiping - гэта калі ўсе паведамленні ўключаюць у сябе час. Гэта прыкладна тое, што мы і выкарыстоўваем. Кожнае паведамленне паміж нодамі, драйвер, роўтэр дата-ноды, абсалютна ўсё для «МангоДБ» - гэта нейкія элементы, кампаненты базы дадзеных, якія ўтрымоўваюць у сабе гадзіннік, які цякуць. У іх усюды ёсць значэнне гібрыднага часу, яно перадаецца. 64 біта? Гэта дазваляе, гэта можна.

Як усё гэта працуе разам?

Тут я разглядаю адзін рэпліка-сэт, каб было крыху прасцей. Ёсць Primary і Secondary. Secondary робіць рэплікацыю і не заўсёды поўнасцю сінхранізаваны з Primary.

Адбываецца ўстаўка (insert) у "Праймеры" з некаторым значэннем часу. Гэты insert павялічвае ўнутраны каўнтэр на 11, калі гэта максімальна. Ці ён будзе правяраць значэння гадзін і сінхранізуецца па гадзінах, калі значэння гадзін больш. Гэта дазваляе ўпарадкаваць па часе.

Пасля таго як ён робіць запіс, адбываецца важны момант. Гадзіны ў «МонгаДБ» і інкрыментуюцца толькі ў выпадку запісу ў «Оплог». Гэта і з'яўляецца падзеяй, якая мяняе стан сістэмы. Абсалютна ва ўсіх класічных артыкулах падзеяй лічыцца трапленне паведамлення ў нод: паведамленне прыйшло - значыць, сістэма змяніла свой стан.

Гэта злучана з тым, што пры даследаванні не зусім можна зразумець, як гэтае паведамленне будзе інтэрпрэтавана. Мы дакладна ведаем, што калі яно не адлюстравана ў «Аплозе», то яно ніяк не будзе інтэрпрэтавана, і зменай стану сістэмы з'яўляецца толькі запіс у «Аплог». Гэта нам усё спрашчае: і мадэль спрашчае, і дазваляе весці парадкаванне ў рамках аднаго рэпліка-сэта, і шмат чаго іншага карыснага.

Вяртаецца значэнне, якое ўжо запісана ў "Аплог" - мы ведаем, што ў "Аплозе" ужо ляжыць гэта значэнне, і яго час - 12. Зараз, скажам, пачынаецца чытанне з іншага нода (Secondary), і ён перадае ўжо afterClusterTime у самым паведамленні. Ён кажа: "Мне трэба ўсё, што адбылося як мінімум пасля 12 або падчас дванаццаці" (гл. Мал. Вышэй).

Гэта тое, што называецца Causal a consistent (CAT). Ёсць такое паняцце ў тэорыі, што гэта некаторыя зрэз часу, якое кансістэнтна само па сабе. У дадзеным выпадку можна сказаць, што гэта стан сістэмы, які назіраўся ў момант часу 12.

Цяпер тут пакуль нічога няма, таму што гэта як бы імітуе сітуацыю, калі трэба, каб Secondary рэпліцыраваў дадзеныя з Primary. Ён чакае… І вось дадзеныя дашлі – вяртае назад гэтыя значэнні.

HighLoad++, Міхаіл Цюленеў (MongoDB): Causal consistency: ад тэорыі да практыкі

Вось так прыкладна ўсё і працуе. Амаль што.

Што значыць "амаль што"? Давайце выкажам здагадку, што ёсць некаторы чалавек, які прачытаў і зразумеў, як гэта ўсё працуе. Зразумеў, што кожны раз адбываецца ClusterTime, ён абнаўляе ўнутраныя лагічныя гадзіны, і потым наступны запіс павялічвае на адзінку. Гэтая функцыя займае 20 радкоў. Дапусцім, гэты чалавек перадае максімальна вялікі 64-бітны лік, мінус адзінка.

Чаму "мінус адзінка"? Таму што ўнутраны гадзіннік падставіцца ў гэтае значэнне (відавочна, гэта самае вялікае магчымае і больш за бягучы час), потым адбудзецца запіс у «Оплог», і гадзіннік інкрыментуецца яшчэ на адзінку – і ўжо будзе наогул максімальнае значэнне (там проста ўсе адзінкі, далей няма куды , unsaint int'ы).

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

HighLoad++, Міхаіл Цюленеў (MongoDB): Causal consistency: ад тэорыі да практыкі

Прычым, калі гэта рэплікуецца яшчэ некуды, то проста кладзецца ўвесь кластар. Абсалютна непрымальная сітуацыя, якую любы чалавек можа арганізаваць вельмі хутка і проста! Таму мы разглядалі гэты момант як адзін з найважнейшых. Як яго прадухіліць?

Наш шлях - падпісваць clusterTime

Так яно перадаецца ў допісе (да сіняга тэксту). Але мы сталі яшчэ і генераваць подпіс (сіні тэкст):

HighLoad++, Міхаіл Цюленеў (MongoDB): Causal consistency: ад тэорыі да практыкі

Подпіс генеруецца ключом, які захоўваецца ўсярэдзіне баз дадзеных, усярэдзіне абароненага перыметра; сам генеруецца, абнаўляецца (карыстальнікі гэтага нічога не бачаць). Генеруецца hash, і кожнае паведамленне пры стварэнні падпісваецца, а пры атрыманні - валідуецца.
Напэўна, узнікае пытанне ў людзей: "Наколькі гэта ўсё запавольвае?" Я ж казаў, што павінна хутка працаваць, асабліва пры адсутнасці гэтай фічы.

Што значыць карыстацца Causal consistency у дадзеным выпадку? Гэта паказваць afterClusterTime-параметр. А без гэтага ён проста будзе перадаваць значэнні ў любым выпадку. Gossiping, пачынаючы з версіі 3.6/XNUMX, працуе заўсёды.

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

Рабі гэта хутка!

Досыць простая рэч, але трук цікавы - падзялюся, можа, камусьці будзе цікава.
У нас ёсць хэш, у якім захоўваюцца падпісаныя даныя. Усе дадзеныя ідуць праз кэш. Кэш падпісвае не канкрэтна час, а Range. Калі прыходзіць некаторае значэнне, мы генеруем Range, маскіруем апошнія 16 біт, і гэта значэнне мы падпісваем:

HighLoad++, Міхаіл Цюленеў (MongoDB): Causal consistency: ад тэорыі да практыкі

Атрымліваючы такі подпіс, мы паскараем сістэму (умоўна) у 65 тысяч разоў. Яно выдатна працуе: калі паставілі эксперыменты - там рэальна ў 10 тысяч разоў скараціўся час, калі ў нас паслядоўны апдэйт. Зразумела, што калі яны ў разнабой, гэтага не атрымоўваецца. Але ў большасці практычных выпадкаў гэта працуе. Камбінацыя подпісу Range разам з подпісам дазволіла вырашыць праблему бяспекі.

Чаму мы навучыліся?

Урокі, якія мы з гэтага вынялі:

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

    Наогул, назіраецца пэўная розніца ў мысленні, калі мае месца акадэмічная канферэнцыя (“Сігмон”, напрыклад) – там усе факусуюцца на новых ідэях. У чым навізна нашага алгарытму? Тут навізны асаблівай няма. Навізна хутчэй заключаецца ў тым, як мы змяшалі разам існуючыя падыходы. Таму першае - трэба чытаць класікаў, пачынаючы з Лэмпарта.

  • У прадакшне зусім іншыя патрабаванні. Я ўпэўнены, што многія з вас сутыкаюцца не са «сферычнымі» базамі дадзеных у абстрактным вакууме, а з нармальнымі, рэальнымі рэчамі, у якіх існуюць праблемы па availability, latency і адмоваўстойлівасці.
  • Апошняе - гэта тое, што нам прыйшлося разгледзець розныя ідэі і скамбінаваць некалькі наогул розных артыкулаў у адзін падыход, разам. Ідэя пра падпісванне, напрыклад, увогуле прыйшла з артыкула, які разглядаў Paxos-пратакол, якія для невізантыйскіх Фейлараў унутры аўтарызацыйнага пратакола, для візантыйскіх – па-за межамі аўтарызацыйнага пратакола… Увогуле, гэта роўна тое, што мы ў выніку і зрабілі.

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

HighLoad++, Міхаіл Цюленеў (MongoDB): Causal consistency: ад тэорыі да практыкі

На гэтым скончу. Дзякуй!

пытанні

Пытанне з залы (далей - У): - Дзякуй, Міхаіл за даклад! Тэма пра час цікавая. Вы карыстаецеся Gossiping. Сказалі, што ва ўсіх ёсць свой час, усе ведаюць свой лакальны час. Я так зразумеў, што ў нас ёсць драйвер – кліентаў з драйверамі можа быць шмат, query-planner'аў таксама, шардаў таксама шмат… А да чаго скочваецца сістэма, калі ў нас раптам узнікне разыходжанне: нехта вырашыць, што ён на хвіліну наперадзе, хтосьці - на хвіліну ззаду? Дзе мы апынемся?

МТ: - Выдатнае пытанне на самой справе! Я якраз пра шарды хацеў сказаць. Калі я правільна разумею пытанне, у нас такая сітуацыя: ёсць шард 1 і шард 2, чытанне адбываецца з гэтых двух шардаў - у іх разыходжанне, яны паміж сабой не ўзаемадзейнічаюць, таму што час, які яны ведаюць - розны, асабліва час, які ў іх існуе ў апорах.
Дапусцім, шард 1 зрабіў мільён запісаў, шард 2 – наогул нічога, а запыт прыйшоў на два шарды. І ў першага ёсць afterClusterTime больш за мільён. У такой сітуацыі, як я патлумачыў, шард 2 увогуле ніколі не адкажа.

У: - Я хацеў даведацца, як яны сінхранізуюцца і абяруць адзін лагічны час?

МТ: - Вельмі проста сінхранізуюцца. Шард, калі да яго прыходзіць afterClusterTime, і ён не знаходзіць часу ў "Аплозе" – ініцыюе no approved. Гэта значыць ён рукамі паднімае свой час да гэтага значэння. Гэта азначае, што ў яго няма падзей, якія адпавядаюць гэтаму запыту. Ён стварае гэтую падзею штучна і становіцца такім чынам Causal Consistent.

У: – А калі да яго пасля гэтага яшчэ прыедуць якія-небудзь падзеі, якія ў сетцы дзесьці згубіліся?

МТ: - Шард так уладкованы, што яны ўжо не прыедуць, паколькі гэта single master. Калі ён ужо запісаў, дык яны ўжо не прыедуць, а будуць пасля. Не можа так атрымацца, што недзе нешта затрымалася, потым ён зробіць no write, а потым гэтыя падзеі прыехалі - і парушылася Causal consistency. Калі ён робіць no write, яны ўсё павінны прыехаць далей (ён іх пачакае).

HighLoad++, Міхаіл Цюленеў (MongoDB): Causal consistency: ад тэорыі да практыкі

У: - У мяне ёсць некалькі пытанняў адносна чэргаў. Causal consistency мяркуе, што ёсць пэўная чарга дзеянняў, якія трэба выканаць. Што здарыцца, калі ў нас адзін пакет знікае? Вось пайшоў 10-ы, 11... 12-ы прапаў, а ўсе астатнія чакаюць, калі ён споўніцца. І ў нас раптам машына памерла, мы нічога ня можам зрабіць. Ці ёсць максімальная даўжыня чаргі, якая збіраецца, перш чым выконваецца? Які fatal failure адбываецца пры страце якога-небудзь аднаго стану? Тым больш, калі мы запісваем, што ёсць нейкі стан папярэдні, то ад яго ж мы павінны неяк адштурхоўвацца? А ад яго не адштурхнуліся!

МТ: - Таксама выдатнае пытанне! Што мы робім? У MongoDB ёсць паняцце кворумных запісаў, кворумнага чытання. У якіх выпадках паведамленне можа знікнуць? Калі запіс некворумны ці калі чытанне не кворумнае (таксама можа прыстаць нейкі garbage).
Адносна Causal consistency выканалі вялікую эксперыментальную праверку, вынікам якой стала тое, што ў выпадку, калі запісы і чытанне - некворумныя, узнікаюць парушэнні Causal consistency. Роўна тое, што вы кажаце!

Наша рада: выкарыстоўваць хаця б кворумнае чытанне пры выкарыстанні Causal consistency. У гэтым выпадку знікаць нічога не будзе, нават калі кворумны запіс знікне… Гэта артаганальная сітуацыя: калі карыстач не жадае каб зніклі дадзеныя, трэба выкарыстоўваць кворумны запіс. Causal consistency не дае гарантыі durability. Гарантыю durability дае replication і machinery, злучаная з replication.

У: - Калі мы ствараем instance, які ў нас шардынг выконвае (не master, а slave адпаведна), ён абапіраецца на unix-час уласнай машыны або на час "майстра"; сінхранізуецца ў першы раз ці перыядычна?

МТ: - Зараз растлумачу. Шард (т. е. гарызантальная партыцыя) там заўсёды ёсць Primary. А ў шардзе можа быць "майстар" і могуць быць рэплікі. Але шард заўсёды падтрымлівае запіс, таму што ён павінен падтрымліваць некаторы дамен (у шардзе стаіць Primary).

У: – Гэта значыць, усё залежыць асабліва ад «майстра»? Заўсёды выкарыстоўваецца «майстар»-час?

МТ: - Так. Можна вобразна сказаць: гадзіннік цікае, калі адбываецца запіс у «майстар», у «Оплог».

У: - У нас ёсць кліент, які канэкціцца, і яму не трэба ведаць пра час нічога?

МТ: - Наогул нічога не трэба ведаць! Калі казаць пра тое, як гэта працуе на кліенце: у кліента, калі ён жадае карыстацца Causal consistency, яму трэба адкрыць сесію. Зараз там усё: і транзакцыі ў сесіі, і retrieve a rights… Сесія - гэта ўпарадкаванне лагічных падзей, якія адбываюцца з кліентам.

Калі ён адчыняе гэтую сэсію і там кажа, што жадае Causal consistency (калі па змаўчаньні сэсія падтрымлівае Causal consistency), усё аўтаматычна працуе. Драйвер запамінае гэты час і павялічвае яго, калі атрымлівае новае паведамленне. Ён запамінае, які адказ вярнула папярэдняе з сэрвера, які вярнуў дадзеныя. Наступны запыт будзе змяшчаць afterCluster («time больш за гэта»).

Кліенту не трэба ведаць роўным лікам нічога! Гэта абсалютна для яго непразрыста. Калі людзі выкарыстоўваюць гэтыя фічы, што дазваляе зрабіць? Па-першае, можна бяспечна чытаць secondaries: можна пісаць на Primary, а чытаць з геаграфічна рэплікаваных secondaries і быць упэўненым, што гэта працуе. Пры гэтым сесіі, якія запісаў на Primary, можна перадаць нават на Secondary, т. е. можна выкарыстоўваць не адну сесію, а некалькі.

У: - З тэмай Eventual consistency моцна звязаны новы пласт Compute science -тыпы дадзеных CRDT (Conflict-free Replicated Data Types). Ці разглядалі вы інтэграцыю гэтых тыпаў дадзеных у базу і што можаце сказаць пра гэта?

МТ: - Добрае пытанне! CRDT мае сэнс для канфліктаў пры запісе: у MongoDB - single master.

У: - У мяне пытанне ад дэвапсаў. У сапраўдным свеце сустракаюцца такія езуіцкія сітуацыі, калі візантыйскі Failure адбываецца, і злыя людзі ўнутры абароненага перыметра пачынаюць утыкацца ў пратакол, спецыяльным чынам крафтавыя пакеты дасылаць?

HighLoad++, Міхаіл Цюленеў (MongoDB): Causal consistency: ад тэорыі да практыкі

МТ: - Злыя людзі ўнутры перыметра - усё роўна што траянскі конь! Злыя людзі ўсярэдзіне перыметра могуць зрабіць шмат дрэнных рэчаў.

У: - Зразумелая справа, што пакідаць у серверы, груба кажучы, дзірачку, праз якую можна заапарк сланоў прасунуць і абваліць увесь кластар назаўжды… Спатрэбіцца час для ручнога аднаўлення… Гэта, мякка кажучы, няправільна. З іншага боку, цікава вось што: у рэальным жыцці, у практыцы сустракаюцца такія сітуацыі, калі натуральна падобныя ўнутраныя напады адбываюцца?

МТ: - Паколькі я нячаста сутыкаюся з security breach'амі ў рэальным жыцці, не магу сказаць - можа, яны і адбываюцца. Але калі казаць аб дэвелаперскай філасофіі, то мы лічым так: у нас ёсць перыметр, які забяспечвае рабят, якія робяць security - гэта замак, сцяна; а ўсярэдзіне перыметра можна рабіць усё, што заўгодна. Зразумела, што ёсць карыстачы з магчымасцю толькі паглядзець, а ёсць карыстачы з магчымасцю сцерці каталог.

У залежнасці ад правоў, damage, які карыстачы могуць зрабіць, можа быць мышшу, а можа быць і сланом. Зразумела, што карыстач з поўнымі правамі можа зрабіць наогул усё што заўгодна. Карыстальнік з не шырокімі правамі шкоды можа прычыніць істотна менш. У прыватнасьці, ён ня можа зламаць сыстэму.

У: – У абароненым перыметры нехта палез фармаваць нечаканыя пратаколы для сервера, каб на рак паставіць сервер, а калі павязе, то і ўвесь кластар… Ці бывае настолькі «добра»?

МТ: - Ні разу не чуў пра такія рэчы. Тое, што такім чынам можна заваліць сервер - гэта не сакрэт. Заваліць усярэдзіне, знаходзячыся з пратаколу, быўшы аўтарызаваным карыстачом, які можа запісаць у паведамленне нешта такое… Насамрэч нельга, таму што ўсё роўна ён будзе верыфікавацца. Ёсць магчымасць адключыць гэтую аўтэнтыфікацыю для карыстальнікаў, якія не жадаюць - гэта тады іх праблемы; яны, груба кажучы, самі разбурылі сцены і можна запхнуць туды слана, які растопча… А ўвогуле, можна апрануцца рамонтнікам, прыйсці і выцягнуць!

У: - Дзякуй за даклад. Сяргей («Яндэкс»). У «Монга» ёсць канстанта, якая лімітуе колькасць галасуючых членаў у Replica Set'е, і гэтая канстанта роўная 7 (сямі). Чаму гэта канстанта? Чаму гэта не параметр нейкі?

МТ: – Replica Set у нас бывае і па 40 нодаў. Там заўжды majority. Я не ведаю якая версія…

У: - У Replica Set'е можна не галасуючых членаў запускаць, але галасуючых - максімум 7. Як у гэтым выпадку перажываць выключэнне, калі ў нас Replica Set сцягнуты на 3 дата-цэнтра? Адзін дата-цэнтр можа папросту выключыцца, і яшчэ адна машынка выпасці.

МТ: – Гэта ўжо крыху за межамі дакладу. Гэта агульнае пытаньне. Можа, потым яго магу расказаць.

HighLoad++, Міхаіл Цюленеў (MongoDB): Causal consistency: ад тэорыі да практыкі

Крыху рэкламы 🙂

Дзякуй, што застаяцеся з намі. Вам падабаюцца нашыя артыкулы? Жадаеце бачыць больш цікавых матэрыялаў? Падтрымайце нас, аформіўшы замову ці парэкамендаваўшы знаёмым, хмарныя VPS для распрацоўшчыкаў ад $4.99, унікальны аналаг entry-level сервераў, які быў прыдуманы намі для Вас: Уся праўда аб VPS (KVM) E5-2697 v3 (6 Cores) 10GB DDR4 480GB SSD 1Gbps ад $19 ці як правільна дзяліць сервер? (даступныя варыянты з RAID1 і RAID10, да 24 ядраў і да 40GB DDR4).

Dell R730xd у 2 разы танней у дата-цэнтры Equinix Tier IV у Амстэрдаме? Толькі ў нас 2 х Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100 ТБ ад $199 у Нідэрландах! Dell R420 – 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB – ад $99! Чытайце аб тым Як пабудаваць інфраструктуру корп. класа c ужываннем сервераў Dell R730xd Е5-2650 v4 коштам 9000 еўра за капейкі?

Крыніца: habr.com

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