Fluentd: Wêrom is it wichtich om te konfigurearjen de útfier buffer

Fluentd: Wêrom is it wichtich om te konfigurearjen de útfier buffer

Tsjintwurdich is it ûnmooglik om in Kubernetes-basearre projekt foar te stellen sûnder de ELK-stapel, dy't logs bewarret fan sawol applikaasjes as systeemkomponinten fan it kluster. Yn ús praktyk brûke wy de EFK-stapel mei Fluentd ynstee fan Logstash.

Fluentd is in moderne, universele log-samler dy't hieltyd mear populariteit wint en is lid wurden fan 'e Cloud Native Computing Foundation, dat is de reden wêrom't syn ûntwikkelingsvektor rjochte is op gebrûk yn kombinaasje mei Kubernetes.

It feit fan it brûken fan Fluentd ynstee fan Logstash feroaret de algemiene essinsje fan it softwarepakket net, lykwols, Fluentd wurdt karakterisearre troch syn eigen spesifike nuânses dy't fuortkomme út syn veelzijdigheid.

Bygelyks, doe't wy begon te brûken EFK yn in drok projekt mei in hege yntinsiteit fan logging, wy waarden konfrontearre mei it feit dat yn Kibana guon berjochten waarden werjûn ferskate kearen. Yn dit artikel sille wy jo fertelle wêrom't dit ferskynsel foarkomt en hoe't jo it probleem oplosse kinne.

It probleem fan duplikaasje fan dokuminten

Yn ús projekten wurdt Fluentd ynset as in DaemonSet (automatysk lansearre yn ien eksimplaar op elke knooppunt fan it Kubernetes-kluster) en kontrolearret stdout-container-logs yn /var/log/containers. Nei it sammeljen en ferwurkjen wurde de logs yn 'e foarm fan JSON-dokuminten stjoerd nei ElasticSearch, opwekke yn kluster of standalone foarm, ôfhinklik fan de skaal fan it projekt en de easken foar prestaasjes en fouttolerânsje. Kibana wurdt brûkt as de grafyske ynterface.

By it brûken fan Fluentd mei in plugin foar útfierbuffer, tsjinkaam wy in situaasje wêryn guon dokuminten yn ElasticSearch krekt deselde ynhâld hienen en allinich ferskillen yn 'e identifier. Jo kinne ferifiearje dat dit in berjocht werhelling is mei it Nginx-log as foarbyld. Yn it logbestân bestiet dit berjocht yn ien kopy:

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

D'r binne lykwols ferskate dokuminten yn ElasticSearch dy't dit berjocht befetsje:

{
  "_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"
  }
}

Boppedat kinne der mear as twa werhellingen wêze.

Wylst jo dit probleem reparearje yn 'e Fluentd-logs, kinne jo in grut oantal warskôgings sjen mei de folgjende ynhâld:

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"

Dizze warskôgings komme foar as ElasticSearch gjin antwurd kin weromjaan op in fersyk binnen de tiid oantsjutte troch de parameter request_timeout, en dêrom kin it trochstjoerde bufferfragmint net wiske wurde. Hjirnei besiket Fluentd it bufferfragmint wer nei ElasticSearch te stjoeren en nei in willekeurich oantal besykjen foltôget de operaasje mei sukses:

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"

ElasticSearch behannelet lykwols elk fan 'e oerdroegen bufferfragminten as unyk en kent har unike _id-fjildwearden ta tidens yndeksearring. Dit is hoe't kopyen fan berjochten ferskine.

Yn Kibana sjocht it der sa út:

Fluentd: Wêrom is it wichtich om te konfigurearjen de útfier buffer

Troubleshooting

D'r binne ferskate opsjes om dit probleem op te lossen. Ien fan har is it meganisme ynboud yn 'e floeiende-plugin-elasticsearch-plugin foar it generearjen fan in unike hash foar elk dokumint. As jo ​​​​dit meganisme brûke, sil ElasticSearch werhellingen werkenne yn it trochstjoerstadium en dûbele dokuminten foarkomme. Mar wy moatte rekken hâlde mei dat dizze metoade foar it oplossen fan it probleem wrakselet mei it ûndersyk en net elimineren de flater mei in gebrek oan time-out, dus wy ferlitten it gebrûk.

Wy brûke in bufferplugin op 'e Fluentd-útfier om logferlies te foarkommen yn gefal fan koarte termyn netwurkproblemen of ferhege yntensiteit fan logboeken. As ElasticSearch om ien of oare reden net by steat is om in dokumint direkt nei de yndeks te skriuwen, wurdt it dokumint yn 'e wachtrige en opslein op skiif. Dêrom, yn ús gefal, om de boarne fan it probleem te eliminearjen dat liedt ta de hjirboppe beskreaune flater, is it needsaaklik om de juste wearden yn te stellen foar de bufferparameters, wêrby't de Fluentd-útfierbuffer fan genôch grutte sil wêze en tagelyk beheare wurde wiske yn 'e tawiisde tiid.

It is de muoite wurdich op te merken dat de wearden fan 'e parameters dy't hjirûnder besprutsen binne yndividueel binne yn elk spesifyk gefal fan gebrûk fan buffering yn útfierplugins, om't se ôfhinklik binne fan in protte faktoaren: de yntensiteit fan it skriuwen fan berjochten nei it log troch tsjinsten, skiifsysteemprestaasjes, netwurk kanaal load en syn bânbreedte. Dêrom, om bufferynstellingen te krijen dy't geskikt binne foar elk yndividueel gefal, mar net oerstallich, om lange sykopdrachten blyn te foarkommen, kinne jo de debuggen-ynformaasje brûke dy't Fluentd skriuwt yn har log yn 'e operaasje en relatyf fluch de juste wearden krije.

