په PostgreSQL کې په لوی حجمونو کې یوه پیسي خوندي کړئ

د لویو ډیټا جریانونو ثبتولو موضوع ته دوام ورکول چې لخوا راپورته شوي د ویشلو په اړه پخوانۍ مقاله، پدې کې به موږ هغه لارې وګورو چې تاسو یې کولی شئ د ذخیره شوي "فزیکي" اندازه کم کړئ په PostgreSQL کې، او د سرور فعالیت باندې د دوی اغیز.

موږ به په اړه خبرې وکړو د TOAST ترتیبات او د معلوماتو سمون. "په اوسط ډول،" دا طریقې به ډیرې سرچینې ونه سپموي، مګر د غوښتنلیک کوډ بدلولو پرته.

په PostgreSQL کې په لوی حجمونو کې یوه پیسي خوندي کړئ
په هرصورت، زموږ تجربه په دې برخه کې خورا ګټوره ثابته شوه، ځکه چې نږدې د هر ډول څارنې ذخیره د خپل طبیعت له مخې ده. زیاتره یوازې ضمیمه د ثبت شوي معلوماتو له مخې. او که تاسو حیران یاست چې تاسو څنګه کولی شئ ډیټابیس ته د دې پرځای ډیسک ته د لیکلو ښوونه وکړئ 200MB / s نیمه برخه - مهرباني وکړئ د پیشو لاندې.

د لویو معلوماتو کوچني رازونه

د دندې پروفایل لخوا زموږ خدمت، دوی په منظمه توګه هغه ته له لیري څخه الوتنه کوي د متن کڅوړې.

او وروسته د VLSI کمپلیکسد هغه ډیټابیس چې موږ یې څارو یو څو اجزاو محصول دی چې پیچلي ډیټا جوړښتونه لري، بیا پوښتنې د اعظمي فعالیت لپاره په بشپړ ډول د دې په څیر وګرځید د پیچلي الګوریتمیک منطق سره "کثیر حجم". نو د غوښتنې د هرې انفرادي مثال حجم یا په لاګ کې د پلي کولو پلان پایله چې موږ ته راځي "په اوسط ډول" خورا لوی وي.

راځئ چې د یو جدول جوړښت ته وګورو په کوم کې چې موږ "خام" ډاټا لیکو - دا دی، دلته د ننوتلو اصلي متن دی:

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

یو عادي نښه (مخکې له مخکې برخه شوې، البته، نو دا د برخې ټیمپلیټ دی)، چیرته چې خورا مهم شی متن دی. ځینې ​​​​وختونه خورا لوی.

په یاد ولرئ چې په PG کې د یو ریکارډ "فزیکي" اندازه نشي کولی د معلوماتو له یوې پاڼې څخه ډیر ونیسي، مګر د "منطقي" اندازه په بشپړه توګه توپیر لري. په ساحه کې د حجمیتریک ارزښت (varchar/text/bytea) لیکلو لپاره، وکاروئ TOAST ټیکنالوژي:

PostgreSQL د یوې ثابتې پاڼې اندازه (معمولا 8 KB) کاروي، او ټپلونو ته اجازه نه ورکوي چې څو پاڼې پراخې کړي. له همدې امله، دا ناشونې ده چې په مستقیم ډول د خورا لوی ساحې ارزښتونه ذخیره کړئ. د دې محدودیت د لرې کولو لپاره، د ساحې لوی ارزښتونه فشار شوي او/یا په څو فزیکي لینونو ویشل شوي. دا د کارونکي لخوا نه لیدل کیږي او په ډیری سرور کوډ باندې لږ اغیزه لري. دا طریقه د TOAST په نوم پیژندل کیږي ...

په حقیقت کې، د هر میز لپاره د "احتمالي لوی" ساحو سره، په اتوماتيک ډول یو جوړه شوی میز د "سلیسینګ" سره جوړ شوی هر "لوی" ریکارډ په 2KB برخو کې:

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

دا دی، که موږ د "لوی" ارزښت سره تار ولیکو data، بیا به ریښتیني ثبت شي نه یوازې اصلي میز او د هغې PK ته ، بلکه TOAST او د هغې PK ته هم.

د TOAST نفوذ کمول

