Бұл дерекқор туралы көбірек әзірлеушілер білуі керек

Ескерту. аударма: Яана Доган – Google компаниясының тәжірибелі инженері, ол қазір Go бағдарламасында жазылған компанияның өндірістік қызметтерін бақылау мүмкіндігімен жұмыс істейді. Ағылшын тілді аудитория арасында үлкен танымалдылыққа ие болған бұл мақалада ол 17 тармақта ДҚБЖ (және кейде тұтастай таратылатын жүйелер) туралы маңызды техникалық мәліметтерді жинады, олар үлкен/талапты қосымшаларды әзірлеушілер үшін пайдалы.

Бұл дерекқор туралы көбірек әзірлеушілер білуі керек

Компьютерлік жүйелердің басым көпшілігі олардың күйін қадағалайды және сәйкесінше деректерді сақтау жүйесінің қандай да бір түрін қажет етеді. Мен ұзақ уақыт бойы деректер қоры туралы білім жинадым, бұл жол бойында деректердің жоғалуы мен үзілуіне әкеліп соқтырған дизайн қателеріне жол бердім. Ақпараттың үлкен көлемін өңдейтін жүйелерде мәліметтер базасы жүйе архитектурасының негізінде жатыр және оңтайлы шешімді таңдауда негізгі элемент ретінде әрекет етеді. Мәліметтер қорының жұмысына мұқият назар аударылғанына қарамастан, қолданбаларды әзірлеушілер болжауға тырысатын мәселелер көбінесе айсбергтің ұшы ғана болып табылады. Осы мақалалар сериясында мен осы салада маманданбаған әзірлеушілер үшін пайдалы болатын кейбір идеялармен бөлісемін.

  1. Желінің 99,999% уақытында ақаулар тудырмаса, сіз бақыттысыз.
  2. ACID әртүрлі нәрсені білдіреді.
  3. Әрбір дерекқордың жүйелілік пен оқшаулануды қамтамасыз ететін өз механизмдері бар.
  4. Оптимистік бұғаттау әдеттегіні сақтау қиын болған кезде көмекке келеді.
  5. Лас оқулар мен деректерді жоғалтудан басқа басқа да ауытқулар бар.
  6. Мәліметтер базасы мен пайдаланушы іс-әрекет барысына әрқашан келісе бермейді.
  7. Қолданба деңгейіндегі үзінділерді қолданбадан тыс жылжытуға болады.
  8. Автоматты көбейту қауіпті болуы мүмкін.
  9. Ескірген деректер пайдалы болуы мүмкін және оларды құлыптауды қажет етпейді.
  10. Бұрмалаулар кез келген уақыт көздеріне тән.
  11. Кешіктірудің көптеген мағынасы бар.
  12. Белгілі бір транзакция үшін өнімділікке қойылатын талаптар бағалануы керек.
  13. Кірістірілген транзакциялар қауіпті болуы мүмкін.
  14. Транзакциялар қолданба күйіне байланысты болмауы керек.
  15. Сұрауды жоспарлаушылар сізге дерекқорлар туралы көп айта алады.
  16. Онлайн көші-қон қиын, бірақ мүмкін.
  17. Дерекқордың айтарлықтай ұлғаюы болжаусыздықтың ұлғаюына әкеледі.

Мен Эммануэль Одеке, Рейн Генрихс және басқаларға осы мақаланың бұрынғы нұсқасы бойынша пікірлері үшін алғыс айтқым келеді.

Желінің 99,999% уақытында ақаулар тудырмаса, сіз бақыттысыз.

Қазіргі заманғы желілік технологиялар қаншалықты сенімді және желідегі ақауларға байланысты жүйелер қаншалықты жиі істен шығады деген сұрақ қалады. Бұл мәселе бойынша ақпарат аз және зерттеулерде көбінесе мамандандырылған желілері, жабдықтары және персоналы бар ірі ұйымдар басым болады.

Spanner (Google-дың дүние жүзінде таратылған дерекқоры) үшін қолжетімділік деңгейі 99,999% болғанда, Google тек 7,6% проблемалар желіге қатысты. Бұл ретте компания өзінің мамандандырылған желісін жоғары қолжетімділіктің «негізгі тірегі» деп атайды. Оқу Бейлис және Кингсбери, 2014 жылы жүргізілген «таратылған есептеулер туралы қате түсініктерПитер Дойч 1994 жылы тұжырымдаған. Желі шынымен сенімді ме?

Алпауыт компаниялардан тыс кең ауқымды Интернет үшін жүргізілген кешенді зерттеулер жоқ. Сондай-ақ негізгі ойыншылардың тұтынушыларының проблемаларының қанша пайызы желіге қатысты екендігі туралы деректер жеткіліксіз. Біз үлкен бұлттық провайдерлердің желілік стекіндегі үзілістер туралы жақсы білеміз, олар көптеген адамдар мен компанияларға әсер ететін жоғары профильді оқиғалар болғандықтан, Интернеттің барлық бөлігін бірнеше сағат бойы өшіре алады. Желідегі үзілістер көптеген жағдайларда проблемаларды тудыруы мүмкін, тіпті бұл жағдайлардың барлығы назарда болмаса да. Бұлттық қызметтердің клиенттері де ақаулардың себептері туралы ештеңе білмейді. Егер ақаулық орын алса, оны қызмет провайдері жағындағы желі қатесіне жатқызу мүмкін емес. Олар үшін үшінші тарап қызметтері қара жәшіктер болып табылады. Ірі қызмет көрсетуші болмайынша әсерді бағалау мүмкін емес.

