Пишемо у ПостгреСКЛ-у на подсветлу: 1 хост, 1 дан, 1ТБ

Недавно сам вам рекао како, користећи стандардне рецепте повећати перформансе СКЛ упита за читање из ПостгреСКЛ базе података. Данас ћемо причати о томе како снимање може бити ефикасније у бази података без употребе икаквих „окретања“ у конфигурацији – једноставно правилним организовањем токова података.

Пишемо у ПостгреСКЛ-у на подсветлу: 1 хост, 1 дан, 1ТБ

#1. Сецтионинг

Чланак о томе како и зашто је вредно организовати примењено партиционисање „у теорији“ је већ било, овде ћемо говорити о пракси примене неких приступа у оквиру нашег сервис за надгледање стотина ПостгреСКЛ сервера.

"Ствари прошлих дана..."

У почетку, као и сваки МВП, наш пројекат је почео под прилично малим оптерећењем - надгледање је вршено само за десет најкритичнијих сервера, све табеле су биле релативно компактне... Али како је време одмицало, број надгледаних хостова је постајао све већи и већи. , и још једном смо покушали да урадимо нешто са једним од столови величине 1.5ТБ, схватили смо да је, иако је могуће наставити овако да живи, било веома незгодно.

Времена су била скоро као епска времена, различите верзије ПостгреСКЛ 9.к су биле релевантне, тако да је све партиционирање морало да се уради „ручно“ – преко наслеђивање табеле и покретачи рутирање са динамичким EXECUTE.

Пишемо у ПостгреСКЛ-у на подсветлу: 1 хост, 1 дан, 1ТБ
Добијено решење се показало довољно универзалним да се може превести на све табеле:

  • Декларисана је празна родитељска табела „хеадер“, која је све описала неопходни индекси и покретачи.
  • Запис из клијентове тачке гледишта је направљен у „роот“ табели и интерно коришћењем окидач за рутирање BEFORE INSERT запис је "физички" убачен у тражени одељак. Да тога још није било, ухватили смо изузетак и...
  • … коришћењем CREATE TABLE ... (LIKE ... INCLUDING ...) је креиран на основу шаблона матичне табеле одељак са ограничењем на жељени датумтако да се приликом преузимања података читање врши само у њима.

ПГ10: први покушај

Али партиционисање путем наслеђивања историјски није било добро за рад са активним током писања или великим бројем подређених партиција. На пример, можете се сетити да је алгоритам за избор потребног одељка имао квадратна сложеност, да ради са 100+ секција, сами разумете како...

У ПГ10 ова ситуација је у великој мери оптимизована имплементацијом подршке изворно партиционисање. Стога смо одмах покушали да га применимо одмах након миграције складишта, али...

Као што се испоставило након копања кроз приручник, изворно партиционирана табела у овој верзији је:

  • не подржава описе индекса
  • не подржава окидаче на њему
  • не може бити ничији "потомак"
  • ne podržavaju INSERT ... ON CONFLICT
  • не може аутоматски да генерише одељак

Пошто смо задобили болан ударац грабљама у чело, схватили смо да је немогуће без модификације апликације и одложили даље истраживање за шест месеци.

ПГ10: друга шанса

Дакле, почели смо да решавамо проблеме који су се појавили један по један:

  1. Јер окидачи и ON CONFLICT Открили смо да су нам још увек потребни ту и тамо, па смо направили међуфазу да их разрадимо проки табле.
  2. Отарасио се "рутирања" у окидачима – односно од EXECUTE.
  3. Изнели су га посебно табела шаблона са свим индексиматако да их нема ни у прокси табели.

Пишемо у ПостгреСКЛ-у на подсветлу: 1 хост, 1 дан, 1ТБ
Коначно, после свега овога, поделили смо главну табелу изворно. Стварање новог одељка је и даље препуштено савести апликације.

„Тестерисање“ речника

Као и у сваком аналитичком систему, и ми смо имали "чињенице" и "резови" (речници). У нашем случају, у овом својству су деловали нпр. тело шаблона слични спори упити или текст самог упита.