مګر زموږ ډیری ریکارډونه لاهم لوی ندي، باید په 8KB کې فټ شي - زه څنګه کولی شم پدې کې پیسې خوندي کړم؟ ...

دا هغه ځای دی چې ځانګړتیا زموږ مرستې ته راځي STORAGE د میز په ستون کې:

  • غځول شوی دواړه کمپریشن او جلا ذخیره کولو ته اجازه ورکوي. دا معیاري اختیار د ډیری TOAST مطابقت لرونکي ډیټا ډولونو لپاره. دا لومړی د کمپریشن ترسره کولو هڅه کوي، بیا یې د میز څخه بهر ذخیره کوي که چیرې قطار لاهم لوی وي.
  • مهمه کمپریشن ته اجازه ورکوي مګر جلا ذخیره نه کوي. (په حقیقت کې، جلا ذخیره به لاهم د ورته کالمونو لپاره ترسره شي، مګر یوازې د وروستي حل په توګه، کله چې د تار د کمولو لپاره بله لاره شتون نلري ترڅو دا په پاڼه کې فټ شي.)

په حقیقت کې، دا هغه څه دي چې موږ د متن لپاره اړتیا لرو - دا د امکان تر حده فشار کړئ، او که دا په بشپړ ډول مناسب نه وي، په TOAST کې یې واچوئ. دا په مستقیم ډول په الوتنه کې ترسره کیدی شي، د یو حکم سره:

ALTER TABLE rawdata_orig ALTER COLUMN data SET STORAGE MAIN;

د اغیز ارزونه څنګه

څرنګه چې د معلوماتو جریان هره ورځ بدلیږي، موږ نشو کولی مطلق شمیر پرتله کړو، مګر په نسبي شرایطو کې کوچنۍ برخه موږ دا په TOAST کې لیکلي - دومره ښه. مګر دلته یو خطر شتون لري - هرڅومره چې د هر انفرادي ریکارډ "فزیکي" حجم لوی وي ، نو شاخص "پراخه" کیږي ، ځکه چې موږ باید د معلوماتو ډیرې پاڼې پوښي.

برخه د بدلونونو دمخه:

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

برخه د بدلونونو وروسته:

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

په حقیقت کې، موږ TOAST ته 2 ځله لږ لیکل پیل کړل، کوم چې نه یوازې ډیسک خلاص کړی ، بلکه CPU هم:

په PostgreSQL کې په لوی حجمونو کې یوه پیسي خوندي کړئ
په PostgreSQL کې په لوی حجمونو کې یوه پیسي خوندي کړئ
زه به په یاد ولرئ چې موږ د ډیسک په "لوستلو" کې هم کوچني شوي یو، نه یوازې "لیکلو" - ځکه چې کله چې په میز کې ریکارډ داخل کړو، موږ باید د هر شاخص د ونې برخه "لوستل" هم وکړو ترڅو د هغې د ټاکلو لپاره. په دوی کې راتلونکی موقف.

څوک کولی شي په PostgreSQL 11 کې ښه ژوند وکړي

PG11 ته د تازه کولو وروسته، موږ پریکړه وکړه چې د TOAST "ټیوننګ" ته دوام ورکړو او ولیدل چې د دې نسخې څخه پیل کولو سره پیرامیټر د ټونینګ لپاره شتون لري toast_tuple_target:

د TOAST پروسس کولو کوډ یوازې هغه وخت اوریږي کله چې په جدول کې د زیرمه کولو قطار ارزښت د TOAST_TUPLE_THRESHOLD بایټ څخه لوی وي (معمولا 2 KB). د TOAST کوډ به د ساحې ارزښتونه له جدول څخه وباسي او/یا حرکت وکړي تر هغه چې د قطار ارزښت د TOAST_TUPLE_TARGET بایټ څخه کم نشي (متغیر ارزښت، معمولا 2 KB) یا اندازه نشي کمیدلی.

موږ پریکړه وکړه چې هغه معلومات چې موږ یې معمولا لرو یا "خورا لنډ" یا "ډیر اوږد" دي، نو موږ پریکړه وکړه چې خپل ځان لږترلږه ممکنه ارزښت ته محدود کړو:

ALTER TABLE rawplan_orig SET (toast_tuple_target = 128);