Үлкен ойыншылардың өз жүйелері туралы не хабарлағанын ескере отырып, желідегі қиындықтар әлеуетті тоқтап қалу мәселелерінің аз ғана пайызын құраса, сәттілікке жетеді деп айтуға болады. Желілік коммуникациялар әлі де аппараттық құралдың ақаулары, топологияның өзгеруі, әкімшілік конфигурацияның өзгеруі және электр қуатының үзілуі сияқты қарапайым нәрселерден зардап шегеді. Жақында мен ықтимал мәселелер тізімі қосылғанын білгенде таң қалдым акуланың шағуы (иә, сіз дұрыс естідіңіз).

ACID көп нәрсені білдіреді

ACID аббревиатурасы Atomicity, Consistency, оқшаулау, сенімділік дегенді білдіреді. Транзакциялардың бұл қасиеттері сәтсіздіктер, қателер, аппараттық құралдардың ақаулары және т.б. кезінде олардың жарамдылығын қамтамасыз етуге арналған. ACID немесе ұқсас схемаларсыз қолданбаларды әзірлеушілерге олардың не үшін жауапты екенін және дерекқордың не үшін жауап беретінін ажырату қиын болар еді. Реляциялық транзакциялық дерекқорлардың көпшілігі ACID сәйкес болуға тырысады, бірақ NoSQL сияқты жаңа тәсілдер ACID транзакциялары жоқ көптеген дерекқорлардың пайда болуына әкелді, себебі оларды жүзеге асыру қымбат.

Мен салаға алғаш кірген кезде, біздің техникалық жетекші ACID тұжырымдамасының қаншалықты өзекті екендігі туралы айтты. Әділ болу үшін, ACID қатаң енгізу стандарты емес, өрескел сипаттама болып саналады. Бүгін мен оны негізінен пайдалы деп санаймын, себебі ол мәселелердің белгілі бір санатын көтереді (және ықтимал шешімдер ауқымын ұсынады).

Әрбір ДҚБЖ ACID сәйкес келмейді; Сонымен қатар, ACID қолдайтын дерекқорды іске асыру талаптар жиынтығын басқаша түсінеді. ACID енгізулерінің біркелкі болуының себептерінің бірі ACID талаптарын орындау үшін жасалуы керек көптеген келісімдерге байланысты. Жасаушылар өздерінің дерекқорларын ACID-үйлесімді ретінде ұсына алады, бірақ шеткі жағдайлардың интерпретациясы «ықтимал» оқиғаларды өңдеу механизмі сияқты күрт әр түрлі болуы мүмкін. Кем дегенде, әзірлеушілер өздерінің ерекше мінез-құлықтары мен дизайн айырбастарын дұрыс түсіну үшін базалық іске асырудың қыр-сырын жоғары деңгейде түсінеді.

MongoDB ACID талаптарына сәйкес келетіні туралы пікірталас 4 нұсқасы шыққаннан кейін де жалғасуда. MongoDB ұзақ уақыт бойы қолдау көрсетпейді журнал жүргізу, бірақ әдепкі бойынша деректер дискіге 60 секунд сайын бір реттен жиі емес бекітілді. Келесі сценарийді елестетіп көріңіз: қолданба екі жазуды жібереді (w1 және w2). MongoDB w1 файлын сәтті сақтайды, бірақ аппараттық құралдың ақаулығына байланысты w2 жоғалды.

Бұл дерекқор туралы көбірек әзірлеушілер білуі керек
Сценарийді көрсететін диаграмма. MongoDB дискіге деректерді жаза алмас бұрын бұзылады

Дискіге қосылу - қымбат процесс. Жиі міндеттемелерден аулақ бола отырып, әзірлеушілер сенімділік есебінен жазба өнімділігін жақсартады. MongoDB қазіргі уақытта тіркеуді қолдайды, бірақ лас жазулар деректер тұтастығына әсер етуі мүмкін, себебі журналдар әдепкі бойынша 100 мс сайын түсіріледі. Яғни, тәуекел әлдеқайда төмен болса да, журналдар мен олардағы өзгерістер үшін ұқсас сценарий әлі де мүмкін.

Әрбір дерекқордың өзінің жүйелілігі мен оқшаулау механизмдері бар

ACID талаптарының ішінде бірізділік пен оқшаулау әртүрлі енгізулердің ең көп санымен мақтана алады, өйткені айырбастау ауқымы кеңірек. Консистенция мен оқшаулау өте қымбат функциялар екенін айту керек. Олар үйлестіруді талап етеді және деректердің сәйкестігі үшін бәсекелестікті арттырады. Мәселе күрделілігі деректер базасын көлденеңінен бірнеше деректер орталықтары бойынша масштабтау қажет болғанда (әсіресе олар әртүрлі географиялық аймақтарда орналасқан болса) айтарлықтай артады. Жүйеліліктің жоғары деңгейіне жету өте қиын, өйткені ол сондай-ақ қолжетімділікті азайтады және желі сегментациясын арттырады. Бұл құбылыстың жалпы түсіндірмесі үшін мен сізге сілтеме жасауды ұсынамын CAP теоремасы. Сондай-ақ, қолданбалар сәйкессіздіктердің шағын көлемін өңдей алатынын және бағдарламашылар оны өңдеу үшін дерекқорға қатты сенбей, сәйкессіздікті өңдеу үшін қолданбада қосымша логиканы енгізу үшін мәселенің нюанстарын жақсы түсінетінін атап өткен жөн.

