NewSQL = NoSQL+ACID

NewSQL = NoSQL+ACID
Акыркы убакка чейин Odnoklassniki SQL серверинде реалдуу убакыт режиминде иштетилген 50 ТБга жакын маалыматтарды сактап келген. Мындай көлөм үчүн SQL DBMS аркылуу тез жана ишенимдүү, ал тургай маалымат борборунун иштен чыгуусуна чыдамдуу кирүү мүмкүнчүлүгүн берүү дээрлик мүмкүн эмес. Адатта, мындай учурларда, NoSQL сактагычтарынын бири колдонулат, бирок бардыгын NoSQLге өткөрүү мүмкүн эмес: кээ бир субъекттер ACID транзакция кепилдиктерин талап кылат.

Бул бизди NewSQL сактагычын, башкача айтканда, NoSQL системаларынын катачылыкка чыдамдуулугун, масштабдуулугун жана иштешин камсыз кылган, бирок ошол эле учурда классикалык системалар үчүн тааныш болгон ACID кепилдиктерин сактоону камсыз кылган МБСти колдонууга алып келди. Бул жаңы класстын иштеп жаткан өнөр жай системалары аз, ошондуктан мындай системаны өзүбүз ишке киргизип, коммерциялык ишке киргиздик.

Бул кантип иштейт жана эмне болду - кесилген астынан окуңуз.

Бүгүнкү күндө Одноклассникинин бир айлык аудиториясы 70 миллиондон ашык уникалдуу конокторду түзөт. Биз Биз алдыңкы бештикке кирдик дүйнөдөгү эң ири социалдык тармактар ​​жана колдонуучулар эң көп убакыт өткөргөн жыйырма сайттын арасында. OK инфраструктурасы өтө чоң жүктөрдү көтөрөт: алдыңкы бир миллиондон ашык HTTP сурамдары/сек. 8000ден ашык сервердик флоттун бөлүктөрү бири-бирине жакын жайгашкан - төрт Москва маалымат борборлорунда, бул алардын ортосунда 1 мсден аз тармактык кечигүү мүмкүнчүлүгүн берет.

Биз Кассандраны 2010-жылдан бери 0.6 версиясынан баштап колдонуп келебиз. Бүгүнкү күндө бир нече ондогон кластерлер иштеп жатат. Эң ылдам кластер секундасына 4 миллиондон ашык операцияны иштетет, ал эми эң чоңу 260 ТБ сактайт.

Бирок, булардын баары сактоо үчүн колдонулган кадимки NoSQL кластерлери начар координацияланган маалыматтар. Биз Odnoklassniki негизделгенден бери колдонулуп келе жаткан негизги ырааттуу сактагычты, Microsoft SQL серверин алмаштыргыбыз келди. Сактагыч 300дөн ашык SQL Server Standard Edition машиналарынан турган, аларда 50 ТБ маалыматтарды камтыган - бизнес субъектилери. Бул маалыматтар ACID транзакцияларынын бир бөлүгү катары өзгөртүлүп, талап кылынат жогорку ырааттуулук.

SQL Server түйүндөрүндө маалыматтарды таратуу үчүн биз вертикалдуу да, горизонталдык да колдондук бөлүү (майдалоо). Тарыхый жактан биз жөнөкөй маалыматтарды бөлүштүрүү схемасын колдондук: ар бир объект энбелгиси менен байланышкан - объекттин идентификаторунун функциясы. Бир эле энбелгиси бар объекттер бир эле SQL серверине жайгаштырылды. Негизги жана кошумча жазуулардын белгилери ар дайым дал келген жана бир серверде жайгашкан үчүн мастер-детал мамилеси ишке ашырылган. Социалдык тармакта дээрлик бардык жазуулар колдонуучунун атынан түзүлөт - бул бир функционалдык подсистеманын ичиндеги бардык колдонуучу маалыматтары бир серверде сакталат дегенди билдирет. Башкача айтканда, бизнес транзакциясы дээрлик ар дайым бир SQL серверинин таблицаларын камтыган, бул локалдык ACID транзакцияларын колдонуу менен маалыматтардын ырааттуулугун камсыздоого мүмкүндүк берген, колдонуунун зарылдыгы жок. жай жана ишенимсиз бөлүштүрүлгөн ACID транзакциялары.