راځئ وګورو چې څنګه نوي تنظیمات د بیا تنظیم کولو وروسته د ډیسک بار کولو اغیزه کوي:

په PostgreSQL کې په لوی حجمونو کې یوه پیسي خوندي کړئ
بد نه دی! اوسط ډیسک ته کتار کم شوی نږدې 1.5 ځله، او ډیسک "مصروف" 20 سلنه دی! مګر شاید دا یو څه په CPU اغیزه وکړي؟

په PostgreSQL کې په لوی حجمونو کې یوه پیسي خوندي کړئ
لږترلږه دا نور خراب نه شو. که څه هم، قضاوت کول ستونزمن دي که حتی دا ډول حجمونه لاهم نشي کولی د اوسط CPU بار لوړ کړي 5%.

د شرایطو د ځایونو په بدلولو سره، مجموعه ... بدلیږي!

لکه څنګه چې تاسو پوهیږئ، یوه پیسي یو روبل خوندي کوي، او زموږ د ذخیره کولو حجمونو سره دا په اړه ده 10TB / میاشت حتی لږ اصلاح کولی شي ښه ګټه ورکړي. له همدې امله، موږ د خپلو معلوماتو فزیکي جوړښت ته پاملرنه وکړه - په سمه توګه په ریکارډ کې دننه "ډک شوي" ساحې هر یو جدول.

ځکه چې د معلوماتو سمون دا مستقیم مخ په وړاندې دی د پایلې حجم اغیزه کوي:

ډیری معمارۍ د ماشین کلمې په حدودو کې د معلوماتو ترتیب چمتو کوي. د مثال په توګه، په 32-bit x86 سیسټم کې، انټیجرونه (د انټیجر ډول، 4 بایټ) به د 4-بایټ کلمې حد سره سمون ولري، لکه څنګه چې به دوه ځله دقیق فلوټینګ پوائنټ شمیرې (دوه ځله دقیق فلوټینګ پوائنټ، 8 بایټ). او په 64-bit سیسټم کې، ډبل ارزښتونه به د 8-بایټ کلمې حدود سره سمون ولري. دا د نه مطابقت بل لامل دی.

د سمون له امله، د میز قطار اندازه د ساحو په ترتیب پورې اړه لري. معمولا دا اغیزه د پام وړ نه ده، مګر په ځینو مواردو کې دا کولی شي د اندازې د پام وړ زیاتوالی لامل شي. د مثال په توګه، که تاسو د char(1) او integer ساحې سره ګډ کړئ، نو د دوی ترمنځ به عموما 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-15GB نیسي.

ابتدايي جوړښت:

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) په دې کې د ریکارډونو شمیر سره - دا دی، موږ ترلاسه کوو د اصلي ذخیره شوي ریکارډ اوسط اندازه:

په PostgreSQL کې په لوی حجمونو کې یوه پیسي خوندي کړئ
منفي 6٪ حجم، غوره!

مګر هرڅه ، البته ، دومره ګلابي ندي - په هرصورت ، په شاخصونو کې موږ نشو کولی د ساحو ترتیب بدل کړو، او له همدې امله "په عمومي توګه" (pg_total_relation_size) ...

په PostgreSQL کې په لوی حجمونو کې یوه پیسي خوندي کړئ
...تر اوسه هم دلته 1.5٪ خوندي شوید کوډ یوه کرښه بدلولو پرته. او او!

په PostgreSQL کې په لوی حجمونو کې یوه پیسي خوندي کړئ

زه یادونه کوم چې د ساحو تنظیم کولو لپاره پورتني اختیار دا حقیقت ندی چې دا ترټولو غوره دی. ځکه چې تاسو نه غواړئ د جمالیاتی دلایلو لپاره د ساحو ځینې بلاکونه "اوښل" کړئ - د مثال په توګه ، یو جوړه (pack, recno)، کوم چې د دې میز لپاره PK دی.

په عموم کې، د ساحو "لږترلږه" ترتیب ټاکل خورا ساده "وحشي ځواک" دنده ده. له همدې امله، تاسو کولی شئ زموږ په پرتله ستاسو د معلوماتو څخه حتی غوره پایلې ترلاسه کړئ - هڅه وکړئ!

سرچینه: www.habr.com

Add a comment