ДҚБЖ жиі оқшаулаудың әртүрлі деңгейлерін қамтамасыз етеді. Қолданбаны әзірлеушілер өз қалауларына қарай ең тиімдісін таңдай алады. Төмен оқшаулау жылдамдықты арттыруға мүмкіндік береді, сонымен қатар деректер жарысының қаупін арттырады. Жоғары оқшаулау бұл ықтималдықты азайтады, бірақ жұмысты баяулатады және бәсекелестікке әкелуі мүмкін, бұл істен шығулар басталатын базада осындай тежегіштерге әкеледі.

Бұл дерекқор туралы көбірек әзірлеушілер білуі керек
Қолданыстағы параллельдік үлгілерді және олардың арасындағы қатынастарды шолу

SQL стандарты тек төрт оқшаулау деңгейін анықтайды, дегенмен теория мен тәжірибеде одан да көп. Jepson.io қолданыстағы параллельдік үлгілердің тамаша шолуын ұсынады. Мысалы, Google Spanner сағатты синхрондау арқылы сыртқы сериялануға кепілдік береді және бұл қатаңырақ оқшаулау қабаты болса да, ол стандартты оқшаулау қабаттарында анықталмаған.

SQL стандарты келесі оқшаулау деңгейлерін айтады:

  • Серияланатын (ең қатаң және қымбат): Серияланатын орындау кейбір дәйекті транзакцияны орындау сияқты әсер етеді. Кезекті орындалу әрбір келесі транзакцияның алдыңғысы аяқталғаннан кейін ғана басталатынын білдіреді. деңгейін атап өту керек Серияланатын жиі интерпретациядағы айырмашылықтарға байланысты суретті оқшаулау деп аталатын (мысалы, Oracle-да) ретінде жүзеге асырылады, дегенмен суретті оқшаулаудың өзі SQL стандартында көрсетілмеген.
  • Қайталанатын оқулар: Ағымдағы транзакциядағы бекітілмеген жазбалар ағымдағы транзакция үшін қолжетімді, бірақ басқа транзакциялармен жасалған өзгерістер (жаңа жолдар сияқты) көрінбейді.
  • Міндетті түрде оқыды: Транзакциялар үшін бекітілмеген деректер қолжетімді емес. Бұл жағдайда транзакциялар тек жасалған деректерді көре алады және фантомдық оқулар орын алуы мүмкін. Егер транзакция жаңа жолдарды енгізсе және орындаса, ағымдағы транзакция оларды сұрау кезінде көре алады.
  • Міндетсіз оқыңыз (ең аз қатаң және қымбат деңгей): Лас оқуларға рұқсат етіледі, транзакциялар басқа транзакциялар жасаған реттелмеген өзгерістерді көре алады. Іс жүзінде бұл деңгей сұраулар сияқты өрескел бағалаулар үшін пайдалы болуы мүмкін COUNT(*) үстелдің үстінде.

деңгей Серияланатын енгізу үшін ең қымбат және жүйедегі ең жоғары бәсекеге қабілетті жүктеме бола отырып, деректер жарысының қаупін азайтады. Басқа оқшаулау деңгейлерін енгізу оңайырақ, бірақ деректер жарысының ықтималдығын арттырады. Кейбір ДҚБЖ теңшелетін оқшаулау деңгейін орнатуға мүмкіндік береді, басқаларында күшті теңшелімдер бар және барлық деңгейлерге қолдау көрсетілмейді.

Оқшаулау деңгейлерін қолдау көбінесе берілген ДҚБЖ-да жарнамаланады, бірақ оның мінез-құлқын мұқият зерттеу ғана шын мәнінде не болып жатқанын аша алады.

Бұл дерекқор туралы көбірек әзірлеушілер білуі керек
Әртүрлі ДҚБЖ үшін әртүрлі оқшаулау деңгейлеріндегі параллельдік ауытқуларды шолу

Мартин Клеппман өз жобасында эрмитаж Әртүрлі оқшаулау деңгейлерін салыстырады, параллельдік ауытқулар туралы және дерекқордың белгілі бір оқшаулау деңгейін ұстану мүмкіндігі туралы әңгімелейді. Клеппманның зерттеулері дерекқор әзірлеушілерінің оқшаулау деңгейлері туралы қалай ойлайтынын көрсетеді.

Оптимистік бұғаттау әдеттегіні сақтау қиын болған кезде көмекке келеді.

Бұғаттау деректер базасындағы бәсекелестікті арттыратындықтан ғана емес, сонымен қатар қолданба серверлерінің дерекқорға үнемі қосылуын талап ететіндіктен өте қымбат болуы мүмкін. Желіні сегменттеу эксклюзивті құлыптау жағдайларын күшейтіп, анықтау және шешу қиын тығырықтан шығуға әкелуі мүмкін. Эксклюзивті құлыптау жарамсыз болған жағдайда, оптимистік құлыптау көмектеседі.

Оптимистік құлып жолды оқу кезінде оның нұсқасын, бақылау сомасын немесе соңғы өзгерту уақытын есепке алатын әдіс. Бұл жазбаны өзгертпес бұрын атомдық нұсқа өзгерісінің жоқтығына көз жеткізуге мүмкіндік береді:

UPDATE products
SET name = 'Telegraph receiver', version = 2
WHERE id = 1 AND version = 1

Бұл жағдайда кестені жаңарту products егер бұрын осы жолға басқа операция енгізілген болса, орындалмайды. Егер бұл жолда басқа әрекеттер орындалмаса, бір жолға өзгеріс орын алады және жаңарту сәтті болды деп айта аламыз.

Лас оқулар мен деректерді жоғалтудан басқа басқа да ауытқулар бар

Деректердің сәйкестігі туралы сөз болғанда, лас оқулар мен деректердің жоғалуына әкелетін жарыс жағдайларының әлеуетіне назар аударылады. Дегенмен, деректер ауытқулары мұнымен тоқтамайды.

Мұндай ауытқулардың бір мысалы жазбаның бұрмалануы болып табылады (қиғаштарды жазу). Бұрмалауларды анықтау қиын, өйткені олар әдетте белсенді түрде ізделмейді. Олар лас оқуларға немесе деректердің жоғалуына байланысты емес, деректерге қойылған логикалық шектеулердің бұзылуына байланысты.

Мысалы, бір оператордың үнемі қоңырауда болуын талап ететін мониторинг қолданбасын қарастырайық:

BEGIN tx1;                      BEGIN tx2;
SELECT COUNT(*)
FROM operators
WHERE oncall = true;
0                               SELECT COUNT(*)
                                FROM operators
                                WHERE oncall = TRUE;
                                0
UPDATE operators                UPDATE operators
SET oncall = TRUE               SET oncall = TRUE
WHERE userId = 4;               WHERE userId = 2;
COMMIT tx1;                     COMMIT tx2;

Жоғарыда көрсетілген жағдайда, егер екі транзакция сәтті жасалған болса, рекордтық сыбайлас жемқорлық орын алады. Лас оқулар немесе деректердің жоғалуы болмаса да, деректердің тұтастығы бұзылды: енді екі адам бір уақытта қоңырау шалған болып саналады.

Серияланатын оқшаулау, схема дизайны немесе дерекқор шектеулері жазу бүлінуін жоюға көмектеседі. Өндірісте оларды болдырмау үшін әзірлеушілер әзірлеу кезінде мұндай ауытқуларды анықтай алуы керек. Сонымен бірге жазудың бұрмалануын код базасында іздеу өте қиын. Әсіресе үлкен жүйелерде, әртүрлі әзірлеу топтары бірдей кестелер негізінде функцияларды орындауға жауапты және деректерге қол жеткізу ерекшеліктерімен келіспесе.

Деректер базасы мен пайдаланушы әрқашан не істеу керектігі туралы келіспейді

Мәліметтер қорының негізгі ерекшеліктерінің бірі орындалу ретінің кепілдігі болып табылады, бірақ бұл тапсырыстың өзі бағдарламалық жасақтаманы әзірлеуші ​​үшін ашық болмауы мүмкін. Мәліметтер базасы транзакцияларды бағдарламашылар ойлаған ретпен емес, алынған ретпен орындайды. Транзакциялар тәртібін болжау қиын, әсіресе жоғары жүктелген параллель жүйелерде.

Әзірлеу кезінде, әсіресе блокталмаған кітапханалармен жұмыс істегенде, нашар стиль және төмен оқылу мүмкіндігі пайдаланушылардың транзакциялар дәйекті түрде орындалатынына сенуіне себеп болуы мүмкін, ал шын мәнінде олар дерекқорға кез келген ретпен келуі мүмкін.

Бір қарағанда, төмендегі бағдарламада T1 және T2 дәйекті түрде шақырылады, бірақ егер бұл функциялар блокталмаған болса және нәтижені дереу пішінде қайтарады. уәде беріңіз, содан кейін қоңыраулардың реті деректер базасына енген сәттер бойынша анықталады:

result1 = T1() // нақты нәтижелер - уәде
нәтиже2 = T2()

Егер атомдық қажет болса (яғни, барлық операциялар аяқталуы немесе тоқтатылуы қажет) және реттілік маңызды болса, T1 және T2 операциялары бір транзакция ішінде орындалуы керек.

Қолданба деңгейіндегі үзінділерді қолданбадан тыс жылжытуға болады

Sharding - дерекқорды көлденең бөлу әдісі. Кейбір дерекқорлар деректерді көлденеңінен автоматты түрде бөле алады, ал басқалары мүмкін емес немесе онша жақсы емес. Деректер сәулетшілері/әзірлеушілері деректерге қалай қол жеткізілетінін дәл болжаған кезде, олар бұл жұмысты дерекқорға тапсырудың орнына пайдаланушы кеңістігінде көлденең бөлімдер жасай алады. Бұл процесс «қолданба деңгейінде бөлу» деп аталады. (қолданба деңгейінде бөлу).

Өкінішке орай, бұл атау көбінесе қолданба қызметтерінде бөлісу өмір сүреді деген қате түсінікті тудырады. Шындығында, оны дерекқордың алдында бөлек қабат ретінде іске асыруға болады. Деректердің өсуіне және схема итерацияларына байланысты бөлу талаптары өте күрделі болуы мүмкін. Кейбір стратегиялар қолданба серверлерін қайта орналастырудың қажетінсіз қайталау мүмкіндігінен пайда алуы мүмкін.

