Біз PostgreSQL-де қосалқы жарықта жазамыз: 1 хост, 1 күн, 1 ТБ

Жақында мен стандартты рецепттерді қолдана отырып, қалай екенін айттым SQL оқу сұрауларының өнімділігін арттыру PostgreSQL дерекқорынан. Бүгін біз қалай туралы айтатын боламыз жазуды тиімдірек жасауға болады дерекқорда конфигурацияда ешқандай «бұралуларды» пайдаланбай – жай деректер ағындарын дұрыс ұйымдастыру арқылы.

Біз PostgreSQL-де қосалқы жарықта жазамыз: 1 хост, 1 күн, 1 ТБ

№1. Бөлу

Оны қалай және неге ұйымдастыру керектігі туралы мақала қолданбалы бөлу «теориялық» бұрыннан бар, бұл жерде біз өзіміздің кейбір тәсілдерді қолдану тәжірибесі туралы айтатын боламыз жүздеген PostgreSQL серверлеріне арналған бақылау қызметі.

«Өткен күндер...»

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

Уақыт эпикалық уақыт сияқты болды, PostgreSQL 9.x-тің әртүрлі нұсқалары өзекті болды, сондықтан барлық бөлуді «қолмен» орындау керек болды - арқылы кесте мұрасы және триггерлер динамикалық бағыттау EXECUTE.

Біз PostgreSQL-де қосалқы жарықта жазамыз: 1 хост, 1 күн, 1 ТБ
Алынған шешім әмбебап болып шықты, оны барлық кестелерге аударуға болады:

  • Барлығын сипаттайтын бос «тақырып» ата-аналық кестесі жарияланды қажетті индекстер мен триггерлер.
  • Клиенттің көзқарасы бойынша жазба «түбір» кестесінде және ішкі қолдану арқылы жасалды маршруттау триггері BEFORE INSERT жазба қажетті бөлімге «физикалық түрде» енгізілді. Егер мұндай нәрсе әлі болмаса, біз ерекше жағдайды ұстадық және...
  • … көмегімен CREATE TABLE ... (LIKE ... INCLUDING ...) негізгі кестенің үлгісі негізінде құрылды қалаған күнге шектеуі бар бөлімсондықтан деректер алынған кезде оқу тек онда орындалады.

PG10: бірінші әрекет

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

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

Нұсқаулықты зерттегеннен кейін белгілі болғандай, осы нұсқадағы жергілікті түрде бөлінген кесте:

  • индекс сипаттамаларын қолдамайды
  • ондағы триггерлерді қолдамайды
  • ешкімнің «ұрпағы» бола алмайды
  • қолдамайды INSERT ... ON CONFLICT
  • бөлімді автоматты түрде жасай алмайды

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

PG10: екінші мүмкіндік

Сонымен, біз туындаған мәселелерді бір-бірлеп шешуге кірістік:

  1. Себебі триггерлер және ON CONFLICT Біз олардың әлі де бізге қажет екенін анықтадық, сондықтан біз оларды өңдеу үшін аралық кезең жасадық прокси кестесі.
  2. «Маршруттаудан» құтылдық триггерлерде - яғни, бастап EXECUTE.
  3. Олар оны бөлек алып шықты барлық индекстері бар үлгілік кестеолар тіпті прокси кестесінде де болмауы үшін.

Біз PostgreSQL-де қосалқы жарықта жазамыз: 1 хост, 1 күн, 1 ТБ
Соңында, осының бәрінен кейін біз негізгі кестені жергілікті түрде бөлдік. Жаңа бөлімді құру әлі де қосымшаның ар-ожданында.

«Аралау» сөздіктері

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

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

Олар көп болды деп айтпаймын, бірақ шамамен 100 ТБ «фактілер» нәтижесінде 2.5 ТБ сөздік пайда болды. Мұндай кестеден ештеңені оңай жоя алмайсыз, оны тиісті уақытта қыса алмайсыз және оған жазу бірте-бірте баяулады.

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

  • жылдамырақ жазу/оқу секция көлемінің кішірек болуына байланысты
  • жадты аз пайдаланады ықшам индекстермен жұмыс істеу арқылы
  • деректерді азырақ сақтайды ескіргендерді тез жою мүмкіндігіне байланысты