„Чињенице“ су се већ дуго делиле по данима, па смо мирно брисали застареле одељке и нису нам сметали (логови!). Али постојао је проблем са речницима...

Да не кажем да их је било много, али отприлике 100 ТБ „чињеница“ резултирало је речником од 2.5 ТБ. Не можете згодно да избришете ништа из такве табеле, не можете је компресовати у одговарајућем времену, а писање у њу је постепено постајало спорије.

Као речник... у њему сваки запис треба да буде представљен тачно једном... и ово је тачно, али!.. Нико нам не брани да имамо посебан речник за сваки дан! Да, ово доноси одређену редундантност, али омогућава:

  • брже писати/читати због мање величине пресека
  • троше мање меморије радом са компактнијим индексима
  • складиштити мање података због могућности брзог уклањања застарелих

Као резултат читавог комплекса мера Оптерећење процесора је смањено за ~30%, оптерећење диска за ~50%:

Пишемо у ПостгреСКЛ-у на подсветлу: 1 хост, 1 дан, 1ТБ
Истовремено, наставили смо да уписујемо потпуно исту ствар у базу података, само са мањим оптерећењем.

#2. Еволуција базе података и рефакторисање

Дакле, решили смо оно што имамо сваки дан има свој одељак са подацима. Заправо, CHECK (dt = '2018-10-12'::date) — и постоји кључ за партицију и услов да запис падне у одређени одељак.

Пошто су сви извештаји у нашем сервису направљени у контексту одређеног датума, индекси за њих од „непартиционираних времена“ су сви типови (Сервер, датум, шаблон плана), (Сервер, датум, План чвор), (датум, класа грешке, сервер), ...

Али сада живе на сваком делу ваше копије сваки такав индекс... И у оквиру сваког одељка датум је константа... Испада да смо сада у сваком таквом индексу једноставно унесите константу као једно од поља, што повећава и његов обим и време тражења за њега, али не доноси никакав резултат. Грабуље су оставили сами себи, опа...

Пишемо у ПостгреСКЛ-у на подсветлу: 1 хост, 1 дан, 1ТБ
Правац оптимизације је очигледан - једноставан уклоните поље датума из свих индекса на подељеним столовима. С обзиром на наше количине, добитак је отприлике 1ТБ/недељно!

Сада да приметимо да је овај терабајт ипак морао некако да се сними. Односно, и ми диск би сада требало да се мање учитава! Ова слика јасно показује ефекат који се добија од чишћења, којем смо посветили недељу дана:

Пишемо у ПостгреСКЛ-у на подсветлу: 1 хост, 1 дан, 1ТБ

#3. „Ширење“ вршног оптерећења

Један од великих проблема учитаних система је редундантна синхронизација неке операције које то не захтевају. Понекад „зато што нису приметили”, некада „тако је било лакше”, али пре или касније морате да се решите тога.

Хајде да увећамо претходну слику и видимо да имамо диск „пумпе“ под оптерећењем са двоструком амплитудом између суседних узорака, што очигледно „статистички“ не би требало да се деси са оволиким бројем операција:

Пишемо у ПостгреСКЛ-у на подсветлу: 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...

Разлика у броју записа послатих у базу података пре/после омогућавања кеширања је очигледна:

Пишемо у ПостгреСКЛ-у на подсветлу: 1 хост, 1 дан, 1ТБ

А ово је пратећи пад оптерећења складишта:

Пишемо у ПостгреСКЛ-у на подсветлу: 1 хост, 1 дан, 1ТБ

Укупно

„Терабајт по дану“ једноставно звучи застрашујуће. Ако све урадите како треба, онда је ово праведно 2^40 бајтова / 86400 секунди = ~12.5МБ/сда чак и десктоп ИДЕ шрафови држе. 🙂

Али озбиљно, чак и са десетоструким „искривљењем“ оптерећења током дана, лако можете задовољити могућности модерних ССД-ова.

Пишемо у ПостгреСКЛ-у на подсветлу: 1 хост, 1 дан, 1ТБ

Извор: ввв.хабр.цом

Додај коментар