Уштедите пени на великим количинама у ПостгреСКЛ-у

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

причаћемо о ТОАСТ подешавања и поравнање података. „У просеку“, ове методе неће уштедети превише ресурса, али без модификације кода апликације уопште.

Уштедите пени на великим количинама у ПостгреСКЛ-у
Међутим, наше искуство се показало веома продуктивним у том погледу, пошто је складиштење скоро сваког праћења по својој природи углавном само за додавање у погледу снимљених података. А ако се питате како да научите базу података да уместо тога пише на диск КСНУМКСМБ / с упола мање - молим под кат.

Мале тајне великих података

По профилу посла наш сервис, редовно му лете из јазбине текстуални пакети.

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

Погледајмо структуру једне од табела у коју уписујемо „сирове“ податке – то јест, ево оригиналног текста из уноса у дневник:

CREATE TABLE rawdata_orig(
  pack -- PK
    uuid NOT NULL
, recno -- PK
    smallint NOT NULL
, dt -- ключ секции
    date
, data -- самое главное
    text
, PRIMARY KEY(pack, recno)
);

Типичан знак (већ подељен, наравно, па је ово шаблон одељка), где је најважнији текст. Понекад прилично обиман.

Подсетимо се да „физичка“ величина једног записа у ПГ не може да заузима више од једне странице података, али „логичка“ величина је сасвим друга ствар. Да бисте записали волуметријску вредност (варцхар/тект/битеа) у поље, користите ТОАСТ технологија:

ПостгреСКЛ користи фиксну величину странице (обично 8 КБ) и не дозвољава да се торке простиру на више страница. Због тога је немогуће директно ускладиштити веома велике вредности поља. Да би се превазишло ово ограничење, велике вредности поља се компримују и/или деле на више физичких линија. Ово се дешава непримећено од стране корисника и има мали утицај на већину серверског кода. Овај метод је познат као ТОАСТ...

У ствари, за сваку табелу са "потенцијално великим" пољима, аутоматски креира се упарена табела са „резањем“. сваки „велики“ запис у сегментима од 2 КБ:

TOAST(
  chunk_id
    integer
, chunk_seq
    integer
, chunk_data
    bytea
, PRIMARY KEY(chunk_id, chunk_seq)
);

То јест, ако морамо да напишемо стринг са „великом“ вредношћу data, тада ће доћи до правог снимања не само на главни сто и његов ПК, већ и на ТОАСТ и његов ПК.

Смањење утицаја ТОАСТ-а

Али већина наших рекорда још увек није тако велика, требало би да стане у 8КБ - Како да уштедим на овоме?..

Ту нам атрибут долази у помоћ STORAGE у колони табеле:

  • ЕКСТЕНДЕД омогућава и компресију и одвојено складиштење. Ово стандардна опција за већину типова података усаглашених са ТОАСТ-ом. Прво покушава да изврши компресију, а затим га складишти ван табеле ако је ред и даље превелик.
  • ГЛАВНИ омогућава компресију, али не и одвојено складиштење. (У ствари, одвојено складиштење ће се и даље обављати за такве колоне, али само као последње средство, када не постоји други начин да се стринг смањи тако да стане на страницу.)

У ствари, то је управо оно што нам треба за текст - стисните га што је више могуће, а ако уопште не стане, ставите га у ТОАСТ. Ово се може урадити директно у ходу, једном командом:

ALTER TABLE rawdata_orig ALTER COLUMN data SET STORAGE MAIN;

Како проценити ефекат

Пошто се ток података мења сваког дана, не можемо поредити апсолутне бројеве, већ релативне мањи удео Записали смо то у ТОАСТ - тим боље. Али овде постоји опасност – што је већи „физички” обим сваког појединачног записа, индекс постаје „шири”, јер морамо да покријемо више страница података.

Одељак пре промена:

heap  = 37GB (39%)
TOAST = 54GB (57%)
PK    =  4GB ( 4%)

Одељак после промена:

heap  = 37GB (67%)
TOAST = 16GB (29%)
PK    =  2GB ( 4%)

У ствари, ми почео да пише у ТОАСТ 2 пута ређе, који је испразнио не само диск, већ и ЦПУ:

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

Ко може добро да живи на ПостгреСКЛ 11

Након ажурирања на ПГ11, одлучили смо да наставимо са „подешавањем“ ТОАСТ-а и приметили смо да је од ове верзије параметар постао доступан за подешавање toast_tuple_target:

Код за обраду ТОАСТ се покреће само када је вредност реда која се чува у табели већа од ТОАСТ_ТУПЛЕ_ТХРЕСХОЛД бајтова (обично 2 КБ). ТОАСТ код ће компримовати и/или преместити вредности поља из табеле све док вредност реда не постане мања од ТОАСТ_ТУПЛЕ_ТАРГЕТ бајтова (променљива вредност, такође обично 2 КБ) или се величина не може смањити.

Одлучили смо да су подаци које обично имамо или „веома кратки“ или „веома дуги“, па смо одлучили да се ограничимо на минималну могућу вредност:

ALTER TABLE rawplan_orig SET (toast_tuple_target = 128);

Да видимо како су нова подешавања утицала на учитавање диска након реконфигурације:

Уштедите пени на великим количинама у ПостгреСКЛ-у
Није лоше! Просек ред до диска се смањио отприлике 1.5 пута, а диск је „заузет“ 20 процената! Али можда је то некако утицало на ЦПУ?

