Տեղադրեք Out-Of-Memory Killer Linux-ում PostgreSQL-ի համար

Տեղադրեք Out-Of-Memory Killer Linux-ում PostgreSQL-ի համար

Երբ տվյալների բազայի սերվերը անսպասելիորեն անջատվում է Linux-ում, դուք պետք է գտնեք պատճառը: Կարող է լինել մի քանի պատճառ. Օրինակ, ՍԻԳՍԵԳՎ — ձախողում հետին սերվերի սխալի պատճառով: Բայց սա հազվադեպ է: Ամենից հաճախ, դուք պարզապես սպառում եք սկավառակի տարածքը կամ հիշողությունը: Եթե ​​սկավառակի տարածքը սպառվում է, ապա միայն մեկ ելք կա՝ ազատեք տարածք և վերագործարկեք տվյալների բազան:

Հիշողությունից դուրս մարդասպան

Երբ սերվերի կամ գործընթացի հիշողությունը սպառվում է, Linux-ն առաջարկում է 2 լուծում՝ խափանել ամբողջ համակարգը կամ դադարեցնել գործընթացը (հավելվածը), որը խլում է հիշողությունը: Ավելի լավ է, իհարկե, դադարեցնել գործընթացը և փրկել ՕՀ-ն խափանումից։ Մի խոսքով, Out-Of-Memory Killer-ը գործընթաց է, որը սպանում է հավելվածը՝ միջուկը խափանումից փրկելու համար: Այն զոհաբերում է հավելվածը՝ ՕՀ-ն աշխատեցնելու համար: Եկեք նախ քննարկենք, թե ինչպես է աշխատում OOM-ը և ինչպես վերահսկել այն, իսկ հետո տեսնենք, թե ինչպես է OOM Killer-ը որոշում, թե որ հավելվածը դադարեցնի:

Linux-ի հիմնական խնդիրներից է հիշողություն հատկացնել գործընթացներին, երբ նրանք դա պահանջում են: Սովորաբար, գործընթացը կամ հավելվածը պահանջում է հիշողություն ՕՀ-ից, բայց այն ամբողջությամբ չի օգտագործում: Եթե ​​ՕՀ-ն հիշողություն է տալիս բոլորին, ովքեր դա խնդրում են, բայց չեն պատրաստվում օգտագործել այն, շատ շուտով հիշողությունը կսպառվի, և համակարգը կխափանվի: Դրանից խուսափելու համար ՕՀ-ն հիշողություն է պահում գործընթացի համար, բայց իրականում այն ​​չի թողարկում: Հիշողությունը հատկացվում է միայն այն դեպքում, երբ գործընթացն իրականում պատրաստվում է օգտագործել այն: Պատահում է, որ ՕՀ-ն ազատ հիշողություն չունի, բայց հիշողություն է հատկացնում պրոցեսին, և երբ պրոցեսին դա անհրաժեշտ է, ՕՀ-ն այն հատկացնում է, եթե կարող է: Բացասական կողմն այն է, որ երբեմն ՕՀ-ն պահում է հիշողությունը, բայց ճիշտ ժամանակին ազատ հիշողություն չկա, և համակարգը խափանում է: OOM-ը կարևոր դեր է խաղում այս սցենարում և դադարեցնում է գործընթացները՝ միջուկի խուճապը կանխելու համար: Երբ PostgreSQL գործընթացը ստիպված է լինում դադարեցնել, գրանցամատյանում հայտնվում է հաղորդագրություն.

Out of Memory: Killed process 12345 (postgres).

Եթե ​​համակարգի հիշողությունը քիչ է, և այն հնարավոր չէ ազատել, ֆունկցիան կանչվում է out_of_memory. Այս փուլում նրան մնում է միայն մեկ բան՝ ավարտել մեկ կամ մի քանի գործընթաց: Պե՞տք է արդյոք OOM-killer-ը անմիջապես դադարեցնի գործընթացը, թե՞ կարող է սպասել: Ակնհայտ է, որ երբ կանչվում է out_of_memory, դա պայմանավորված է I/O գործողության կամ սկավառակի վրա էջավորում սպասելու պատճառով: Հետևաբար, OOM մարդասպանը նախ պետք է ստուգումներ կատարի և դրանց հիման վրա որոշի, որ գործընթացը պետք է դադարեցվի: Եթե ​​ստորև բերված բոլոր ստուգումները դրական են, OOM-ը կդադարեցնի գործընթացը:

Գործընթացի ընտրություն

Երբ հիշողությունը սպառվում է, ֆունկցիան կանչվում է out_of_memory(). Այն ունի գործառույթ select_bad_process(), որը գնահատական ​​է ստանում ֆունկցիայից badness(). «Ամենավատ» գործընթացը թիրախային է լինելու. Գործառույթ badness() ընտրում է գործընթացը որոշակի կանոնների համաձայն.

  1. Միջուկն իր համար նվազագույն հիշողության կարիք ունի:
  2. Դուք պետք է ազատեք շատ հիշողություն:
  3. Կարիք չկա դադարեցնել այն գործընթացները, որոնք քիչ հիշողություն են օգտագործում:
  4. Պետք է ավարտվեն նվազագույն գործընթացները.
  5. Բարդ ալգորիթմներ, որոնք մեծացնում են այն գործընթացների ավարտի հնարավորությունները, որոնք օգտատերն ինքը ցանկանում է ավարտել:

Ավարտելով այս բոլոր ստուգումները՝ OOM-ն ուսումնասիրում է միավորը (oom_score) OOM-ը նշանակում է oom_score յուրաքանչյուր գործընթաց, այնուհետև այս արժեքը բազմապատկում է հիշողության քանակով: Ավելի մեծ արժեքներ ունեցող գործընթացներն ավելի հավանական է դառնում OOM Killer-ի զոհը: Արմատային օգտատիրոջ հետ կապված գործընթացներն ավելի ցածր գնահատական ​​ունեն և ավելի քիչ հավանական է, որ ստիպված կլինեն դադարեցնել:

postgres=# SELECT pg_backend_pid();
pg_backend_pid 
----------------
    3813
(1 row)

Postgres գործընթացի ID-ն 3813 է, ուստի մեկ այլ վահանակում հնարավոր է միավոր ստանալ՝ օգտագործելով միջուկի այս պարամետրը: oom_score:

vagrant@vagrant:~$ sudo cat /proc/3813/oom_score
2

Եթե ​​դուք չեք ցանկանում, որ OOM-Killer-ն ընդհանրապես սպանի գործընթացը, կա մեկ այլ միջուկի տարբերակ. oom_score_adj. Ավելացրեք մեծ բացասական արժեք՝ ձեր գնահատած գործընթացն ավարտելու հնարավորությունները նվազեցնելու համար:

sudo echo -100 > /proc/3813/oom_score_adj

Արժեք սահմանելու համար oom_score_adj, սահմանել OOMScore Adjust ծառայության բլոկում.

[Service]
OOMScoreAdjust=-1000

Կամ օգտագործել oomprotect թիմում rcctl.

rcctl set <i>servicename</i> oomprotect -1000

Գործընթացի հարկադիր դադարեցում

Երբ մեկ կամ մի քանի գործընթացներ արդեն ընտրված են, OOM-Killer-ը կանչում է ֆունկցիան oom_kill_task(). Այս ֆունկցիան ավարտման ազդանշան է ուղարկում գործընթացին: Հիշողության պակասի դեպքում oom_kill() Կանչում է այս ֆունկցիան՝ գործընթացին SIGKILL ազդանշան ուղարկելու համար: Հաղորդագրություն է գրվում միջուկի մատյանում:

Out of Memory: Killed process [pid] [name].

Ինչպես վերահսկել OOM-Killer-ը

Linux-ում կարող եք միացնել կամ անջատել OOM-Killer-ը (չնայած վերջինս խորհուրդ չի տրվում): Միացնելու կամ անջատելու համար օգտագործեք պարամետրը vm.oom-kill. OOM-Killer-ը գործարկման ժամանակ միացնելու համար գործարկեք հրամանը sysctl.

sudo -s sysctl -w vm.oom-kill = 1

OOM-Killer-ն անջատելու համար նույն հրամանում նշեք 0 արժեքը.

sudo -s sysctl -w vm.oom-kill = 0

