Биз PostgreSQLде sublight боюнча жазабыз: 1 хост, 1 күн, 1 ТБ

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

Биз PostgreSQLде sublight боюнча жазабыз: 1 хост, 1 күн, 1 ТБ

#1. Бөлүнүү

Кантип жана эмне үчүн уюштуруу керектиги жөнүндө макала "теорияда" колдонулуучу бөлүү буга чейин эле болгон, бул жерде биз өзүбүздүн айрым ыкмаларды колдонуу практикасы жөнүндө сүйлөшөбүз жүздөгөн PostgreSQL серверлери үчүн мониторинг кызматы.

"Өткөн күндөр..."

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

Убакыт эпикалык мезгилдей эле, PostgreSQL 9.xтин ар кандай версиялары актуалдуу болгон, андыктан бардык бөлүүлөрдү "кол менен" жасоо керек болчу - аркылуу таблица мурасы жана триггерлер динамикалык багыттоо EXECUTE.

Биз PostgreSQLде sublight боюнча жазабыз: 1 хост, 1 күн, 1 ТБ
Алынган чечим универсалдуу болуп чыкты, аны бардык таблицаларга которууга болот:

  • Баарын сүрөттөгөн бош "башкы" аталык таблица жарыяланды керектүү көрсөткүчтөр жана триггерлер.
  • Кардардын көз карашы боюнча жазуу "тамыр" таблицасында жана ички колдонууда жасалган багыттоо триггери BEFORE INSERT жазуу талап кылынган бөлүмгө "физикалык" киргизилген. Эгер андай нерсе жок болсо, биз өзгөчө учурду кармадык жана...
  • … жардамы менен CREATE TABLE ... (LIKE ... INCLUDING ...) аталык таблицанын шаблонунун негизинде түзүлгөн каалаган датага чектөө менен бөлүмОшентип, маалыматтар алынганда, окуу анда гана аткарылат.

PG10: биринчи аракет

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

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

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

  • индекстин сүрөттөмөлөрүн колдобойт
  • андагы триггерлерди колдобойт
  • эч кимдин "тукуму" боло албайт
  • колдобогула INSERT ... ON CONFLICT
  • бөлүмдү автоматтык түрдө түзө албайт

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

PG10: экинчи мүмкүнчүлүк

Ошентип, биз пайда болгон көйгөйлөрдү биринин артынан бири чече баштадык:

  1. Анткени триггерлер жана ON CONFLICT Биз аларга дагы эле бул жерде жана бул жерде керек экенин байкадык, ошондуктан биз аларды иштеп чыгуу үчүн орто баскычты жасадык прокси таблица.
  2. "Маршруттуктан" кутулдук триггерлерде - башкача айтканда, тартып EXECUTE.
  3. Алар өзүнчө алып чыгышты бардык индекстери менен шаблон таблицасыалар прокси таблицада да жок болушу үчүн.

Биз PostgreSQLде sublight боюнча жазабыз: 1 хост, 1 күн, 1 ТБ
Акыры, мунун бардыгынан кийин, биз негизги үстөлдү жергиликтүү түрдө бөлдүк. Жаңы бөлүмдү түзүү дагы эле арыздын абийиринде.

«Аралоо» сөздүктөр

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

"Фактылар" көптөн бери күнүгө бөлүнгөн, ошондуктан биз эскирген бөлүмдөрдү акырындык менен өчүрдүк, алар бизди тынчсыздандырган жок (журналдар!). Бирок сөздүктөрдө көйгөй бар эле...

Алардын саны көп деп айтууга болбойт, бирок болжол менен 100 ТБ "фактылар" 2.5 ТБ сөздүк түздү. Мындай таблицадан эч нерсени оңой өчүрө албайсыз, аны адекваттуу убакытта кысуу мүмкүн эмес жана ага жазуу акырындык менен жайлай баштады.

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

  • тезирээк жазуу/окуу кичинекей бөлүгүнүн өлчөмүнө байланыштуу
  • эстутум азыраак керектелет компакттуу көрсөткүчтөр менен иштөө менен
  • азыраак маалыматтарды сактоо тез эскирген алып салуу мүмкүнчүлүгүнө байланыштуу

Чаралардын буткул комплексинин натыйжасында CPU жүгү ~30%, диск жүктөө ~50% азайды:

Биз PostgreSQLде sublight боюнча жазабыз: 1 хост, 1 күн, 1 ТБ
Ошол эле учурда, биз азыраак жүктөө менен, маалымат базасына дал ошол нерсени жазууну уланта бердик.

#2. Берилиштер базасынын эволюциясы жана рефакторинги

Ошентип, биз колубуздагы нерсеге токтолдук ар бир күндүн өзүнүн бөлүмү бар маалыматтар менен. Чынында, CHECK (dt = '2018-10-12'::date) — жана бөлүүчү ачкыч жана жазуунун белгилүү бир бөлүмгө түшүү шарты бар.

Биздин кызматыбыздагы бардык отчеттор белгилүү бир датанын контекстинде түзүлгөндүктөн, алар үчүн "бөлүнбөгөн мезгилден" бери индекстер бардык түрлөрү болгон. (Сервер, дата, План шаблону), (Сервер, дата, План түйүнү), (дата, Ката классы, Сервер), ...

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

Биз PostgreSQLде sublight боюнча жазабыз: 1 хост, 1 күн, 1 ТБ
оптималдаштыруу багыты айкын - жөнөкөй бардык индекстерден дата талаасын алып салыңыз бөлүнгөн үстөлдөрдө. Биздин көлөмдөрдү эске алганда, пайда болжол менен 1TB/апта!

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

Биз PostgreSQLде sublight боюнча жазабыз: 1 хост, 1 күн, 1 ТБ

#3. Чокусу жүктү "тартуу"

Жүктөлгөн системалардын чоң көйгөйлөрүнүн бири болуп саналат ашыкча синхрондоштуруу талап кылбаган кээ бир операциялар. Кээде “байкабагандыктан”, кээде “ушинтип жеңилирээк болчу”, бирок эртеби-кечпи андан кутулууга туура келет.

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

Биз PostgreSQLде sublight боюнча жазабыз: 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де sublight боюнча жазабыз: 1 хост, 1 күн, 1 ТБ

Бул сактоо жүктөмүнүн төмөндөшү:

Биз PostgreSQLде sublight боюнча жазабыз: 1 хост, 1 күн, 1 ТБ

жалпы

"Терабайт күнүнө" жөн гана коркунучтуу угулат. Эгер сиз баарын туура кылсаңыз, анда бул жөн эле 2^40 байт / 86400 секунд = ~12.5 МБ/секал тургай, рабочий IDE бурамалар кармалып турат. 🙂

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

Биз PostgreSQLде sublight боюнча жазабыз: 1 хост, 1 күн, 1 ТБ

Source: www.habr.com

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