Fluentd: zergatik den garrantzitsua irteera-buffer-a konfiguratzea

Fluentd: zergatik den garrantzitsua irteera-buffer-a konfiguratzea

Gaur egun, ezinezkoa da Kubernetesen oinarritutako proiektu bat imajinatu ELK pilarik gabe, zeinak klusterraren aplikazioen eta sistemaren osagaien erregistroak gordetzen dituen. Gure praktikan, EFK pila erabiltzen dugu Fluentd-rekin Logstash-en ordez.

Fluentd erregistro-biltzaile moderno eta unibertsala da, gero eta ospe handiagoa hartzen ari dena eta Cloud Native Computing Foundation-en sartu dena, horregatik bere garapen-bektorea Kubernetesekin batera erabiltzera bideratzen da.

Logstash-en ordez Fluentd erabiltzeak ez du software paketearen funtsa orokorra aldatzen, hala ere, Fluentd-ek bere aldakortasunaren ondoriozko Γ±abardura espezifikoak ditu.

Esaterako, erregistro-intentsitate handiko proiektu okupatu batean EFK erabiltzen hasi ginenean, Kibanan mezu batzuk behin eta berriz bistaratzen zirela tokatu zitzaigun. Artikulu honetan fenomeno hau zergatik gertatzen den eta arazoa nola konpondu esango dizugu.

Dokumentuen bikoizketaren arazoa

Gure proiektuetan, Fluentd DaemonSet gisa zabaltzen da (automatikoki abiarazten da Kubernetes klusterreko nodo bakoitzean instantzia batean) eta stdout edukiontzien erregistroak kontrolatzen ditu /var/log/containers-en. Bildu eta prozesatu ondoren, JSON dokumentuen formako erregistroak ElasticSearch-era bidaltzen dira, kluster edo modu autonomoan sortuak, proiektuaren eskalaren eta errendimenduaren eta akatsen tolerantziaren eskakizunen arabera. Kibana interfaze grafiko gisa erabiltzen da.

Fluentd irteerako buffer-plugin batekin erabiltzean, ElasticSearch-eko dokumentu batzuek eduki berdina zuten eta identifikatzailean soilik desberdintzen ziren egoera bat aurkitu genuen. Hau mezu errepikapena dela egiazta dezakezu Nginx erregistroa adibide gisa erabiliz. Erregistro fitxategian, mezu hau kopia bakarrean dago:

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

Hala ere, ElasticSearch-en badaude mezu hau duten hainbat dokumentu:

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

Gainera, bi errepikapen baino gehiago egon daitezke.

Fluentd erregistroetan arazo hau konpontzen duzun bitartean, abisu ugari ikus ditzakezu eduki honekin:

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"

Abisu hauek ElasticSearch-ek ezin duenean erantzun eskaerari erantzun request_timeout parametroak zehaztutako epean gertatzen dira, horregatik ezin da birbidaltutako buffer zatia garbitu. Horren ondoren, Fluentd-ek buffer zatia ElasticSearch-era bidaltzen saiatzen da berriro eta saiakera kopuru arbitrario baten ondoren, eragiketa arrakastaz amaitzen da:

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"

Hala ere, ElasticSearch-ek transferitutako buffer zati bakoitza bakar gisa tratatzen du eta _id eremuko balio bakarrak esleitzen dizkie indexazioan. Horrela agertzen dira mezuen kopiak.

Kibanan honela ikusten da:

Fluentd: zergatik den garrantzitsua irteera-buffer-a konfiguratzea

Irtenbidea

Hainbat aukera daude arazo hau konpontzeko. Horietako bat fluent-plugin-elasticsearch pluginean integratutako mekanismoa da, dokumentu bakoitzeko hash bakarra sortzeko. Mekanismo hau erabiltzen baduzu, ElasticSearch-ek birbidaltzeko fasean errepikapenak ezagutuko ditu eta dokumentu bikoiztuak saihestuko ditu. Baina kontuan izan behar dugu arazoa konpontzeko metodo honek ikerketarekin borrokatzen duela eta ez duela akatsa kentzen denbora-muga faltarekin, beraz, erabilerari utzi genion.

Buffering plugin bat erabiltzen dugu Fluentd irteeran epe laburreko sare-arazoak edo erregistro-intentsitatea handituz gero erregistro-galera saihesteko. Arrazoiren batengatik ElasticSearch-ek ezin badu dokumentu bat berehala idatzi indizean, dokumentua ilaran jartzen da eta diskoan gordetzen da. Hori dela eta, gure kasuan, goian deskribatutako errorea eragiten duen arazoaren iturburua ezabatzeko, beharrezkoa da buffering-parametroen balio zuzenak ezarri, zeinetan Fluentd irteerako buffer nahikoa izango den eta aldi berean, emandako denboran garbitzea lortzen da.

Azpimarratzekoa da azpian aztertutako parametroen balioak indibidualak direla irteerako pluginetan buffering-a erabiltzeko kasu zehatz bakoitzean, faktore askoren araberakoak baitira: zerbitzuen arabera erregistroan mezuak idazteko intentsitatea, disko-sistemaren errendimendua, sarea. kanalaren karga eta bere banda zabalera. Hori dela eta, kasu bakoitzerako egokiak diren buffer ezarpenak lortzeko, baina erredundikoak ez direnak, bilaketa luzeak itsu-itsuan saihestuz, Fluentd-ek bere erregistroan idazten duen arazketa-informazioa erabil dezakezu operazioan zehar eta nahiko azkar lor ditzakezu balio zuzenak.

