Fluentd: miks on oluline väljundpuhvrit konfigureerida

Fluentd: miks on oluline väljundpuhvrit konfigureerida

Tänapäeval on võimatu ette kujutada Kubernetese-põhist projekti ilma ELK-pinnata, mis salvestab nii rakenduste kui ka klastri süsteemikomponentide logisid. Oma praktikas kasutame Logstashi asemel EFK virna Fluentdiga.

Fluentd on kaasaegne universaalne logikoguja, mis kogub üha enam populaarsust ja on liitunud Cloud Native Computing Foundationiga, mistõttu on selle arendusvektor keskendunud kasutamisele koos Kubernetesega.

Fluentdi kasutamine Logstashi asemel ei muuda tarkvarapaketi üldist olemust, kuid Fluentdi iseloomustavad selle mitmekülgsusest tulenevad oma spetsiifilised nüansid.

Näiteks kui hakkasime EFK-d kasutama kiires ja suure metsaraie intensiivsusega projektis, seisime silmitsi tõsiasjaga, et Kibanas kuvati mõnda teadet korduvalt korduvalt. Selles artiklis räägime teile, miks see nähtus ilmneb ja kuidas probleemi lahendada.

Dokumentide dubleerimise probleem

Meie projektides on Fluentd juurutatud DaemonSetina (käivitatakse automaatselt ühes eksemplaris Kubernetese klastri igas sõlmes) ja jälgib stdout konteineri logisid /var/log/containers. Pärast kogumist ja töötlemist saadetakse JSON-dokumentide vormis logid ElasticSearchile, tõstetakse üles kas kobaras või eraldiseisvas vormis, olenevalt projekti ulatusest ning jõudluse ja tõrketaluvuse nõuetest. Graafilise liidesena kasutatakse Kibanat.

Kasutades Fluentd koos väljundi puhverduspluginaga, tekkis olukord, kus ElasticSearchis olid mõned dokumendid täpselt sama sisuga ja erinesid ainult identifikaatori poolest. Saate kontrollida, kas see on sõnumi kordus, kasutades näitena Nginxi logi. Logifailis on see teade ühes eksemplaris:

127.0.0.1 192.168.0.1 - [28/Feb/2013:12:00:00 +0900] "GET / HTTP/1.1" 200 777 "-" "Opera/12.0" -

Siiski on ElasticSearchis mitu dokumenti, mis sisaldavad seda teadet:

{
  "_index": "test-custom-prod-example-2020.01.02",
  "_type": "_doc",
  "_id": "HgGl_nIBR8C-2_33RlQV",
  "_version": 1,
  "_score": 0,
  "_source": {
    "service": "test-custom-prod-example",
    "container_name": "nginx",
    "namespace": "test-prod",
    "@timestamp": "2020-01-14T05:29:47.599052886 00:00",
    "log": "127.0.0.1 192.168.0.1 - [28/Feb/2013:12:00:00  0900] "GET / HTTP/1.1" 200 777 "-" "Opera/12.0" -",
    "tag": "custom-log"
  }
}

{
  "_index": "test-custom-prod-example-2020.01.02",
  "_type": "_doc",
  "_id": "IgGm_nIBR8C-2_33e2ST",
  "_version": 1,
  "_score": 0,
  "_source": {
    "service": "test-custom-prod-example",
    "container_name": "nginx",
    "namespace": "test-prod",
    "@timestamp": "2020-01-14T05:29:47.599052886 00:00",
    "log": "127.0.0.1 192.168.0.1 - [28/Feb/2013:12:00:00  0900] "GET / HTTP/1.1" 200 777 "-" "Opera/12.0" -",
    "tag": "custom-log"
  }
}

Pealegi võib kordusi olla rohkem kui kaks.

Selle probleemi lahendamisel Fluentdi logides näete suurt hulka järgmise sisuga hoiatusi:

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"

Need hoiatused ilmnevad siis, kui ElasticSearch ei saa parameetriga request_timeout määratud aja jooksul päringule vastust tagastada, mistõttu ei saa edastatud puhvri fragmenti tühjendada. Pärast seda proovib Fluentd puhvri fragmenti uuesti ElasticSearchile saata ja pärast suvalise arvu katseid lõpeb toiming edukalt:

2020-01-16 01:47:05 +0000 [warn]: [test-prod] retry succeeded. chunk_id="59c37fc3fb320608692c352802b973ce" 
2020-01-16 01:47:05 +0000 [warn]: [test-prod] retry succeeded. chunk_id="59c37fad241ab300518b936e27200747" 
2020-01-16 01:47:05 +0000 [warn]: [test-dev] retry succeeded. chunk_id="59c37fc11f7ab707ca5de72a88321cc2" 
2020-01-16 01:47:05 +0000 [warn]: [test-dev] retry succeeded. chunk_id="59c37fb5adb70c06e649d8c108318c9b" 
2020-01-16 01:47:15 +0000 [warn]: [kube-system] retry succeeded. chunk_id="59c37f63a9046e6dff7e9987729be66f"

Siiski käsitleb ElasticSearch iga ülekantud puhvri fragmenti unikaalsena ja määrab neile indekseerimise ajal ainulaadsed _id välja väärtused. Nii ilmuvad sõnumite koopiad.

Kibanas näeb see välja selline:

Fluentd: miks on oluline väljundpuhvrit konfigureerida

Lahendus

Selle probleemi lahendamiseks on mitu võimalust. Üks neist on pluginasse fluent-plugin-elasticsearch sisseehitatud mehhanism, mis loob iga dokumendi jaoks ainulaadse räsi. Kui kasutate seda mehhanismi, tunneb ElasticSearch ära kordused edastamise etapis ja hoiab ära dokumentide dubleerimise. Kuid me peame arvestama, et see probleemi lahendamise meetod võitleb uurimisega ega kõrvalda viga ajalõpu puudumisega, mistõttu loobusime selle kasutamisest.

Kasutame Fluentd väljundis puhverduspluginat, et vältida logikadu lühiajaliste võrguprobleemide või suurenenud logimise intensiivsuse korral. Kui ElasticSearch ei saa mingil põhjusel dokumenti kohe registrisse kirjutada, pannakse dokument järjekorda ja salvestatakse kettale. Seetõttu on meie puhul ülalkirjeldatud tõrke põhjustava probleemi allika kõrvaldamiseks vaja puhverdusparameetrite jaoks määrata õiged väärtused, mille juures on Fluentd väljundpuhver piisava suurusega ja samal ajal õnnestub määratud aja jooksul puhastada.

Väärib märkimist, et allpool käsitletud parameetrite väärtused on igal konkreetsel juhul väljundpluginate puhverdamise kasutamisel individuaalsed, kuna need sõltuvad paljudest teguritest: teenuste logisse sõnumite kirjutamise intensiivsus, kettasüsteemi jõudlus, võrk. kanali koormus ja selle ribalaius. Seega, selleks, et saada igaks üksikjuhtumiks sobivaid, kuid mitte üleliigseid puhvrisätteid, vältides pimesi pikki otsinguid, saate kasutada silumisinfot, mille Fluentd töö ajal oma logisse kirjutab, ja hankida suhteliselt kiiresti õiged väärtused.

Probleemi salvestamise ajal nägi konfiguratsioon välja selline:

 <buffer>
        @type file
        path /var/log/fluentd-buffers/kubernetes.test.buffer
        flush_mode interval
        retry_type exponential_backoff
        flush_thread_count 2
        flush_interval 5s
        retry_forever
        retry_max_interval 30
        chunk_limit_size 8M
        queue_limit_length 8
        overflow_action block
      </buffer>

Probleemi lahendamisel valiti käsitsi järgmiste parameetrite väärtused:
chunk_limit_size — tükkide suurus, milleks puhvris olevad sõnumid on jagatud.

  • flush_interval – ajavahemik, mille möödudes puhver tühjendatakse.
  • queue_limit_length — maksimaalne tükkide arv järjekorras.
  • request_timeout on aeg, milleks Fluentd ja ElasticSearch vaheline ühendus luuakse.

Puhvri kogumahu saab arvutada, korrutades parameetrid queue_limit_length ja chunk_limit_size, mida saab tõlgendada kui "maksimaalset tükkide arvu järjekorras, millest igaühel on etteantud suurus". Kui puhvri suurus on ebapiisav, kuvatakse logides järgmine hoiatus:

2020-01-21 10:22:57 +0000 [warn]: [test-prod] failed to write data into buffer by buffer overflow action=:block

See tähendab, et puhvril ei ole aega määratud aja jooksul tühjendada ja täispuhvrisse sisenevad andmed blokeeritakse, mis toob kaasa osa logide kadumise.

Saate puhvrit suurendada kahel viisil: suurendades kas järjekorras iga tüki suurust või järjekorras olevate tükkide arvu.

Kui seate tüki suuruseks chunk_limit_size rohkem kui 32 megabaiti, siis ElasticSeacrh seda ei aktsepteeri, kuna sissetulev pakett on liiga suur. Seega, kui teil on vaja puhvrit veelgi suurendada, on parem suurendada järjekorra maksimaalset pikkust queue_limit_length.

Kui puhver lõpetab ületäitumise ja alles jääb ainult teade timeout insufficient, võite alustada parameetri request_timeout suurendamist. Kui aga määrate väärtuseks rohkem kui 20 sekundit, hakkavad Fluentd logides ilmuma järgmised hoiatused.

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" 

See teade ei mõjuta kuidagi süsteemi tööd ja tähendab, et puhvri loputusaeg võttis kauem aega, kui parameetri slow_flush_log_threshold poolt määratud. See on silumise teave ja me kasutame seda parameetri request_timeout väärtuse valimisel.

Üldine valikualgoritm on järgmine:

  1. Määrake päringu_ajalõpp väärtuseks, mis on garanteeritud vajalikust suurem (sadu sekundeid). Seadistamise ajal on selle parameetri õige seadistamise peamiseks kriteeriumiks ajalõpu puudumise hoiatuste kadumine.
  2. Oodake teateid slow_flush_log_threshold läve ületamise kohta. Hoiatustekst väljal kulunud_aeg näitab puhvri tühjendamise reaalaega.
  3. Määrake päringu_ajalõpp väärtuseks, mis on suurem kui vaatlusperioodi jooksul saadud maksimaalne kulunud_aeg. Arvutame päringu ajalõpu väärtuseks kulunud_aeg + 50%.
  4. Hoiatuste eemaldamiseks logist pikkade puhvri loputuste kohta saate tõsta slow_flush_log_threshold väärtust. Arvutame selle väärtuse kulunud_aeg + 25%.

Nende parameetrite lõplikud väärtused, nagu varem märgitud, saadakse iga juhtumi puhul eraldi. Ülaltoodud algoritmi järgides kõrvaldame vea, mis põhjustab korduvaid sõnumeid.

Allolev tabel näitab, kuidas muutub päevaste vigade arv, mis põhjustab sõnumite dubleerimist, ülalkirjeldatud parameetrite väärtuste valimise protsessis:

sõlm-1
sõlm-2
sõlm-3
sõlm-4

Enne pärast
Enne pärast
Enne pärast
Enne pärast

puhvrit ei õnnestunud loputada
1749/2
694/2
47/0
1121/2

uuesti proovimine õnnestus
410/2
205/1
24/0
241/2

Lisaks väärib märkimist, et saadud sätted võivad projekti kasvades kaotada oma tähtsuse ja vastavalt suureneb logide arv. Ebapiisava ajalõpu peamine märk on sõnumite tagasipöördumine pika puhvri loputamise kohta Fluentd logi, st slow_flush_log_threshold läve ületamist. Sellest hetkest alates jääb parameetri request_timeout parameetri ületamiseks veel väike varu, seega on vaja neile teadetele õigeaegselt vastata ja korrata ülalkirjeldatud optimaalsete sätete valimise protsessi.

Järeldus

Fluentd väljundpuhvri peenhäälestus on EFK virna konfigureerimise üks peamisi etappe, mis määrab selle töö stabiilsuse ja dokumentide õige paigutuse indeksitesse. Kirjeldatud konfiguratsioonialgoritmi põhjal võite olla kindel, et kõik logid kirjutatakse ElasticSearchi indeksisse õiges järjekorras, ilma korduste ja kadudeta.

Loe ka teisi meie ajaveebi artikleid:

Allikas: www.habr.com

Lisa kommentaar