Այս հրամանի արդյունքը հավերժ չի պահպանվի, այլ միայն մինչև առաջին վերաբեռնումը: Եթե ​​Ձեզ անհրաժեշտ է ավելի շատ հաստատակամություն, ավելացրեք այս տողը ֆայլին /etc/sysctl.conf:

echo vm.oom-kill = 1 >>/etc/sysctl.conf

Միացնելու և անջատելու մեկ այլ եղանակ փոփոխական գրելն է panic_on_oom. Արժեքը միշտ կարելի է ստուգել /proc.

$ cat /proc/sys/vm/panic_on_oom
0

Եթե ​​արժեքը սահմանեք 0, ապա երբ հիշողությունը սպառվի, միջուկի խուճապ չի լինի:

$ echo 0 > /proc/sys/vm/panic_on_oom

Եթե ​​արժեքը սահմանեք 1, ապա երբ հիշողությունը վերջանա, միջուկի խուճապ կառաջանա:

echo 1 > /proc/sys/vm/panic_on_oom

OOM-Killer-ը ոչ միայն կարելի է միացնել և անջատել: Մենք արդեն ասել ենք, որ Linux-ը կարող է ավելի շատ հիշողություն վերապահել գործընթացների համար, քան հասանելի է առանց այն իրականում հատկացնելու, և այս վարքագիծը վերահսկվում է Linux միջուկի պարամետրով: Դրա համար պատասխանատու է փոփոխականը vm.overcommit_memory.

Դրա համար կարող եք նշել հետևյալ արժեքները.

0: Միջուկն ինքն է որոշում՝ արդյոք չափից շատ հիշողություն պահել: Սա լռելյայն է Linux-ի տարբերակների մեծ մասում:
1: Միջուկը միշտ կպահի լրացուցիչ հիշողություն: Սա ռիսկային է, քանի որ հիշողությունը կարող է սպառվել, քանի որ, ամենայն հավանականությամբ, մի օր գործընթացները դա կպահանջեն։
2: միջուկը չի պահի ավելի շատ հիշողություն, քան նշված է պարամետրում overcommit_ratio.

Այս պարամետրով դուք նշում եք հիշողության այն տոկոսը, որը թույլատրվում է չափից ավելի վերապահովել: Եթե ​​դրա համար տեղ չկա, հիշողություն չի հատկացվում, և ամրագրումը կմերժվի։ Սա PostgreSQL-ի համար առաջարկվող ամենաանվտանգ տարբերակն է: OOM-Killer-ի վրա ազդում է մեկ այլ տարր՝ փոխանակման հնարավորությունը, որը վերահսկվում է փոփոխականով: cat /proc/sys/vm/swappiness. Այս արժեքները միջուկին ասում են, թե ինչպես վարվել էջերում: Որքան մեծ է արժեքը, այնքան քիչ հավանական է, որ OOM-ը կդադարեցնի գործընթացը, բայց I/O գործառնությունների պատճառով դա բացասական ազդեցություն ունի տվյալների բազայի վրա: Եվ հակառակը, որքան ցածր է արժեքը, այնքան մեծ է OOM-Killer միջամտության հավանականությունը, բայց տվյալների բազայի կատարումը նույնպես ավելի բարձր է: Լռելյայն արժեքը 60 է, բայց եթե ամբողջ տվյալների բազան տեղավորվում է հիշողության մեջ, ավելի լավ է արժեքը սահմանել 1:

Արդյունքները

Թույլ մի տվեք, որ «մարդասպանը» OOM-Killer-ում ձեզ վախեցնի: Այս դեպքում մարդասպանը կլինի ձեր համակարգի փրկիչը։ Այն «սպանում է» ամենավատ գործընթացները և փրկում համակարգը խափանումից: PostgreSQL-ն դադարեցնելու համար OOM-Killer-ն օգտագործելուց խուսափելու համար սահմանեք vm.overcommit_memory արժեքը 2. Սա չի երաշխավորում, որ OOM-Killer-ը ստիպված չի լինի միջամտել, բայց դա կնվազեցնի PostgreSQL գործընթացի դադարեցման ստիպելու հավանականությունը:

Source: www.habr.com

Добавить комментарий