Sharding жана SQLди тездетүү үчүн рахмат:

  • Биз Чет өлкөлүк ачкыч чектөөлөрүн колдонбойбуз, анткени бөлүү учурунда объект ID башка серверде болушу мүмкүн.
  • DBMS CPU кошумча жүктөөдөн улам биз сакталган процедураларды жана триггерлерди колдонбойбуз.
  • Биз JOINдерди колдонбойбуз, анткени жогоруда айтылгандардын бардыгы жана дисктен туш келди окуулар көп.
  • Транзакциядан тышкары, биз туюктарды азайтуу үчүн Read Uncommitted изоляция деңгээлин колдонобуз.
  • Биз кыска гана транзакцияларды аткарабыз (орто эсеп менен 100 мсден кыска).
  • Биз көп саптуу UPDATE жана DELETE функциясын туюктардын көптүгүнө байланыштуу колдонбойбуз – биз бир эле учурда бир гана жазууну жаңыртабыз.
  • Биз ар дайым суроо-талаптарды индекстер боюнча гана аткарабыз - биз үчүн толук таблицаны сканерлөө планы бар суроо, маалымат базасын ашыкча жүктөө жана анын иштебей калышына алып келет.

Бул кадамдар SQL серверлеринин дээрлик максималдуу иштешин кыскартууга мүмкүндүк берди. Бирок, көйгөйлөр барган сайын көбөйө берди. Келгиле, аларды карап көрөлү.

SQL менен көйгөйлөр

  • Биз өз алдынча жазылган сыныктарды колдонгондуктан, жаңы сыныктарды кошуу администраторлор тарабынан кол менен аткарылган. Ушул убакыттын ичинде масштабдуу берилиштердин репликалары суроо-талаптарды тейлеген эмес.
  • Таблицадагы жазуулардын саны өскөн сайын киргизүү жана өзгөртүү ылдамдыгы азаят; учурдагы таблицага индекстерди кошкондо, ылдамдык бир эсеге төмөндөйт; индекстерди түзүү жана кайра түзүү токтоп калуу менен ишке ашат.
  • Өндүрүштө SQL Server үчүн Windows аз санда болушу инфраструктураны башкарууну кыйындатат

Бирок негизги көйгөй

катага сабырдуулук

Классикалык SQL сервери каталарга чыдамкайлыкка ээ. Айталы, сизде бир гана маалымат базасы сервери бар жана ал үч жылда бир жолу иштебей калат. Бул убакыттын ичинде сайт 20 мүнөткө иштебейт, бул алгылыктуу. Эгер сизде 64 сервер болсо, анда сайт үч жумада бир жолу иштебейт. Ал эми сизде 200 сервер болсо, анда сайт жума сайын иштебейт. Бул көйгөй.

SQL серверинин катачылыкка чыдамдуулугун жогорулатуу үчүн эмне кылса болот? Wikipedia бизди курууга чакырат жогорку жеткиликтүү кластер: компоненттердин бири иштебей калган учурда резервдик көчүрмөсү бар.

Бул кымбат баалуу жабдуулардын паркын талап кылат: көп сандаган кайталоо, оптикалык була, жалпы сактоо жана резервди киргизүү ишенимдүү иштебейт: коммутациялардын 10% жакыны негизги түйүндүн артындагы поезд сыяктуу резервдик түйүн бузулушу менен аяктайт.

Бирок мындай жогорку жеткиликтүү кластердин негизги кемчилиги, эгерде ал жайгашкан маалымат борбору иштебей калса, нөлдүк жеткиликтүүлүк. Одноклассникиде төрт дата борбору бар жана алардын биринде толук иштен чыккан учурда иштөөнү камсыз кылышыбыз керек.

Бул үчүн биз колдоно алабыз Multi-Master SQL серверине орнотулган репликация. Бул чечим программалык камсыздоонун баасына байланыштуу бир топ кымбатыраак жана репликациянын белгилүү көйгөйлөрүнөн жапа чегет - синхрондуу репликация менен күтүлбөгөн транзакциянын кечигүүлөрү жана асинхрондук репликация менен репликацияларды колдонуудагы кечигүүлөр (жана, натыйжада, жоголгон модификациялар). болжолдонгон чыр-чатакты кол менен чечүү бул опцияны биз үчүн таптакыр колдонбойт.

Мына ушул проблемалардын бардыгы туп-тамырынан бери чечууну талап кылды, биз аларды ар тараптан талдай баштадык. Бул жерде биз SQL Server негизинен эмне менен таанышышыбыз керек - транзакциялар.

Жөнөкөй транзакция

Колдонмо SQL программистинин көз карашы менен эң жөнөкөй транзакцияны карап көрөлү: альбомго сүрөт кошуу. Альбомдор жана фотосүрөттөр ар кандай табактарда сакталат. Альбомдо коомдук фото эсептегич бар. Андан кийин мындай бүтүм төмөнкү кадамдарга бөлүнөт:

  1. Альбомду ачкыч менен бекитебиз.
  2. Сүрөт жадыбалына жазуу түзүңүз.
  3. Эгерде сүрөт коомдук статуска ээ болсо, анда альбомго коомдук фото эсептегичти кошуп, жазууну жаңыртыңыз жана транзакцияны жасаңыз.

