Fluentd: KÄpÄc ir svarÄ«gi konfigurÄt izvades buferi
MÅ«sdienÄs nav iespÄjams iedomÄties uz Kubernetes balstÄ«tu projektu bez ELK steka, kas saglabÄ gan lietojumprogrammu, gan klastera sistÄmas komponentu žurnÄlus. MÅ«su praksÄ mÄs izmantojam EFK steku ar Fluentd, nevis Logstash.
Fluentd ir moderns, universÄls baļķu savÄcÄjs, kas gÅ«st arvien lielÄku popularitÄti un ir pievienojies Cloud Native Computing Foundation, tÄpÄc tÄ izstrÄdes vektors ir vÄrsts uz lietoÅ”anu kopÄ ar Kubernetes.
Fluentd izmantoÅ”ana Logstash vietÄ nemaina programmatÅ«ras pakotnes vispÄrÄjo bÅ«tÄ«bu, tomÄr Fluentd raksturo savas specifiskÄs nianses, kas izriet no tÄ daudzpusÄ«bas.
PiemÄram, kad sÄkÄm lietot EFK kÄdÄ noslogotÄ projektÄ ar augstu mežizstrÄdes intensitÄti, saskÄrÄmies ar faktu, ka KibanÄ daži ziÅojumi tika parÄdÄ«ti atkÄrtoti vairÄkas reizes. Å ajÄ rakstÄ mÄs jums pateiksim, kÄpÄc Ŕī parÄdÄ«ba notiek un kÄ atrisinÄt problÄmu.
Dokumentu dublÄÅ”anas problÄma
MÅ«su projektos Fluentd tiek izvietots kÄ DaemonSet (automÄtiski palaists vienÄ instancÄ katrÄ Kubernetes klastera mezglÄ) un uzrauga standarta konteineru žurnÄlus mapÄ /var/log/containers. PÄc savÄkÅ”anas un apstrÄdes žurnÄli JSON dokumentu veidÄ tiek nosÅ«tÄ«ti uz ElasticSearch, izveidoti klastera vai atseviŔķa formÄ atkarÄ«bÄ no projekta mÄroga un prasÄ«bÄm attiecÄ«bÄ uz veiktspÄju un kļūdu toleranci. Kibana tiek izmantota kÄ grafiskais interfeiss.
Izmantojot Fluentd ar izvades buferizÄcijas spraudni, mÄs saskÄrÄmies ar situÄciju, ka dažiem ElasticSearch dokumentiem bija tieÅ”i tÄds pats saturs un tie atŔķīrÄs tikai ar identifikatoru. Varat pÄrbaudÄ«t, vai tas ir ziÅojuma atkÄrtojums, izmantojot Nginx žurnÄlu kÄ piemÄru. ŽurnÄla failÄ Å”is ziÅojums pastÄv vienÄ eksemplÄrÄ:
TurklÄt var bÅ«t vairÄk nekÄ divi atkÄrtojumi.
NovÄrÅ”ot Å”o problÄmu Fluentd žurnÄlos, varat redzÄt lielu skaitu brÄ«dinÄjumu ar Å”Ädu saturu:
2020-01-16 01:46:46 +0000 [warn]: [test-prod] failed to flush the buffer. retry_time=4 next_retry_seconds=2020-01-16 01:46:53 +0000 chunk="59c37fc3fb320608692c352802b973ce" error_class=Fluent::Plugin::ElasticsearchOutput::RecoverableRequestFailure error="could not push logs to Elasticsearch cluster ({:host=>"elasticsearch", :port=>9200, :scheme=>"http", :user=>"elastic", :password=>"obfuscated"}): read timeout reached"
Å ie brÄ«dinÄjumi rodas, ja ElasticSearch nevar atgriezt atbildi uz pieprasÄ«jumu parametrÄ request_timeout norÄdÄ«tajÄ laikÄ, tÄpÄc pÄrsÅ«tÄ«to bufera fragmentu nevar notÄ«rÄ«t. PÄc tam Fluentd mÄÄ£ina vÄlreiz nosÅ«tÄ«t bufera fragmentu ElasticSearch un pÄc patvaļīga skaita mÄÄ£inÄjumu darbÄ«ba tiek veiksmÄ«gi pabeigta:
TomÄr ElasticSearch katru pÄrsÅ«tÄ«to bufera fragmentu uzskata par unikÄlu un indeksÄÅ”anas laikÄ pieŔķir tiem unikÄlas _id lauka vÄrtÄ«bas. Å Ädi parÄdÄs ziÅojumu kopijas.
KibanÄ tas izskatÄs Å”Ädi:
RisinÄjums
Å Ä«s problÄmas risinÄÅ”anai ir vairÄkas iespÄjas. Viens no tiem ir mehÄnisms, kas iebÅ«vÄts spraudnÄ« fluent-plugin-elasticsearch, lai katram dokumentam Ä£enerÄtu unikÄlu jaucÄju. Ja izmantojat Å”o mehÄnismu, ElasticSearch atpazÄ«s atkÄrtojumus pÄrsÅ«tÄ«Å”anas posmÄ un novÄrsÄ«s dokumentu dublikÄtus. Bet jÄÅem vÄrÄ, ka Ŕī problÄmas risinÄÅ”anas metode cÄ«nÄs ar izmeklÄÅ”anu un nenovÄrÅ” kļūdu ar taimauta trÅ«kumu, tÄpÄc mÄs atteicÄmies no tÄs izmantoÅ”anas.
MÄs izmantojam buferizÄcijas spraudni Fluentd izvadei, lai novÄrstu žurnÄla zudumus Ä«slaicÄ«gu tÄ«kla problÄmu vai palielinÄtas reÄ£istrÄÅ”anas intensitÄtes gadÄ«jumÄ. Ja kÄda iemesla dÄļ ElasticSearch nevar uzreiz ierakstÄ«t dokumentu indeksÄ, dokuments tiek ievietots rindÄ un saglabÄts diskÄ. TÄpÄc mÅ«su gadÄ«jumÄ, lai novÄrstu problÄmas avotu, kas izraisa iepriekÅ” aprakstÄ«to kļūdu, ir jÄiestata pareizas buferizÄcijas parametru vÄrtÄ«bas, pie kurÄm Fluentd izvades buferis bÅ«s pietiekama izmÄra un tajÄ paÅ”Ä laikÄ izdodas tikt notÄ«rÄ«tam atvÄlÄtajÄ laikÄ.
Ir vÄrts atzÄ«mÄt, ka tÄlÄk aplÅ«koto parametru vÄrtÄ«bas ir individuÄlas katrÄ konkrÄtajÄ gadÄ«jumÄ, ja izvades spraudÅos tiek izmantota buferizÄcija, jo tÄs ir atkarÄ«gas no daudziem faktoriem: ziÅojumu ierakstÄ«Å”anas žurnÄlÄ intensitÄtes pa pakalpojumiem, diska sistÄmas veiktspÄjas, tÄ«kla. kanÄla slodze un tÄs joslas platums. TÄpÄc, lai iegÅ«tu katram atseviŔķam gadÄ«jumam piemÄrotus, bet ne liekus bufera iestatÄ«jumus, akli izvairoties no ilgstoÅ”as āāmeklÄÅ”anas, var izmantot atkļūdoÅ”anas informÄciju, ko Fluentd darbÄ«bas laikÄ ieraksta savÄ Å¾urnÄlÄ, un salÄ«dzinoÅ”i Ätri iegÅ«t pareizÄs vÄrtÄ«bas.
LaikÄ, kad problÄma tika reÄ£istrÄta, konfigurÄcija izskatÄ«jÄs Å”Ädi:
Atrisinot problÄmu, manuÄli tika atlasÄ«tas Å”Ädu parametru vÄrtÄ«bas:
chunk_limit_size ā to gabalu lielums, kuros tiek sadalÄ«ti ziÅojumi buferÄ«.
flush_interval ā laika intervÄls, pÄc kura buferis tiek notÄ«rÄ«ts.
queue_limit_length ā maksimÄlais gabalu skaits rindÄ.
request_timeout ir laiks, kurÄ tiek izveidots savienojums starp Fluentd un ElasticSearch.
KopÄjo bufera lielumu var aprÄÄ·inÄt, reizinot parametrus queue_limit_length un chunk_limit_size, ko var interpretÄt kÄ "maksimÄlo gabalu skaitu rindÄ, no kuriem katram ir noteikts izmÄrs". Ja bufera lielums nav pietiekams, žurnÄlos tiks parÄdÄ«ts Å”Äds brÄ«dinÄjums:
2020-01-21 10:22:57 +0000 [warn]: [test-prod] failed to write data into buffer by buffer overflow action=:block
Tas nozÄ«mÄ, ka buferim nav laika iztÄ«rÄ«ties atvÄlÄtajÄ laikÄ un tiek bloÄ·Äti dati, kas nonÄk pilnÄ buferÄ«, kÄ rezultÄtÄ daļa žurnÄlu tiks zaudÄta.
JÅ«s varat palielinÄt buferi divos veidos: palielinot vai nu katra rindas gabala lielumu, vai to gabalu skaitu, kas var bÅ«t rindÄ.
Ja gabala lielumu chunk_limit_size iestatÄt uz vairÄk nekÄ 32 megabaitiem, ElasticSeacrh to nepieÅems, jo ienÄkoÅ”Ä pakete bÅ«s pÄrÄk liela. TÄpÄc, ja nepiecieÅ”ams vÄl vairÄk palielinÄt buferi, labÄk ir palielinÄt maksimÄlo rindas garumu queue_limit_length.
Kad buferis pÄrstÄj pÄrpildÄ«t un paliek tikai ziÅojums par taimauta nepietiekamÄ«bu, varat sÄkt palielinÄt request_timeout parametru. TomÄr, ja iestatÄ«sit vÄrtÄ«bu, kas pÄrsniedz 20 sekundes, Fluentd žurnÄlos tiks parÄdÄ«ti Å”Ädi brÄ«dinÄjumi:
2020-01-21 09:55:33 +0000 [warn]: [test-dev] buffer flush took longer time than slow_flush_log_threshold: elapsed_time=20.85753920301795 slow_flush_log_threshold=20.0 plugin_id="postgresql-dev"
Å is ziÅojums nekÄdÄ veidÄ neietekmÄ sistÄmas darbÄ«bu un nozÄ«mÄ, ka bufera skaloÅ”anas laiks bija ilgÄks, nekÄ iestatÄ«ts ar parametru slow_flush_log_threshold. Å Ä« ir atkļūdoÅ”anas informÄcija, un mÄs to izmantojam, izvÄloties parametra request_timeout vÄrtÄ«bu.
VispÄrÄjais atlases algoritms ir Å”Äds:
Iestatiet request_timeout vÄrtÄ«bu, kas garantÄta ir lielÄka nekÄ nepiecieÅ”ams (simtiem sekunžu). IestatÄ«Å”anas laikÄ galvenais Ŕī parametra pareizas iestatÄ«Å”anas kritÄrijs bÅ«s brÄ«dinÄjumu pazuÅ”ana par taimauta trÅ«kumu.
Sagaidiet ziÅojumus par lÄnÄ_flush_log_threshold sliekÅ”Åa pÄrsniegÅ”anu. BrÄ«dinÄjuma teksts laukÄ elapsed_time parÄdÄ«s reÄlo laiku, kad buferis tika notÄ«rÄ«ts.
Iestatiet request_timeout vÄrtÄ«bu, kas ir lielÄka par maksimÄlo pagÄjuÅ”o laiku vÄrtÄ«bu, kas iegÅ«ta novÄroÅ”anas periodÄ. MÄs aprÄÄ·inÄm request_timeout vÄrtÄ«bu kÄ pagÄjuÅ”ais_laiks + 50%.
Lai no žurnÄla noÅemtu brÄ«dinÄjumus par garÄm bufera skalÄm, varat palielinÄt lÄnas_flush_log_threshold vÄrtÄ«bu. MÄs aprÄÄ·inÄm Å”o vÄrtÄ«bu kÄ pagÄjuÅ”ais_laiks + 25%.
Å o parametru galÄ«gÄs vÄrtÄ«bas, kÄ minÄts iepriekÅ”, tiek iegÅ«tas katram gadÄ«jumam atseviŔķi. IevÄrojot iepriekÅ” minÄto algoritmu, mÄs garantÄjam, ka novÄrsÄ«sim kļūdu, kas izraisa atkÄrtotus ziÅojumus.
TÄlÄk esoÅ”ajÄ tabulÄ parÄdÄ«ts, kÄ mainÄs kļūdu skaits dienÄ, kas izraisa ziÅojumu dublÄÅ”anos, iepriekÅ” aprakstÄ«to parametru vÄrtÄ«bu atlases procesÄ:
Ir arÄ« vÄrts atzÄ«mÄt, ka iegÅ«tie iestatÄ«jumi var zaudÄt savu nozÄ«mi, projektam augot un attiecÄ«gi palielinoties žurnÄlu skaitam. GalvenÄ nepietiekama taimauta pazÄ«me ir ziÅojumu atgrieÅ”anÄs par ilgu bufera skaloÅ”anu Fluentd žurnÄlÄ, tas ir, lÄna_flush_log_threshold sliekÅ”Åa pÄrsniegÅ”ana. No Ŕī brīža joprojÄm ir neliela rezerve, pirms tiek pÄrsniegts parametrs request_timeout, tÄpÄc ir nepiecieÅ”ams savlaicÄ«gi atbildÄt uz Å”iem ziÅojumiem un atkÄrtot iepriekÅ” aprakstÄ«to optimÄlo iestatÄ«jumu atlases procesu.
SecinÄjums
Fluentd izvades bufera precizÄÅ”ana ir viens no galvenajiem EFK steka konfigurÄÅ”anas posmiem, nosakot tÄ darbÄ«bas stabilitÄti un pareizu dokumentu izvietoÅ”anu indeksos. Pamatojoties uz aprakstÄ«to konfigurÄcijas algoritmu, varat bÅ«t pÄrliecinÄti, ka visi žurnÄli tiks ierakstÄ«ti ElasticSearch indeksÄ pareizÄ secÄ«bÄ, bez atkÄrtojumiem un zaudÄjumiem.