Бұл дерекқор туралы көбірек әзірлеушілер білуі керек
Бағдарлама серверлері бөлісу қызметінен бөлінген архитектураның мысалы

Бөлшектеуді бөлек қызметке жылжыту қолданбаларды қайта орналастыру қажеттілігінсіз әртүрлі бөлу стратегияларын пайдалану мүмкіндігін кеңейтеді. Витесс қолданба деңгейіндегі осындай бөлу жүйесінің мысалы болып табылады. Vitess MySQL үшін көлденең бөлуді қамтамасыз етеді және клиенттерге MySQL протоколы арқылы оған қосылуға мүмкіндік береді. Жүйе деректерді бір-бірімен ештеңе білмейтін әртүрлі MySQL түйіндеріне бөледі.

Автоматты көбейту қауіпті болуы мүмкін

AUTOINCREMENT – бастапқы кілттерді жасаудың кең таралған тәсілі. Дерекқорлар идентификатор генераторлары ретінде пайдаланылатын жағдайлар жиі кездеседі және деректер базасында идентификаторларды құруға арналған кестелер болады. Автоматты ұлғайту арқылы бастапқы кілттерді жасау идеалдан алыс болуының бірнеше себептері бар:

  • Бөлінген дерекқорда автоматты ұлғайту маңызды мәселе болып табылады. Идентификаторды жасау үшін жаһандық құлып қажет. Оның орнына сіз UUID жасай аласыз: бұл әртүрлі дерекқор түйіндері арасындағы өзара әрекеттесуді қажет етпейді. Құлыптармен автоматты ұлғайту қайшылыққа әкелуі мүмкін және таратылған жағдайларда кірістірулердің өнімділігін айтарлықтай төмендетуі мүмкін. Кейбір ДҚБЖ (мысалы, MySQL) мастер-мастер репликациясын дұрыс ұйымдастыру үшін арнайы конфигурацияны және мұқият назар аударуды қажет етуі мүмкін. Конфигурациялау кезінде қателіктер жіберу оңай, бұл жазу сәтсіздігіне әкеледі.
  • Кейбір дерекқорларда бастапқы кілттерге негізделген бөлу алгоритмдері бар. Кезекті идентификаторлар күтпеген ыстық нүктелерге және кейбір бөлімдердегі жүктеменің артуына әкелуі мүмкін, ал басқалары бос қалады.
  • Бастапқы кілт - дерекқордағы жолға қол жеткізудің ең жылдам жолы. Жазбаларды анықтаудың жақсы әдістерімен дәйекті идентификаторлар кестелердегі ең маңызды бағанды ​​мағынасыз мәндермен толтырылған пайдасыз бағанға айналдыра алады. Сондықтан мүмкіндігінше жаһандық бірегей және табиғи бастапқы кілтті (мысалы, пайдаланушы аты) таңдаңыз.

Әдіс туралы шешім қабылдамас бұрын, автоматты түрде ұлғайтылатын идентификаторлар мен UUID кодтарының индекстеуге, бөлуге және бөлуге әсерін қарастырыңыз.

Ескірген деректер пайдалы болуы мүмкін және құлыптауды қажет етпейді

Көп нұсқалы параллельді бақылау (MVCC) жоғарыда қысқаша талқыланған көптеген сәйкестік талаптарын жүзеге асырады. Кейбір дерекқорлар (мысалы, Postgres, Spanner) дерекқордың ескі нұсқаларымен транзакцияларды «беру» үшін MVCC пайдаланады. Сәйкестікті қамтамасыз ету үшін сурет транзакцияларын сериялауға болады. Ескі суреттен оқу кезінде ескірген деректер оқылады.

Сәл ескірген деректерді оқу пайдалы болуы мүмкін, мысалы, деректерден аналитика жасау немесе шамамен жиынтық мәндерді есептеу.

Бұрынғы деректермен жұмыс істеудің бірінші артықшылығы - төмен кідіріс (әсіресе дерекқор әртүрлі географиялар бойынша таратылса). Екіншісі, тек оқуға арналған транзакциялар құлыпсыз. Бұл ескі деректерді өңдей алатын болса, көп оқитын қолданбалар үшін маңызды артықшылық.

Бұл дерекқор туралы көбірек әзірлеушілер білуі керек
Бағдарлама сервері соңғы нұсқасы Тынық мұхитының арғы жағында қол жетімді болса да, 5 секунд ескірген жергілікті көшірмедегі деректерді оқиды.

ДҚБЖ ескі нұсқаларды автоматты түрде тазартады және кейбір жағдайларда сұрау бойынша мұны істеуге мүмкіндік береді. Мысалы, Postgres пайдаланушыларға жасауға мүмкіндік береді VACUUM сұрауы бойынша, сондай-ақ мерзімді түрде осы операцияны автоматты түрде орындайды. Spanner бір сағаттан асқан суреттерден құтылу үшін қоқыс жинағышты басқарады.

Кез келген уақыт көздері бұрмалануға ұшырайды

Информатикадағы ең жақсы сақталған құпия - барлық уақыттық API өтірік. Шындығында, біздің машиналар дәл қазіргі уақытты білмейді. Компьютерлерде уақытты сақтау үшін қолданылатын тербелістерді тудыратын кварц кристалдары бар. Дегенмен, олар жеткілікті дәл емес және нақты уақыттан алда/артта болуы мүмкін. Ауысым күніне 20 секундқа жетуі мүмкін. Сондықтан біздің компьютерлеріміздегі уақыт желімен мезгіл-мезгіл синхрондалу керек.