Же псевдокоддо:

TX.start("Albums", id);
Album album = albums.lock(id);
Photo photo = photos.create(…);

if (photo.status == PUBLIC ) {
    album.incPublicPhotosCount();
}
album.update();

TX.commit();

Бизнес транзакциясынын эң кеңири таралган сценарийи бул маалымат базасынан маалыматты тиркеме серверинин эс тутумуна окуу, бир нерсени өзгөртүү жана жаңы баалуулуктарды кайра маалымат базасына сактоо экенин көрөбүз. Адатта мындай транзакцияда биз бир нече субъекттерди, бир нече таблицаларды жаңыртабыз.

Транзакцияны ишке ашырууда башка системадан ошол эле маалыматтардын бир эле учурда модификацияланышы мүмкүн. Мисалы, антиспам колдонуучу кандайдыр бир деңгээлде шектүү деп чечиши мүмкүн, ошондуктан колдонуучунун бардык сүрөттөрү мындан ары ачык болбошу керек, алар модерацияга жөнөтүлүшү керек, бул photo.status башка мааниге өзгөртүүнү жана тиешелүү эсептегичтерди өчүрүүнү билдирет. Албетте, эгерде бул операция колдонуунун атомдуулугунун кепилдиктерисиз жана атаандаш модификацияларды обочолонтуусуз жүрсө, КЫЧКЫЛ, анда натыйжа керектүү нерсе болбойт - же фото эсептегич туура эмес маанини көрсөтөт, же бардык сүрөттөр модерацияга жөнөтүлбөйт.

Бир транзакциянын ичинде ар кандай бизнес субъектилерин манипуляциялоочу көптөгөн окшош коддор Одноклассникинин бүткүл жашоосунда жазылган. NoSQLге көчүрүү тажрыйбасынын негизинде Акыркы ырааттуулук Биз эң чоң кыйынчылык (жана убакытты инвестициялоо) маалыматтардын ырааттуулугун сактоо үчүн кодду иштеп чыгуудан келерин билебиз. Ошондуктан, биз жаңы сактагычтын негизги талабын тиркеме логикасы үчүн реалдуу ACID транзакцияларын камсыз кылуу деп эсептедик.

Башка, андан кем эмес маанилүү талаптар:

  • Эгер маалымат борбору иштебей калса, жаңы сактагычка окуу жана жазуу жеткиликтүү болушу керек.
  • Учурдагы өнүгүү ылдамдыгын сактоо. Башкача айтканда, жаңы репозиторий менен иштөөдө коддун көлөмү болжол менен бирдей болушу керек, репозиторийге эч нерсе кошуунун, конфликттерди чечүү үчүн алгоритмдерди иштеп чыгуунун, экинчилик индекстерди сактоонун ж.б.у.с. кереги жок.
  • Жаңы сактагычтын ылдамдыгы маалыматтарды окуп жатканда да, транзакцияларды иштеп чыгууда да кыйла жогору болушу керек болчу, бул эффективдүү түрдө академиялык жактан катуу, универсалдуу, бирок жай чечимдерди, мисалы, колдонууга болбойт дегенди билдирет. эки фазалуу милдеттенмелер.
  • Автоматтык түрдө масштабдоо.
  • Экзотикалык жабдыктарды сатып алуунун зарылдыгы жок кадимки арзан серверлерди колдонуу.
  • Компаниянын иштеп чыгуучулары тарабынан сактоону өнүктүрүү мүмкүнчүлүгү. Башкача айтканда, приоритеттүү же ачык булактуу чечимдерге артыкчылык берилген, эң жакшысы Java.

Чечимдер чечимдер

Мүмкүн болгон чечимдерди талдап, биз эки мүмкүн болгон архитектуралык тандоого келдик:

Биринчиси, кандайдыр бир SQL серверин алып, талап кылынган катага чыдамдуулукту, масштабдоо механизмин, иштен чыгуу кластерин, конфликттерди чечүү жана бөлүштүрүлгөн, ишенимдүү жана тез ACID транзакцияларын ишке ашыруу. Биз бул вариантты өтө маанилүү эмес жана көп эмгекти талап кылган деп бааладык.

Экинчи вариант - ишке ашырылган масштабдоо, иштебей калуу кластери, конфликттерди чечүү жана транзакцияларды жана SQLди өзүңүз ишке ашыруу менен даяр NoSQL сактагычын алуу. Бир караганда, ACID транзакцияларын айтпаганда да, SQLди ишке ашыруу милдети да көп жылдарды талап кыла турган иш сыяктуу көрүнөт. Бирок кийин биз иш жүзүндө колдонгон SQL өзгөчөлүктөрү топтому ANSI SQLден алыс экенин түшүндүк Кассандра CQL ANSI SQLден алыс. CQLге тереңирээк көз чаптырып, биз ал бизге керектүү нерсеге абдан жакын экенин түшүндүк.