Op it momint dat it probleem waard opnommen, seach de konfiguraasje der sa út:

 <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>

By it oplossen fan it probleem waarden de wearden fan 'e folgjende parameters mei de hân selektearre:
chunk_limit_size - de grutte fan 'e brokken wêryn berjochten yn' e buffer binne ferdield.

  • flush_interval - tiid ynterval wêrnei't de buffer wurdt wiske.
  • queue_limit_length - it maksimum oantal brokken yn 'e wachtrige.
  • request_timeout is de tiid wêrfoar't de ferbining tusken Fluentd en ElasticSearch is oprjochte.

De totale buffergrutte kin wurde berekkene troch it fermannichfâldigjen fan de parameters queue_limit_length en chunk_limit_size, dy't kin wurde ynterpretearre as "it maksimum oantal brokken yn 'e wachtrige, elk fan dat hat in opjûne grutte." As de buffergrutte net genôch is, sil de folgjende warskôging ferskine yn 'e logs:

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

It betsjut dat de buffer gjin tiid hat om te wiskjen yn 'e tawiisde tiid en de gegevens dy't de folsleine buffer ynfiere wurde blokkearre, wat sil liede ta it ferlies fan in diel fan' e logs.

Jo kinne de buffer op twa manieren ferheegje: troch de grutte fan elke brok yn 'e wachtrige te fergrutsjen, of it oantal brokken dat yn' e wachtrige kin wêze.

As jo ​​de brokgrutte chunk_limit_size op mear as 32 megabytes ynstelle, dan sil ElasticSeacrh it net akseptearje, om't it ynkommende pakket te grut sil wêze. Dêrom, as jo moatte fergrutsje de buffer fierder, it is better te fergrutsjen de maksimale wachtrige lingte queue_limit_length.

Wannear't de buffer ophâldt oerrinnend en allinnich de time-out net genôch berjocht bliuwt, kinne jo begjinne te fergrutsjen de request_timeout parameter. As jo ​​​​de wearde lykwols op mear as 20 sekonden ynstelle, sille de folgjende warskôgings begjinne te ferskinen yn 'e Fluentd-logs:

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" 

Dit berjocht hat gjin ynfloed op de wurking fan it systeem yn alle wize en betsjut dat de buffer flush tiid duorre langer as ynsteld troch de slow_flush_log_threshold parameter. Dit is ynformaasje oer debuggen en wy brûke it by it kiezen fan de wearde fan de parameter request_timeout.

It generalisearre seleksjealgoritme is as folget:

  1. Stel request_timeout yn op in garandearre wearde grutter dan nedich (hûnderten sekonden). Tidens de opset sil it wichtichste kritearium foar de juste ynstelling fan dizze parameter it ferdwinen fan warskôgings foar in gebrek oan time-out wêze.
  2. Wachtsje op berjochten oer it oersjen fan de slow_flush_log_threshold-drompel. De warskôgingstekst yn it elapsed_time-fjild sil de echte tiid sjen litte dat de buffer wiske is.
  3. Stel request_timeout yn op in wearde dy't grutter is as de maksimale elapsed_time wearde krigen yn 'e observaasjeperioade. Wy berekkenje de request_timeout wearde as elapsed_time + 50%.
  4. Foar in fuortsmite warskôgings oer lange buffer flushes út it log, kinne jo ferheegje de wearde fan slow_flush_log_threshold. Wy berekkenje dizze wearde as elapsed_time + 25%.

De definitive wearden fan dizze parameters, lykas earder opmurken, wurde yndividueel foar elk gefal krigen. Troch it boppesteande algoritme te folgjen, wurde wy garandearre om de flater te eliminearjen dy't liedt ta werhelle berjochten.

De tabel hjirûnder lit sjen hoe't it oantal flaters per dei, dy't liedt ta duplikaasje fan berjochten, feroarings yn it proses fan it selektearjen fan de wearden fan de hjirboppe beskreaune parameters:

node-1
node-2
node-3
node-4

Foar nei
Foar nei
Foar nei
Foar nei

mislearre te spoelen de buffer
1749/2
694/2
47/0
1121/2

opnij besykjen slagge
410/2
205/1
24/0
241/2

It is ek de muoite wurdich op te merken dat de resultearjende ynstellingen har relevânsje kinne ferlieze as it projekt groeit en dêrtroch it oantal logs nimt ta. It primêre teken fan ûnfoldwaande time-out is it werombringen fan berjochten oer in lange bufferflush nei it Fluentd-log, dat wol sizze, oer de slow_flush_log_threshold-drompel. Fan dit punt ôf is d'r noch in lytse marzje foar't de parameter request_timeout wurdt overschreden, dus it is nedich om op 'e tiid te reagearjen op dizze berjochten en it proses fan it selektearjen fan de hjirboppe beskreaune optimale ynstellingen werhelje.

konklúzje

Fine-tuning de Fluentd útfier buffer is ien fan de wichtichste stadia fan it konfigurearjen fan de EFK stack, bepale de stabiliteit fan syn wurking en de krekte pleatsing fan dokuminten yn yndeksen. Op grûn fan it beskreaune konfiguraasjealgoritme kinne jo der wis fan wêze dat alle logs wurde skreaun nei de ElasticSearch-yndeks yn 'e juste folchoarder, sûnder werhellingen of ferlies.

Lês ek oare artikels op ús blog:

Boarne: www.habr.com

Add a comment