Arazoa grabatu zen unean, konfigurazioa honela zegoen:

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

Arazoa ebaztean, parametro hauen balioak eskuz hautatu ziren:
chunk_limit_size β€” Buffer-eko mezuak banatzen diren zatien tamaina.

  • flush_interval β€” buffera garbitzen den denbora-tartea.
  • queue_limit_length β€” ilaran dagoen gehienezko zati kopurua.
  • request_timeout Fluentd eta ElasticSearch-en arteko konexioa ezartzen den denbora da.

Buffer-aren guztizko tamaina, queue_limit_length eta chunk_limit_size parametroak biderkatuz kalkula daiteke, "ilaran dauden zati kopuru maximoa, horietako bakoitzak tamaina jakin bat du" gisa interpretatu daitekeena. Buffer-aren tamaina nahikoa ez bada, honako abisu hau agertuko da erregistroetan:

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

Esan nahi du buffer-ak ez duela emandako denboran garbitzeko astirik eta buffer osoan sartzen diren datuak blokeatuta daudela, eta horrek erregistroen zati bat galtzea ekarriko du.

Buffer-a bi modutara handitu dezakezu: ilaran dagoen zati bakoitzaren tamaina edo ilaran egon daitezkeen zati kopurua handituz.

Chunk_limit_size zatiaren tamaina 32 megabyte baino gehiago ezartzen baduzu, ElasticSeacrh-ek ez du onartuko, sarrerako paketea handiegia izango baita. Hori dela eta, buffer-a gehiago handitu behar baduzu, hobe da ilararen gehienezko luzera ilara_limit_length handitzea.

Buffer-ak gainezka egiten uzten duenean eta denbora-muga ez dagoen mezua bakarrik geratzen denean, request_timeout parametroa handitzen has zaitezke. Hala ere, balioa 20 segundo baino gehiagotan ezartzen baduzu, abisu hauek hasiko dira Fluentd erregistroetan:

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" 

Mezu honek ez dio sistemaren funtzionamenduari inola ere eragiten eta esan nahi du buffer-a garbitzeko denborak slow_flush_log_threshold parametroak ezarritakoa baino luzeagoa izan dela. Hau arazketa-informazioa da eta request_timeout parametroaren balioa aukeratzerakoan erabiltzen dugu.

Aukeraketa algoritmo orokortua honako hau da:

  1. Ezarri request_timeout beharrezkoa baino handiagoa izango dela bermatuta dagoen balio batean (ehunka segundo). Konfigurazioan, parametro hau zuzen ezartzeko irizpide nagusia denbora-muga faltagatik abisuak desagertzea izango da.
  2. Itxaron slow_flush_log_threshold atalasea gainditzeari buruzko mezuak. Elapsed_time eremuko abisu-testuak buffera garbitu den denbora errealean erakutsiko du.
  3. Ezarri request_timeout behaketa-aldian lortutako gehienezko elapsed_time balioa baino balio handiagoarekin. request_timeout balioa elapsed_time + %50 gisa kalkulatzen dugu.
  4. Bufferen husketa luzeei buruzko abisuak erregistrotik kentzeko, slow_flush_log_threshold-en balioa igo dezakezu. Balio hau elapsed_time + % 25 gisa kalkulatzen dugu.

Parametro horien azken balioak, lehen esan bezala, banan-banan lortzen dira kasu bakoitzerako. Goiko algoritmoari jarraituz, mezu errepikatuak eragiten dituen errorea ezabatuko dugula bermatuta gaude.

Beheko taulak erakusten du nola aldatzen den eguneko errore kopurua, mezuak bikoiztea eraginez, goian deskribatutako parametroen balioak hautatzeko prozesuan:

nodoa-1
nodoa-2
nodoa-3
nodoa-4

Aurretik eta gero
Aurretik eta gero
Aurretik eta gero
Aurretik eta gero

huts egin du buffer-a garbitu
1749/2
694/2
47/0
1121/2

berriro saiatu da
410/2
205/1
24/0
241/2

Gainera, nabarmentzekoa da ondoriozko ezarpenek garrantzia galdu dezaketela proiektua hazten den heinean eta, ondorioz, erregistro-kopurua handitzen dela. Denbora-muga nahikoa ezaren seinale nagusia Buffer-aren hustuketa luze bati buruzko mezuak Fluentd erregistrora itzultzea da, hau da, slow_flush_log_threshold atalasea gainditzea. Une honetatik aurrera, oraindik marjina txiki bat dago request_timeout parametroa gainditu aurretik, beraz, beharrezkoa da mezu horiei garaiz erantzutea eta goian deskribatutako ezarpen optimoak hautatzeko prozesua errepikatzea.

Ondorioa

Fluentd irteera-buffer-a finkatzea EFK pila konfiguratzeko fase nagusietako bat da, bere funtzionamenduaren egonkortasuna eta dokumentuak indizeetan zuzen kokatzeko. Deskribatutako konfigurazio algoritmoan oinarrituta, ziur egon zaitez erregistro guztiak ElasticSearch indizean ordena egokian idatziko direla, errepikapenik edo galerarik gabe.

Irakurri beste artikulu batzuk ere gure blogean:

Iturria: www.habr.com

Gehitu iruzkin berria