Кассандра жана CQL

Ошентип, Кассандранын эмнеси кызык, анын кандай мүмкүнчүлүктөрү бар?

Биринчиден, бул жерде ар кандай маалымат түрлөрүн колдогон таблицаларды түзө аласыз; негизги ачкычта SELECT же ЖАҢЫРТУУ жасай аласыз.

CREATE TABLE photos (id bigint KEY, owner bigint,…);
SELECT * FROM photos WHERE id=?;
UPDATE photos SET … WHERE id=?;

Реплика маалыматтарынын ырааттуулугун камсыз кылуу үчүн Кассандра колдонот кворум мамилеси. Эң жөнөкөй учурда, бул бир катардын үч репликасы кластердин ар кандай түйүндөрүнө жайгаштырылганда, эгерде түйүндөрдүн көпчүлүгү (башкача айтканда, үчтөн экөө) бул жазуу операциясынын ийгилигини ырастаса, жазуу ийгиликтүү деп эсептелет дегенди билдирет. . Катар маалыматтары ырааттуу деп эсептелет, эгерде окуп жатканда түйүндөрдүн көпчүлүгү сурамжылоодон өтүп, аларды тастыктаса. Ошентип, үч реплика менен, бир түйүн иштебей калса, толук жана ыкчам маалымат ырааттуулугу кепилденет. Бул ыкма бизге дагы ишенимдүү схеманы ишке ашырууга мүмкүндүк берди: ар дайым үч репликага тең суроо-талаптарды жөнөтүү, эки эң ылдамдан жооп күтүп туруу. Үчүнчү репликанын кеч жообу бул учурда жокко чыгарылат. Кечигип жооп берген түйүндө олуттуу көйгөйлөр болушу мүмкүн - тормоздор, JVMде таштанды чогултуу, Linux ядросунда эстутумдун түз калыбына келтирилиши, аппараттык камсыздоонун бузулушу, тармактан ажыратуу. Бирок, бул кардардын операцияларына же маалыматтарына эч кандай таасир этпейт.

Үч түйүн менен байланышып, экөөнөн жооп алган ыкма деп аталат спекуляция: кошумча репликаларга суроо-талап ал "түшүп кете электе" жөнөтүлөт.

Кассандранын дагы бир артыкчылыгы - бул Batchlog, бул сиз киргизген өзгөртүүлөрдүн партиясы толугу менен колдонулушун же такыр колдонулбагандыгын камсыз кылган механизм. Бул бизге ACIDдеги А-ны чечүүгө мүмкүндүк берет - кутудан чыккан атомдук.

Кассандрадагы транзакцияларга эң жакын нерсе - бул "жеңил транзакциялар". Бирок алар алыс "чыныгы" ACID бүтүмдөр: чындыгында, бул эмне үчүн мүмкүнчүлүк болуп саналат CAS оор салмактагы Paxos протоколун колдонуу менен консенсусту колдонуу менен бир гана рекорддон алынган маалыматтар боюнча. Ошондуктан, мындай бүтүмдөрдүн ылдамдыгы төмөн.

Кассандрага эмне жетишпей жатты

Ошентип, биз Кассандрада чыныгы ACID транзакцияларын ишке ашырууга туура келди. Аларды колдонуу менен биз классикалык СББнын дагы эки ыңгайлуу мүмкүнчүлүктөрүн оңой эле ишке ашыра алабыз: ырааттуу тез индекстер, бул бизге маалыматтарды тандоону негизги ачкыч менен гана эмес, жана монотондук автоматтык өсүү идентификаторлорунун кадимки генератору.

C*Бир

Ошентип, жаңы DBMS пайда болду C*Бир, сервер түйүндөрүнүн үч түрүнөн турат:

  • Сактоо - (дээрлик) локалдык дисктерде маалыматтарды сактоо үчүн жооптуу стандарттуу Кассандра серверлери. Маалыматтардын жүктөмү жана көлөмү өскөн сайын, алардын санын ондогон жана жүздөгөн санга чейин оңой эле кеңейтүүгө болот.
  • Транзакциялардын координаторлору - бүтүмдөрдүн аткарылышын камсыз кылуу.
  • Кардарлар бизнес операцияларын ишке ашырган жана транзакцияларды баштаган тиркеме серверлери. Мындай кардарлардын саны миңдеп саналат.

NewSQL = NoSQL+ACID

Бардык типтеги серверлер жалпы кластердин бир бөлүгү болуп саналат, бири-бири менен байланышуу үчүн ички Кассандра билдирүү протоколун колдонушат жана ушак кластердик маалымат алмашуу үчүн. Heartbeat менен серверлер өз ара бузулуулар жөнүндө билип, бирдиктүү маалымат схемасын - таблицаларды, алардын түзүмүн жана репликациясын сакташат; бөлүү схемасы, кластер топологиясы ж.б.