Уштедите пени на великим количинама у ПостгреСКЛ-у
Барем није било горе. Иако је тешко проценити да ли чак и такве количине још увек не могу да повећају просечно оптерећење ЦПУ-а 5%.

Променом места појмова мења се збир...!

Као што знате, један пени штеди рубљу, а са нашим количинама складиштења ради се о томе 10ТБ/месец чак и мала оптимизација може дати добар профит. Стога смо обратили пажњу на физичку структуру наших података – како тачно „наслагана“ поља унутар записа свака од табела.

Јер због усклађивање података ово је право напред утиче на резултујућу запремину:

Многе архитектуре обезбеђују поравнање података на границама машинских речи. На пример, на 32-битном к86 систему, цели бројеви (тип целог броја, 4 бајта) ће бити поравнати на граници речи од 4 бајта, као и бројеви са помичним зарезом двоструке прецизности (покретни зарез двоструке прецизности, 8 бајтова). А на 64-битном систему, двоструке вредности ће бити усклађене са границама речи од 8 бајта. Ово је још један разлог за некомпатибилност.

Због поравнања, величина реда табеле зависи од редоследа поља. Обично овај ефекат није веома приметан, али у неким случајевима може довести до значајног повећања величине. На пример, ако помешате цхар(1) и целобројна поља, обично ће између њих бити изгубљена 3 бајта.

Почнимо са синтетичким моделима:

SELECT pg_column_size(ROW(
  '0000-0000-0000-0000-0000-0000-0000-0000'::uuid
, 0::smallint
, '2019-01-01'::date
));
-- 48 байт

SELECT pg_column_size(ROW(
  '2019-01-01'::date
, '0000-0000-0000-0000-0000-0000-0000-0000'::uuid
, 0::smallint
));
-- 46 байт

Откуд пар додатних бајтова у првом случају? То је једноставно - 2-бајтни смаллинт поравнат на 4-бајтној граници пре следећег поља, а када је последње, нема ничега и нема потребе за поравнавањем.

У теорији, све је у реду и можете преуредити поља како желите. Хајде да то проверимо на стварним подацима на примеру једне од табела, чији дневни део заузима 10-15 ГБ.

Почетна структура:

CREATE TABLE public.plan_20190220
(
-- Унаследована from table plan:  pack uuid NOT NULL,
-- Унаследована from table plan:  recno smallint NOT NULL,
-- Унаследована from table plan:  host uuid,
-- Унаследована from table plan:  ts timestamp with time zone,
-- Унаследована from table plan:  exectime numeric(32,3),
-- Унаследована from table plan:  duration numeric(32,3),
-- Унаследована from table plan:  bufint bigint,
-- Унаследована from table plan:  bufmem bigint,
-- Унаследована from table plan:  bufdsk bigint,
-- Унаследована from table plan:  apn uuid,
-- Унаследована from table plan:  ptr uuid,
-- Унаследована from table plan:  dt date,
  CONSTRAINT plan_20190220_pkey PRIMARY KEY (pack, recno),
  CONSTRAINT chck_ptr CHECK (ptr IS NOT NULL),
  CONSTRAINT plan_20190220_dt_check CHECK (dt = '2019-02-20'::date)
)
INHERITS (public.plan)

Одељак после промене редоследа колона - тачно иста поља, само другачији редослед:

CREATE TABLE public.plan_20190221
(
-- Унаследована from table plan:  dt date NOT NULL,
-- Унаследована from table plan:  ts timestamp with time zone,
-- Унаследована from table plan:  pack uuid NOT NULL,
-- Унаследована from table plan:  recno smallint NOT NULL,
-- Унаследована from table plan:  host uuid,
-- Унаследована from table plan:  apn uuid,
-- Унаследована from table plan:  ptr uuid,
-- Унаследована from table plan:  bufint bigint,
-- Унаследована from table plan:  bufmem bigint,
-- Унаследована from table plan:  bufdsk bigint,
-- Унаследована from table plan:  exectime numeric(32,3),
-- Унаследована from table plan:  duration numeric(32,3),
  CONSTRAINT plan_20190221_pkey PRIMARY KEY (pack, recno),
  CONSTRAINT chck_ptr CHECK (ptr IS NOT NULL),
  CONSTRAINT plan_20190221_dt_check CHECK (dt = '2019-02-21'::date)
)
INHERITS (public.plan)

Укупна запремина секције је одређена бројем „чињеница“ и зависи само од спољних процеса, па поделимо величину гомиле (pg_relation_size) по броју записа у њему – односно добијамо просечна величина стварно сачуваног записа:

Уштедите пени на великим количинама у ПостгреСКЛ-у
Минус 6% запремине, Велики!

Али све, наравно, није тако ружичасто - уосталом, у индексима не можемо променити редослед поља, а самим тим и „уопштено“ (pg_total_relation_size) ...

Уштедите пени на великим количинама у ПостгреСКЛ-у
...још увек овде уштеђено 1.5%без промене једног реда кода. Да да!

Уштедите пени на великим количинама у ПостгреСКЛ-у

Напомињем да горња опција за уређење поља није чињеница да је најоптималнија. Зато што не желите да "поцепате" неке блокове поља из естетских разлога - на пример, пар (pack, recno), што је ПК за ову табелу.

Генерално, одређивање „минималног“ распореда поља је прилично једноставан задатак „грубе силе“. Стога, можете добити још боље резултате од ваших података од наших - испробајте!

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

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