NTP серверлері синхрондау үшін пайдаланылады, бірақ синхрондау процесінің өзі желілік кідірістерге ұшырайды. Тіпті бір деректер орталығында NTP серверімен синхрондау біраз уақытты алады. Қоғамдық NTP серверімен жұмыс істеу одан да үлкен бұрмалауға әкелуі мүмкін екені анық.

Атомдық сағаттар және олардың GPS аналогтары ағымдағы уақытты анықтау үшін жақсырақ, бірақ олар қымбат және күрделі орнатуды қажет етеді, сондықтан оларды әр көлікке орнату мүмкін емес. Осыған байланысты деректер орталықтары деңгейлік тәсілді пайдаланады. Атомдық және/немесе GPS сағаттары нақты уақытты көрсетеді, содан кейін ол екінші серверлер арқылы басқа машиналарға таратылады. Бұл әрбір машина нақты уақыттан белгілі бір ауытқуды сезінетінін білдіреді.

Жағдай қосымшалар мен деректер базаларының жиі әртүрлі машиналарда (әртүрлі деректер орталықтарында болмаса) орналасуымен қиындатады. Осылайша, уақыт әр түрлі машиналарға бөлінген ДҚ түйіндерінде ғана емес әр түрлі болады. Ол қолданба серверінде де басқаша болады.

Google TrueTime мүлдем басқа тәсілді қолданады. Көптеген адамдар Google-дың бұл бағыттағы ілгерілеуі атомдық және GPS сағаттарына банальды көшумен түсіндіріледі деп санайды, бірақ бұл үлкен суреттің бір бөлігі ғана. TrueTime қалай жұмыс істейді:

  • TrueTime екі түрлі көзді пайдаланады: GPS және атомдық сағаттар. Бұл сағаттарда корреляциялық емес сәтсіздік режимдері бар. [мәліметтер алу үшін 5-бетті қараңыз осында - шамамен. аудар.), сондықтан оларды бірлесіп пайдалану сенімділікті арттырады.
  • TrueTime-де әдеттен тыс API бар. Ол уақытты өлшеу қатесі мен оған енгізілген белгісіздікпен интервал ретінде қайтарады. Уақыттың нақты сәті интервалдың жоғарғы және төменгі шекараларының арасында орналасқан. Spanner, Google-дың таратылған дерекқоры, ағымдағы уақыт ауқымнан тыс екенін айту қауіпсіз болғанша күтеді. Бұл әдіс жүйеге кейбір кідірістерді енгізеді, әсіресе шеберлердегі белгісіздік жоғары болса, бірақ тіпті жаһандық таралған жағдайда дұрыстығын қамтамасыз етеді.

Бұл дерекқор туралы көбірек әзірлеушілер білуі керек
Spanner құрамдастары TrueTime функциясын пайдаланады, мұнда TT.now() интервалды қайтарады, сондықтан Spanner ағымдағы уақыттың белгілі бір нүктеден өткеніне сенімді болатын нүктеге дейін жай ғана ұйықтайды.

Ағымдағы уақытты анықтаудағы төмендетілген дәлдік Spanner операцияларының ұзақтығының ұлғаюын және өнімділіктің төмендеуін білдіреді. Сондықтан толық дәл сағатты алу мүмкін болмаса да, ең жоғары дәлдікті сақтау маңызды.

Кешіктірудің көптеген мағынасы бар

Кешігудің не екенін ондаған сарапшылардан сұрасаңыз, әртүрлі жауаптар аласыз. ДҚБЖ-да кідіріс жиі «деректер базасының кешігуі» деп аталады және клиент қабылдайтыннан ерекшеленеді. Өйткені, клиент желі кідірісі мен дерекқор кешігуінің қосындысын бақылайды. Өсіп келе жатқан мәселелерді жөндеу кезінде кідіріс түрін оқшаулау мүмкіндігі өте маңызды. Көрсеткіштерді жинау және көрсету кезінде әрқашан екі түрді де қадағалап көріңіз.

Белгілі бір транзакция үшін өнімділікке қойылатын талаптар бағалануы керек

Кейде ДҚБЖ өнімділік сипаттамалары және оның шектеулері жазу/оқу өткізу қабілеті және кешігуі тұрғысынан көрсетіледі. Бұл жүйенің негізгі параметрлерінің жалпы шолуын қамтамасыз етеді, бірақ жаңа ДҚБЖ өнімділігін бағалау кезінде маңызды операцияларды бөлек бағалау (әр сұрау және/немесе транзакция үшін) анағұрлым жан-жақты тәсіл болып табылады. Мысалдар:

  • Көрсетілген шектеулермен және қатысты кестелердегі жолды толтырумен X кестесіне (50 миллион жолдармен) жаңа жолды кірістіру кезінде өткізу қабілеті мен кідіріс уақытын жазыңыз.
  • Орташа достар саны 500 болған кезде белгілі бір пайдаланушының достарының достарын көрсетудің кешігуі.
  • Пайдаланушы сағатына X жазбалары бар 100 басқа пайдаланушыларды бақылаған кезде, пайдаланушы тарихынан ең жақсы 500 жазбаны шығарып алудағы кідіріс.