кардарлар

NewSQL = NoSQL+ACID

Стандарттык драйверлердин ордуна Fat Client режими колдонулат. Мындай түйүн маалыматтарды сактабайт, бирок суроо-талаптарды аткаруу үчүн координатордун ролун аткара алат, башкача айтканда, Кардар өзү анын суроо-талаптарынын координатору катары иштейт: ал сактагыч репликаларын сурайт жана конфликттерди чечет. Бул алыскы координатор менен байланышты талап кылган стандарттуу драйверге караганда ишенимдүү жана тезирээк гана эмес, ошондой эле суроо-талаптарды берүүнү башкарууга мүмкүндүк берет. Кардар үчүн ачык транзакциядан тышкары, суроо-талаптар репозиторийлерге жөнөтүлөт. Эгерде кардар транзакцияны ачкан болсо, анда транзакциянын ичиндеги бардык суроо-талаптар транзакциянын координаторуна жөнөтүлөт.
NewSQL = NoSQL+ACID

Транзакциялардын координатору C*One

Координатор - бул биз C*One үчүн нөлдөн баштап ишке ашырган нерсе. Ал транзакцияларды, кулпуларды жана транзакцияларды колдонуу тартибин башкаруу үчүн жооптуу.

Ар бир тейленген транзакция үчүн координатор убакыт белгисин түзөт: ар бир кийинки транзакция мурунку транзакциядан чоңураак. Кассандранын чыр-чатакты чечүү системасы убакыт белгилерине негизделгендиктен (эки карама-каршы келген жазуулардын, акыркы убакыт белгиси учурдагы деп эсептелет), чыр-чатактар ​​ар дайым кийинки транзакциянын пайдасына чечилет. Ошентип ишке ашырдык Лампорт сааты - бөлүштүрүлгөн системадагы чыр-чатактарды чечүүнүн арзан жолу.

бөгөт коюу

Изоляцияны камсыз кылуу үчүн биз эң жөнөкөй ыкманы колдонууну чечтик - рекорддун негизги ачкычына негизделген пессимисттик кулпулар. Башкача айтканда, транзакцияда жазуу адегенде кулпуланышы керек, андан кийин гана окуу, өзгөртүү жана сактоо керек. Ийгиликтүү ишке ашкандан кийин гана рекорддун кулпусун ачууга болот, андыктан атаандаш транзакциялар аны колдоно алышат.

Мындай кулпуну ишке ашыруу бөлүштүрүлбөгөн чөйрөдө жөнөкөй. Бөлүштүрүлгөн системада эки негизги вариант бар: же кластерде бөлүштүрүлгөн кулпулоону ишке ашыруу, же транзакцияларды бир эле жазууну камтыган транзакцияларды ар дайым бир координатор тейлей тургандай кылып бөлүштүрүү.

Биздин учурда маалыматтар SQLдеги локалдык транзакциялардын топторунун арасында бөлүштүрүлгөндүктөн, координаторлорго локалдык транзакция топторун дайындоо чечими кабыл алынды: бир координатор бардык транзакцияларды 0дөн 9га чейин, экинчиси - 10дон 19га чейинки токендер менен жүргүзөт, жана башка. Натыйжада, координатор инстанцияларынын ар бири транзакция тобунун кожоюну болуп калат.

Андан кийин кулпулар координатордун эсинде баналдык HashMap түрүндө ишке ашырылышы мүмкүн.

Координаторлордун каталары

Бир координатор транзакциялардын тобун гана тейлегендиктен, транзакцияны ишке ашыруунун экинчи аракетинин убактысы бүтүшү үчүн анын ишке ашпай калуу фактысын тез арада аныктоо абдан маанилүү. Бул тез жана ишенимдүү болушу үчүн, биз толугу менен туташкан кворумдун угуу протоколун колдондук:

Ар бир маалымат борборунда жок дегенде эки координатор түйүн бар. Мезгил-мезгили менен ар бир координатор башка координаторлорго жүрөктүн согушу жөнүндө билдирүү жөнөтөт жана аларга анын иштеши, ошондой эле акыркы жолу кластердеги кайсы координаторлордон жүрөктүн кагышы тууралуу кабарларды алганы жөнүндө маалымат берет.

NewSQL = NoSQL+ACID