Барлық кешенді шаралардың нәтижесінде CPU жүктемесі ~30%, диск жүктемесі ~50% төмендеді:

Біз PostgreSQL-де қосалқы жарықта жазамыз: 1 хост, 1 күн, 1 ТБ
Сонымен қатар, біз деректер базасына дәл сол нәрсені жазуды жалғастырдық, тек аз жүктемемен.

№2. Мәліметтер қорының эволюциясы және рефакторинг

Сондықтан біз қолымызда бар нәрсеге тоқтадық әр күннің өз бөлімі бар деректермен. Шын мәнінде, CHECK (dt = '2018-10-12'::date) — және бөлу кілті және жазбаның белгілі бір бөлімге түсу шарты бар.

Біздің қызметіміздегі барлық есептер белгілі бір күн контекстінде құрастырылғандықтан, олар үшін «бөлінбеген уақыттан» бері индекстер барлық түрлер болды. (Сервер, дата, Жоспар үлгісі), (Сервер, дата, Жоспар түйіні), (дата, Қате класы, Сервер)...

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

Біз PostgreSQL-де қосалқы жарықта жазамыз: 1 хост, 1 күн, 1 ТБ
Оңтайландыру бағыты айқын – қарапайым барлық индекстерден күн өрісін алып тастаңыз бөлінген кестелерде. Біздің көлемдерімізді ескере отырып, пайда шамамен 1 ТБ/апта!

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

Біз PostgreSQL-де қосалқы жарықта жазамыз: 1 хост, 1 күн, 1 ТБ

№3. Ең жоғары жүктемені «тарату».

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

Алдыңғы суретті үлкейтіп көрейік, бізде диск бар Қос амплитудасы бар жүктеме астында «сорғылар». Көршілес үлгілер арасында мұндай операциялардың саны «статистикалық түрде» болмауы керек:

Біз PostgreSQL-де қосалқы жарықта жазамыз: 1 хост, 1 күн, 1 ТБ

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

setInterval(sendToDB, interval)

Бұл жерде мәселе дәл осында барлық ағындар шамамен бір уақытта басталады, сондықтан олардың жіберу уақыты әрдайым дерлік «нүктеге» сәйкес келеді. Ой №2...

Бақытымызға орай, мұны түзету өте оңай, «кездейсоқ» жүгіруді қосу уақыт бойынша:

setInterval(sendToDB, interval * (1 + 0.1 * (Math.random() - 0.5)))

№4. Біз қажет нәрсені кэштейміз

Үшінші дәстүрлі жоғары жүктеме мәселесі кэш жоқ ол қайда мүмкін болу.

Мысалы, біз жоспар түйіндері тұрғысынан талдауға мүмкіндік бердік (осының барлығы Seq Scan on users), бірақ олар көбінесе бірдей деп ойлаңыз - олар ұмытып кетті.

Жоқ, әрине, дерекқорға ештеңе жазылмайды, бұл триггерді өшіреді INSERT ... ON CONFLICT DO NOTHING. Бірақ бұл деректер әлі де дерекқорға жетеді және бұл қажет емес қайшылықты тексеру үшін оқу істеу керек. Ой №3...

Кэштеу қосылғанға дейін/кейін дерекқорға жіберілген жазбалар санындағы айырмашылық айқын:

Біз PostgreSQL-де қосалқы жарықта жазамыз: 1 хост, 1 күн, 1 ТБ

Бұл сақтау жүктемесінің ілеспе төмендеуі:

Біз PostgreSQL-де қосалқы жарықта жазамыз: 1 хост, 1 күн, 1 ТБ

Барлығы

«Тәулігіне терабайт» жай ғана қорқынышты естіледі. Егер сіз бәрін дұрыс жасасаңыз, бұл жай ғана 2^40 байт / 86400 секунд = ~12.5 МБ/сбұл тіпті жұмыс үстелінің IDE бұрандалары да ұсталады. 🙂

Бірақ шындап айтсақ, күндізгі жүктеменің он есе «қисайуы» болса да, сіз заманауи SSD мүмкіндіктерін оңай кездестіре аласыз.

Біз PostgreSQL-де қосалқы жарықта жазамыз: 1 хост, 1 күн, 1 ТБ

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

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