Дерекқор өнімділік талаптарына сәйкес келетініне сенімді болмайынша, бағалау және эксперимент осындай маңызды жағдайларды қамтуы мүмкін. Ұқсас ереже кідіріс көрсеткіштерін жинау және SLO анықтау кезінде де осы бөлуді ескереді.

Әрбір операция үшін көрсеткіштерді жинаған кезде жоғары кардиналдық туралы хабардар болыңыз. Жоғары қуатты жөндеу деректерін алу үшін журналдарды, оқиғалар жинағын немесе бөлінген бақылауды пайдаланыңыз. мақаласында «Кешігуді түзеткіңіз келе ме?» сіз кешіктіруді түзету әдістемелерімен таныса аласыз.

Кірістірілген транзакциялар қауіпті болуы мүмкін

Әрбір ДҚБЖ кірістірілген транзакцияларды қолдамайды, бірақ олар жасаған кезде мұндай транзакциялар күтпеген қателерді тудыруы мүмкін, оларды анықтау әрдайым оңай емес (яғни, қандай да бір ауытқушылық бар екені анық болуы керек).

Оларды анықтауға және айналып өтуге болатын клиенттік кітапханаларды пайдаланып кірістірілген транзакцияларды пайдаланудан аулақ бола аласыз. Кірістірілген транзакциялардан бас тарту мүмкін болмаса, кірістірілген транзакцияларға байланысты аяқталған транзакциялар кездейсоқ тоқтатылатын күтпеген жағдайларды болдырмау үшін оларды жүзеге асыруда ерекше сақ болыңыз.

Әртүрлі қабаттардағы транзакцияларды инкапсуляциялау күтпеген кірістірілген транзакцияларға әкелуі мүмкін және кодты оқу мүмкіндігі тұрғысынан автордың ниетін түсінуді қиындатады. Келесі бағдарламаны қараңыз:

with newTransaction():
   Accounts.create("609-543-222")
   with newTransaction():
       Accounts.create("775-988-322")
       throw Rollback();

Жоғарыдағы кодтың нәтижесі қандай болады? Ол екі транзакцияны немесе тек ішкі транзакцияны қайтара ма? Біз үшін транзакцияларды жасауды қамтитын кітапханалардың бірнеше қабаттарына сүйенсек не болады? Осындай жағдайларды анықтап, жетілдіре аламыз ба?

Бірнеше операциялары бар деректер қабатын елестетіңіз (мысалы, newAccount) өзінің транзакцияларында қазірдің өзінде жүзеге асырылған. Оларды өз транзакциясында орындалатын жоғары деңгейдегі бизнес логикасының бөлігі ретінде іске қоссаңыз не болады? Бұл жағдайда оқшаулану және жүйелілік қандай болады?

function newAccount(id string) {
  with newTransaction():
      Accounts.create(id)
}

Осындай шексіз сұрақтарға жауап іздеудің орнына, кірістірілген транзакциялардан аулақ болған дұрыс. Өйткені, сіздің деректер деңгейіңіз өз транзакцияларын жасамай-ақ жоғары деңгейдегі операцияларды оңай орындай алады. Сонымен қатар, бизнес логикасының өзі транзакцияны бастауға, ол бойынша операцияларды орындауға, транзакцияны жасауға немесе тоқтатуға қабілетті.

function newAccount(id string) {
   Accounts.create(id)
}
// In main application:
with newTransaction():
   // Read some data from database for configuration.
   // Generate an ID from the ID service.
   Accounts.create(id)
   Uploads.create(id) // create upload queue for the user.

Транзакциялар қолданба күйіне байланысты болмауы керек

Кейде белгілі бір мәндерді өзгерту немесе сұрау параметрлерін өзгерту үшін транзакцияларда қолданба күйін пайдалану қызықтырады. Қарастырылатын маңызды нюанс - дұрыс қолдану аясы. Желілік ақаулар туындаған кезде клиенттер көбінесе транзакцияларды қайта бастайды. Егер транзакция басқа процесс арқылы өзгертілетін күйге байланысты болса, ол деректер жарысының мүмкіндігіне байланысты қате мәнді таңдауы мүмкін. Транзакциялар қолданбадағы деректер жарысы шарттарының тәуекелін ескеруі керек.

var seq int64
with newTransaction():
    newSeq := atomic.Increment(&seq)
    Entries.query(newSeq)
    // Other operations...

Жоғарыда көрсетілген транзакция соңғы нәтижеге қарамастан орындалған сайын реттік нөмірді арттырады. Желілік ақауларға байланысты тапсырма орындалмаса, қайталап көргенде сұрау басқа реттік нөмірмен орындалады.

Сұрауды жоспарлаушылар сізге дерекқор туралы көп нәрсе айта алады

Сұрауды жоспарлаушылар сұраудың дерекқорда қалай орындалатынын анықтайды. Олар сондай-ақ сұрауларды талдайды және оларды жібермес бұрын оңтайландырады. Жоспарлаушылар қолындағы сигналдарға негізделген кейбір ықтимал бағалауларды ғана ұсына алады. Мысалы, келесі сұрау үшін ең жақсы іздеу әдісі қандай?

SELECT * FROM articles where author = "rakyll" order by title;

Нәтижелерді екі жолмен алуға болады:

  • Толық кестені сканерлеу: Кестедегі әрбір жазбаны қарап, сәйкес автор аты бар мақалаларды қайтара аласыз, содан кейін оларға тапсырыс бере аласыз.
  • Индексті сканерлеу: Сәйкес идентификаторларды табу, сол жолдарды алу, содан кейін оларға тапсырыс беру үшін индексті пайдалануға болады.