Башкалардан ушул сыяктуу маалыматты алардын жүрөктүн кагуусу боюнча билдирүүлөрүнүн бир бөлүгү катары алып, ар бир координатор кворум принцибин жетекчиликке алуу менен кайсы кластер түйүндөрү иштеп, кайсынысы иштебей турганын өзү чечет: эгерде X түйүнү кластердеги көпчүлүк түйүндөрдөн нормалдуу абал жөнүндө маалымат алган болсо. Y түйүнүнөн кабарларды алуу, анда , Y иштейт. Тескерисинче, көпчүлүк Y түйүнүнөн кабарлар жок деп кабарлагандан кийин, Y баш тартты. Кызыгы, эгер кворум X түйүнүнө андан билдирүүлөрдү албай калганын билдирсе, анда X түйүнү өзүн ийгиликсиз деп эсептейт.

Жүрөктүн согушу тууралуу билдирүүлөр секундасына 20 жолу, 50 мс мезгили менен жогорку жыштык менен жөнөтүлөт. Жавада таштанды жыйноочу себеп болгон тыныгуулардын салыштырмалуу узундугуна байланыштуу 50 мс ичинде тиркеменин жообун кепилдик берүү кыйын. Биз бул жооп убактысына G1 таштанды жыйноочу аркылуу жетише алдык, бул бизге GC тыныгууларынын узактыгы үчүн максатты көрсөтүүгө мүмкүндүк берет. Бирок, кээде, өтө сейрек, коллектордук тыныгуулар 50 мс ашат, бул жалган катаны аныктоого алып келиши мүмкүн. Буга жол бербөө үчүн координатор алыскы түйүндөн жүрөктүн кагышынын биринчи кабары жоголуп кеткенде, анын иштебей калгандыгы жөнүндө кабарлабайт, эгерде бир нечеси катары менен жоголсо гана.. Биз 200-жылы координатор түйүнүнүн бузулушун ушинтип аныктай алдык. Айым.

Бирок кайсы түйүн иштебей калганын тез түшүнүү жетишсиз. Биз бул боюнча бир нерсе кылышыбыз керек.

Резерв

Классикалык схема, кожоюн иштебей калса, алардын бирин колдонуп жаңы шайлоону баштоону камтыйт модалуу универсалдуу алгоритмдер. Бирок, мындай алгоритмдердин убакыттын конвергенциясы жана шайлоо процессинин узактыгы боюнча белгилүү көйгөйлөрү бар. Толук туташкан тармактагы координаторлорду алмаштыруу схемасын колдонуп, мындай кошумча кечигүүлөрдү болтурбай алдык:

NewSQL = NoSQL+ACID

Келгиле, биз 50-топтогу транзакцияны аткаргыбыз келет дейли. Алдын ала алмаштыруу схемасын аныктайлы, башкача айтканда, негизги координатор иштебей калган учурда 50-топтогу транзакцияларды кайсы түйүндөр аткара тургандыгын аныктайлы. Биздин максат - маалымат борбору иштебей калган учурда системанын иштешин сактап калуу. Биринчи резерв башка маалымат борборунан түйүн, ал эми экинчи резерв үчүнчүдөн түйүн болорун аныктайлы. Бул схема бир жолу тандалып алынат жана кластердин топологиясы өзгөрмөйүнчө, башкача айтканда, ага жаңы түйүндөр киргенге чейин өзгөрбөйт (бул өтө сейрек кездешет). Эгерде эскиси иштебей калса, жаңы активдүү мастерди тандоо жол-жобосу дайыма төмөнкүдөй болот: биринчи резерв активдүү мастерге айланат, ал эми ал иштебей калса, экинчи резерв активдүү мастер болуп калат.

Бул схема универсалдуу алгоритмге караганда ишенимдүү, анткени жаңы мастерди иштетүү үчүн эскинин иштебей калгандыгын аныктоо жетиштүү.

Бирок кардарлар азыр кайсы мастер иштеп жатканын кантип түшүнүшөт? Миңдеген кардарларга 50 мс ичинде маалымат жөнөтүү мүмкүн эмес. Кардар транзакцияны ачууга суроо-талапты жөнөткөндө, бул мастер иштебей калганын али билбестен, суроо-талаптын күтүлбөй калышы мүмкүн. Мунун алдын алуу үчүн кардарлар топтун кожоюнуна жана анын эки резервине бир эле учурда транзакция ачуу өтүнүчүн жөнөтүшөт, бирок бул суроого учурда активдүү кожоюн болгон адам гана жооп берет. Кардар транзакциянын алкагында бардык кийинки байланыштарды активдүү мастер менен гана жүргүзөт.

Камдык кожоюндар өздөрүнө таандык эмес транзакциялар боюнча кабыл алынган суроо-талаптарды төрөлө элек транзакциялардын кезегине коюшат, алар бир нече убакытка чейин сакталат. Эгерде активдүү мастер өлсө, жаңы мастер кезектеги транзакцияларды ачуу өтүнүчтөрүн иштеп чыгат жана кардарга жооп берет. кардар мурунтан эле эски кожоюну менен бүтүм ачкан болсо, анда экинчи жооп четке кагылат (жана, албетте, мындай транзакция аягына чыкпайт жана кардар тарабынан кайталанат).