Сұрауды жоспарлаушының міндеті – қай стратегияның жақсы екенін анықтау. Сұрауды жоспарлаушылардың тек шектеулі болжау мүмкіндіктері бар екенін ескерген жөн. Бұл дұрыс емес шешімдерге әкелуі мүмкін. DBA немесе әзірлеушілер оларды нашар орындалатын сұрауларды диагностикалау және дәл реттеу үшін пайдалана алады. ДҚБЖ жаңа нұсқалары сұрауды жоспарлаушыларды конфигурациялай алады және жаңа нұсқа өнімділік мәселелеріне әкелсе, дерекқорды жаңарту кезінде өзін-өзі диагностикалау көмектесе алады. Баяу сұрау журналдары, кідіріс мәселесі есептері немесе орындалу уақыты статистикасы оңтайландыруды қажет ететін сұрауларды анықтауға көмектеседі.

Сұрауды жоспарлаушы ұсынған кейбір көрсеткіштер шуылға ұшырауы мүмкін (әсіресе кідіріс немесе процессор уақытын бағалау кезінде). Жоспарлаушыларға жақсы қосымша - орындау жолын қадағалау және қадағалау құралдары. Олар осындай проблемаларды диагностикалауға мүмкіндік береді (өкінішке орай, барлық ДҚБЖ мұндай құралдарды қамтамасыз ете бермейді).

Онлайн көші-қон қиын, бірақ мүмкін

Онлайн көшіру, тікелей көшіру немесе нақты уақыттағы тасымалдау бір дерекқордан екіншісіне тоқтаусыз немесе деректердің бүлінуінсіз көшуді білдіреді. Егер көшу бір ДҚБЖ/қозғалтқышта орын алса, тікелей тасымалдауды орындау оңайырақ. Әртүрлі өнімділік пен схема талаптары бар жаңа ДҚБЖ-ға көшу қажет болғанда жағдай күрделене түседі.

Әр түрлі онлайн көшіру үлгілері бар. Міне, олардың бірі:

  • Екі дерекқорда қос енгізуді қосыңыз. Бұл кезеңдегі жаңа дерекқорда барлық деректер жоқ, тек соңғы деректерді ғана қабылдайды. Бұған сенімді болғаннан кейін келесі қадамға өтуге болады.
  • Екі дерекқордан оқуды қосыңыз.
  • Оқу және жазу негізінен жаңа дерекқорда орындалатындай жүйені конфигурациялаңыз.
  • Деректерді оқуды жалғастыра отырып, ескі дерекқорға жазуды тоқтатыңыз. Бұл кезеңде жаңа деректер базасы әлі де кейбір деректерден айырылған. Оларды ескі дерекқордан көшіру керек.
  • Ескі дерекқор тек оқуға арналған. Ескі дерекқордан жетіспейтін деректерді жаңасына көшіріңіз. Тасымалдау аяқталғаннан кейін жолдарды жаңа дерекқорға ауыстырып, ескісін тоқтатып, оны жүйеден жойыңыз.

Қосымша ақпарат алу үшін хабарласуды ұсынамын мақала, ол осы үлгіге негізделген Stripe тасымалдау стратегиясын егжей-тегжейлі көрсетеді.

Дерекқордың айтарлықтай ұлғаюы болжаусыздықтың ұлғаюына әкеледі

Мәліметтер қорының өсуі оның масштабымен байланысты күтпеген мәселелерге әкеледі. Дерекқордың ішкі құрылымы туралы неғұрлым көбірек білсек, оның масштабталатынын соғұрлым жақсы болжай аламыз. Дегенмен, кейбір сәттерді болжау әлі де мүмкін емес.
Негіз өскен сайын деректер көлемі мен желінің өткізу қабілетіне қойылатын талаптарға қатысты бұрынғы болжамдар мен күтулер ескіруі мүмкін. Бұл жағдайда ықтимал проблемаларды болдырмау үшін дизайнды күрделі жөндеу, ауқымды операциялық жақсартулар, орналастыруды қайта қарастыру немесе басқа ДҚБЖ-ға көшу туралы сұрақ туындайды.

Бірақ бар дерекқордың ішкі құрылымын тамаша білу қажет деп ойламаңыз. Жаңа таразылар өздерімен бірге жаңа белгісіздерді әкеледі. Күтпеген ауырсыну нүктелері, деректерді біркелкі бөлу, күтпеген өткізу қабілеттілігі мен аппараттық мәселелер, үнемі өсіп келе жатқан трафик және жаңа желі сегменттері сізді дерекқор тәсілін, деректер үлгісін, орналастыру үлгісін және дерекқор өлшемін қайта қарауға мәжбүр етеді.

...

Мен осы мақаланы жариялау туралы ойлана бастаған кезде, менің бастапқы тізімімде тағы бес элемент бар еді. Содан кейін үлкен сан келді жаңа идеялар тағы не қамтуға болатыны туралы. Сондықтан мақалада барынша назар аударуды қажет ететін ең аз айқын мәселелер қозғалады. Дегенмен, бұл тақырып таусылды дегенді білдірмейді және мен оған алдағы материалдарымда енді оралмаймын және қазіргіге өзгертулер енгізбеймін.

PS

Біздің блогта да оқыңыз:

Ақпарат көзі: www.habr.com

пікір қалдыру