Транзакция кантип иштейт

Айталы, кардар координаторго баланча негизги ачкыч менен баланча субъект үчүн транзакция ачуу өтүнүчүн жөнөттү. Координатор бул объектти кулпулап, аны эс тутумдагы кулпу таблицасына жайгаштырат. Зарыл болсо, координатор бул объектти сактоодон окуйт жана алынган маалыматтарды координатордун эсинде транзакция абалында сактайт.

NewSQL = NoSQL+ACID

Кардар транзакциядагы маалыматтарды өзгөртүүнү каалаганда, ал координаторго объектти өзгөртүү өтүнүчүн жөнөтөт жана координатор жаңы маалыматтарды эс тутумдагы транзакциянын статусу таблицасына жайгаштырат. Бул жазууну аяктайт - сактагычка эч кандай жазуу жасалбайт.

NewSQL = NoSQL+ACID

Кардар активдүү транзакциянын бөлүгү катары өзүнүн өзгөртүлгөн маалыматтарын сураганда, координатор төмөнкүдөй иш-аракет кылат:

  • эгерде ID мурунтан эле транзакцияда болсо, анда маалыматтар эс тутумдан алынат;
  • эгерде эстутумда ID жок болсо, анда жетишпеген маалыматтар эстутумдагылар менен бириктирилип, сактоо түйүндөрүнөн окулат жана натыйжа кардарга берилет.

Ошентип, кардар өзүнүн өзгөртүүлөрүн окуй алат, бирок башка кардарлар бул өзгөртүүлөрдү көрүшпөйт, анткени алар координатордун эсинде гана сакталат, алар азырынча Кассандра түйүндөрүндө эмес.

NewSQL = NoSQL+ACID

Кардар милдеттенме жөнөткөндө, кызматтын эсинде болгон абал координатор тарабынан журналга жазылган партияда сакталат жана журналга жазылган партия катары Кассандра сактагычына жөнөтүлөт. Дүкөндөр бул пакеттин атомдук түрдө (толугу менен) колдонулушун камсыз кылуу үчүн зарыл болгон нерселердин бардыгын жасашат жана координаторго жооп кайтарышат, ал кулпуларды бошотуп, кардарга транзакциянын ийгилигин тастыктайт.

NewSQL = NoSQL+ACID

Ал эми артка кайтаруу үчүн координатор транзакция абалы ээлеген эстутумду бошотушу керек.

Жогорудагы жакшыртуулардын натыйжасында биз ACID принциптерин ишке ашырдык:

  • Атомдук. Бул системада эч кандай транзакция жарым-жартылай жазылбай тургандыгынын кепилдиги; анын бардык субоперациялары бүтөт, же бири дагы бүтпөйт. Биз бул принципти Кассандрада катталган партия аркылуу карманабыз.
  • ырааттуулук. Ар бир ийгиликтүү транзакция, аныктама боюнча, жарактуу натыйжаларды гана жазат. Эгерде транзакцияны ачып, операциялардын бир бөлүгүн аткаргандан кийин натыйжа жараксыз деп табылса, артка кайтаруу жүргүзүлөт.
  • Изоляция. Транзакцияны ишке ашырууда, параллелдүү операциялар анын жыйынтыгына таасир этпеши керек. Атаандашкан транзакциялар координатордун пессимисттик кулпуларын колдонуу менен обочолонгон. Транзакциядан тышкаркы окуулар үчүн Окуу Committed деңгээлинде изоляция принциби сакталат.
  • Туруктуулук. Төмөнкү деңгээлдеги көйгөйлөргө карабастан – тутумдун өчүрүлүшү, аппараттык камсыздоонун бузулушу – ийгиликтүү аяктаган транзакция менен киргизилген өзгөртүүлөр операциялар кайра башталганда сакталышы керек.

Индекс боюнча окуу

Жөнөкөй таблицаны алалы:

CREATE TABLE photos (
id bigint primary key,
owner bigint,
modified timestamp,
…)

Анын ID (негизги ачкыч), ээси жана өзгөртүү датасы бар. Сиз абдан жөнөкөй суроо-талап кылышыңыз керек - "акыркы күн үчүн" өзгөртүү датасы менен ээси жөнүндө маалыматтарды тандоо.

SELECT *
WHERE owner=?
AND modified>?

Мындай суроо тез иштелип чыгышы үчүн, классикалык SQL DBMSде индексти мамычалар боюнча түзүшүңүз керек (ээси, өзгөртүлгөн). Биз муну оңой эле жасай алабыз, анткени бизде азыр ACID кепилдиктери бар!

C* Oneдагы индекстер

Жазуу ID негизги ачкыч болуп саналган сүрөттөрү бар булак таблицасы бар.

NewSQL = NoSQL+ACID

Индекс үчүн C*One оригиналдын көчүрмөсү болгон жаңы таблицаны түзөт. Ачкыч индекстин туюнтмасы менен бирдей жана булак таблицадагы жазуунун негизги ачкычын да камтыйт:

NewSQL = NoSQL+ACID

Эми "акыркы күндүн ээси" суроосун башка таблицадан тандоо катары кайра жазууга болот:

SELECT * FROM i1_test
WHERE owner=?
AND modified>?

Булак таблицанын фотосүрөттөрүндөгү жана индекс таблицасы i1деги маалыматтардын ырааттуулугу координатор тарабынан автоматтык түрдө сакталат. Бир гана маалымат схемасынын негизинде, өзгөртүү кабыл алынганда, координатор өзгөртүүнү негизги таблицада гана эмес, көчүрмөдө да түзөт жана сактайт. Индекс таблицасында эч кандай кошумча аракеттер жасалбайт, журналдар окулбайт жана кулпулар колдонулбайт. Башкача айтканда, индекстерди кошуу дээрлик эч кандай ресурстарды талап кылбайт жана өзгөртүүлөрдү киргизүү ылдамдыгына дээрлик эч кандай таасир этпейт.

ACIDди колдонуу менен биз SQL сыяктуу индекстерди ишке ашыра алдык. Алар ырааттуу, масштабдуу, тез, түзүлүүчү жана CQL суроо тилине курулган. Индекстерди колдоо үчүн колдонмо кодуна эч кандай өзгөртүүлөр талап кылынбайт. Баары SQLдегидей жөнөкөй. Эң негизгиси, индекстер баштапкы транзакция таблицасына өзгөртүүлөрдү киргизүү ылдамдыгына таасир этпейт.

Эмне болду

Биз C*One компаниясын үч жыл мурун иштеп чыгып, аны коммерциялык ишке киргизгенбиз.

Акырында эмне алдык? Келгиле, муну социалдык тармактагы маалыматтардын эң маанилүү түрлөрүнүн бири болгон фото иштетүү жана сактоо подсистемасынын мисалында баалайлы. Кеп сүрөттөрдүн денелери жөнүндө эмес, ар кандай мета-маалыматтар жөнүндө болуп жатат. Азыр Одноклассникиде 20 миллиардга жакын ушундай жазуулар бар, система секундасына 80 миң окуу сурамдарын, маалыматтарды өзгөртүү менен байланышкан секундасына 8 миңге чейин ACID транзакцияларын иштетет.

Биз SQLди репликация коэффициенти = 1 менен колдонгондо (бирок RAID 10до), фото метаинформация Microsoft SQL Server иштеткен 32 машинадан турган жогорку жеткиликтүү кластерде сакталган (плюс 11 камдык көчүрмө). Ошондой эле резервдик көчүрмөлөрдү сактоо үчүн 10 сервер бөлүнгөн. Жалпысынан 50 кымбат унаа. Мында система резервсиз, номиналдык жүктө иштеген.

Жаңы системага өткөндөн кийин биз репликация коэффициентин алдык = 3 - ар бир маалымат борборунда көчүрмө. Система 63 Кассандра сактоо түйүнүнөн жана 6 координатордук машинадан, бардыгы болуп 69 серверден турат. Бирок бул машиналар алда канча арзан, алардын жалпы баасы SQL системасынын наркынын болжол менен 30% түзөт. Ошол эле учурда жүк 30% сакталат.

C*One киргизүү менен кечигүү да азайды: SQLде жазуу операциясы болжол менен 4,5 мсни алды. C*One - болжол менен 1,6 мс. Транзакциянын узактыгы орто эсеп менен 40 мсден аз, милдеттенме 2 мс ичинде бүтөт, окуу жана жазуу узактыгы орто эсеп менен 2 мс. 99-процентиль – болгону 3-3,1 мс, тайм-ауттардын саны 100 эсеге кыскарды – мунун баары алыпсатыкты кеңири колдонуунун эсебинен.

Азырынча SQL Server түйүндөрүнүн көпчүлүгү иштен чыгарылды; жаңы өнүмдөр C*One аркылуу гана иштелип жатат. Биз C*One булутубузда иштөөгө ыңгайлаштырдык бир булут, бул жаңы кластерлерди жайылтууну тездетүүгө, конфигурацияны жөнөкөйлөтүүгө жана ишти автоматташтырууга мүмкүндүк берди. Булак коду болбосо, муну жасоо алда канча татаал жана түйшүктүү болмок.

Азыр биз башка сактагычтарыбызды булутка өткөрүүнүн үстүндө иштеп жатабыз, бирок бул таптакыр башка окуя.

Source: www.habr.com

Комментарий кошуу