Fluentd: Чаро танзим кардани буфери баромад муҳим аст

Fluentd: Чаро танзим кардани буфери баромад муҳим аст

Имрӯзҳо лоиҳаи Кубернетесро бе стеки ELK тасаввур кардан ғайриимкон аст, ки сабтҳои ҳам замимаҳо ва ҳам ҷузъҳои системаи кластерро захира мекунад. Дар таҷрибаи мо, мо ба ҷои Logstash стеки EFK-ро бо Fluentd истифода мебарем.

Fluentd коллектори муосир ва универсалии лог мебошад, ки торафт маъруфият пайдо мекунад ва ба Бунёди Cloud Native Computing ҳамроҳ шудааст, аз ин рӯ вектори рушди он ба истифода дар якҷоягӣ бо Kubernetes нигаронида шудааст.

Далели истифодаи Fluentd ба ҷои Logstash моҳияти умумии бастаи нармафзорро тағир намедиҳад, аммо Fluentd бо нозукиҳои хоси худ, ки аз универсалии он бармеоянд, тавсиф мешавад.

Масалан, вақте ки мо истифодаи EFK-ро дар як лоиҳаи серодам бо шиддати баланди сабткунӣ оғоз кардем, мо бо он дучор шудем, ки дар Кибана баъзе паёмҳо борҳо такроран намоиш дода шуданд. Дар ин мақола мо ба шумо мегӯям, ки чаро ин падида рух медиҳад ва чӣ гуна ҳалли мушкилот.

Проблемаи такрори ҳуҷҷатҳо

Дар лоиҳаҳои мо, Fluentd ҳамчун DaemonSet ҷойгир карда шудааст (ба таври худкор дар як мисол дар ҳар як гиреҳи кластери Kubernetes оғоз мешавад) ва сабтҳои контейнерии stdout-ро дар /var/log/containers назорат мекунад. Пас аз ҷамъоварӣ ва коркард, гузоришҳо дар шакли ҳуҷҷатҳои JSON ба ElasticSearch фиристода мешаванд, ки вобаста ба миқёси лоиҳа ва талабот ба иҷроиш ва таҳаммулпазирии хатогиҳо дар кластер ё шакли мустақил бардошта мешаванд. Kibana ҳамчун интерфейси графикӣ истифода мешавад.

Ҳангоми истифодаи Fluentd бо плагини буферии баромад, мо ба вазъият дучор шудем, ки баъзе ҳуҷҷатҳо дар ElasticSearch айнан ҳамон мундариҷа доштанд ва танҳо дар идентификатор фарқ мекарданд. Шумо метавонед тафтиш кунед, ки ин такрори паём аст, бо истифода аз сабти Nginx ҳамчун мисол. Дар файли сабт, ин паём дар як нусха мавҷуд аст:

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

Аммо, дар ElasticSearch якчанд ҳуҷҷатҳо мавҷуданд, ки ин паёмро дар бар мегиранд:

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

Илова бар ин, метавонад зиёда аз ду такрор бошад.

Ҳангоми ислоҳи ин мушкилот дар гузоришҳои Fluentd, шумо метавонед шумораи зиёди огоҳиҳои дорои мундариҷаи зеринро бинед:

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"

Ин огоҳиҳо вақте рух медиҳанд, ки ElasticSearch натавонист посухро ба дархост дар давоми вақти муайянкардаи параметри request_timeout баргардонад, аз ин рӯ фрагменти буферии ирсолшуда тоза карда намешавад. Пас аз ин, Fluentd кӯшиш мекунад, ки фрагменти буфериро ба ElasticSearch дубора фиристад ва пас аз кӯшишҳои худсарона, амалиёт бомуваффақият анҷом меёбад:

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 ба ҳар як порчаҳои буферии интиқолшуда ҳамчун беназир муносибат мекунад ва ба онҳо ҳангоми индексатсия арзишҳои беназири майдони _id таъин мекунад. Ҳамин тавр нусхаҳои паёмҳо пайдо мешаванд.

Дар Кибана чунин менамояд:

Fluentd: Чаро танзим кардани буфери баромад муҳим аст

Муҳофизати саволҳо

Якчанд вариантҳо барои ҳалли ин мушкилот вуҷуд доранд. Яке аз онҳо механизмест, ки дар плагини fluent-plugin-elasticsearch барои тавлиди хэши беназир барои ҳар як ҳуҷҷат сохта шудааст. Агар шумо ин механизмро истифода баред, ElasticSearch такрорҳоро дар марҳилаи интиқол эътироф мекунад ва ҳуҷҷатҳои такрориро пешгирӣ мекунад. Аммо мо бояд ба назар гирем, ки ин усули халли масъала бо тафтишот мубориза мебарад ва хатогиро бо нарасидани вакт бартараф намекунад, бинобар ин мо аз истифодаи он даст кашидаем.

Мо як плагини буфериро дар баромади Fluentd истифода мебарем, то аз талафоти сабт дар сурати мушкилоти кӯтоҳмуддати шабака ё афзоиши шиддати сабткунӣ пешгирӣ карда шавад. Агар бо ягон сабаб ElasticSearch наметавонад ҳуҷҷатро фавран ба индекс нависад, ҳуҷҷат дар навбат гузошта мешавад ва дар диск нигоҳ дошта мешавад. Аз ин рӯ, дар ҳолати мо, барои бартараф кардани манбаи мушкилоте, ки боиси хатогии дар боло тавсифшуда мегардад, зарур аст, ки арзишҳои дурусти параметрҳои буферӣ муқаррар карда шаванд, ки дар он буфери баромади Fluentd андозаи кофӣ хоҳад буд ва дар баробари ин муяссар мешавад, ки дар мухлати мукарраршуда тоза карда шавад.

Бояд қайд кард, ки арзишҳои параметрҳои дар зер баррасӣшуда дар ҳар як ҳолати мушаххаси истифодаи буферӣ дар плагинҳои баромад инфиродӣ мебошанд, зеро онҳо аз бисёр омилҳо вобастаанд: шиддати навиштани паёмҳо ба гузориш аз ҷониби хидматҳо, кори системаи диск, шабака сарбории канал ва маҷрои он. Аз ин рӯ, барои ба даст овардани танзимоти буферӣ, ки барои ҳар як ҳолати инфиродӣ мувофиқанд, аммо зиёдатӣ нестанд ва аз ҷустуҷӯҳои тӯлонӣ дурӣ ҷӯянд, шумо метавонед иттилооти ислоҳиро, ки Fluentd ҳангоми кор ба сабти худ менависад, истифода баред ва нисбатан зуд арзишҳои дурустро ба даст оред.

Ҳангоми сабт кардани мушкилот, конфигуратсия чунин менамуд:

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

Ҳангоми ҳалли мушкилот, арзишҳои параметрҳои зерин дастӣ интихоб карда шуданд:
chunk_limit_size — андозаи пораҳое, ки паёмҳо дар буфер ба онҳо тақсим мешаванд.

  • flush_interval — фосилаи вақт, ки пас аз он буфер тоза карда мешавад.
  • queue_limit_length — шумораи ниҳоии порчаҳо дар навбат.
  • request_timeout вақтест, ки барои он робита байни Fluentd ва ElasticSearch муқаррар карда мешавад.

Андозаи умумии буферро бо роҳи зарб кардани параметрҳои queue_limit_length ва chunk_limit_size ҳисоб кардан мумкин аст, ки онро метавон ҳамчун "шумораи ҳадди аксар қисмҳои навбат, ки ҳар яки онҳо андозаи додашуда доранд" тафсир кард. Агар андозаи буфер нокифоя бошад, дар гузоришҳо огоҳии зерин пайдо мешавад:

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

Ин маънои онро дорад, ки буфер барои тоза кардан дар вақти ҷудошуда вақт надорад ва маълумоте, ки ба буфери пурра ворид мешавад, баста мешавад, ки ин боиси гум шудани қисми гузоришҳо мегардад.

Шумо метавонед буферро бо ду роҳ зиёд кунед: бо зиёд кардани андозаи ҳар як порча дар навбат ё шумораи порчаҳое, ки метавонанд дар навбат бошанд.

Агар шумо андозаи chunk_limit_size-ро ба зиёда аз 32 мегабайт муқаррар кунед, ElasticSeacrh онро қабул намекунад, зеро бастаи воридотӣ хеле калон хоҳад буд. Аз ин рӯ, агар ба шумо лозим ояд, ки буферро минбаъд зиёд кунед, беҳтар аст, ки дарозии навбати максималии queue_limit_length -ро зиёд кунед.

Вақте ки буфер пур шуданро қатъ мекунад ва танҳо паёми нокифояи вақт боқӣ мемонад, шумо метавонед ба зиёд кардани параметри request_timeout оғоз кунед. Аммо, агар шумо арзишро ба зиёда аз 20 сония таъин кунед, огоҳиҳои зерин дар гузоришҳои Fluentd пайдо мешаванд:

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" 

Ин паём ба кори система ба ҳеҷ ваҷҳ таъсир намерасонад ва маънои онро дорад, ки вақти шустакунии буфер назар ба параметри slow_flush_log_threshold муқарраршуда зиёдтар гирифт. Ин маълумоти ислоҳи ислоҳот аст ва мо онро ҳангоми интихоби арзиши параметри request_timeout истифода мебарем.

Алгоритми умумии интихоб чунин аст:

  1. request_timeout -ро ба арзише таъин кунед, ки кафолат дода мешавад, ки аз зарурӣ зиёдтар бошад (садҳо сония). Ҳангоми насб, меъёри асосии танзими дурусти ин параметр аз байн рафтани огоҳиҳо дар бораи набудани вақт мебошад.
  2. Интизор шавед, ки паёмҳо дар бораи гузаштан аз ҳадди slow_flush_log_threshold. Матни огоҳӣ дар майдони elapsed_time вақти воқеии тоза кардани буферро нишон медиҳад.
  3. request_timeout-ро ба қимате аз арзиши максималии гузашта_вақти дар давраи мушоҳида гирифташуда таъин кунед. Мо арзиши request_timeout -ро ҳамчун гузашти_вақт + 50% ҳисоб мекунем.
  4. Барои нест кардани огоҳиҳо дар бораи флешҳои буферии тӯлонӣ аз сабт, шумо метавонед арзиши slow_flush_log_threshold-ро баланд кунед. Мо ин арзишро ҳамчун вақти гузашта + 25% ҳисоб мекунем.

Арзиши ниҳоии ин параметрҳо, тавре ки дар боло қайд карда шуд, барои ҳар як ҳолат алоҳида гирифта мешаванд. Бо риояи алгоритми дар боло зикршуда, мо кафолат медиҳем, ки хатогиеро, ки ба паёмҳои такрорӣ оварда мерасонад, бартараф кунем.

Дар ҷадвали зер нишон дода шудааст, ки чӣ гуна шумораи хатогиҳо дар як рӯз, ки ба такрори паёмҳо оварда мерасонанд, дар раванди интихоби арзишҳои параметрҳои дар боло тавсифшуда тағир меёбанд:

гиреҳ-1
гиреҳ-2
гиреҳ-3
гиреҳ-4

Пеш аз пас
Пеш аз пас
Пеш аз пас
Пеш аз пас

буферро тоза карда натавонист
1749/2
694/2
47/0
1121/2

кӯшиши дубора муваффақ шуд
410/2
205/1
24/0
241/2

Илова бар ин, бояд қайд кард, ки танзимоти натиҷавӣ метавонанд аҳамияти худро гум кунанд, зеро лоиҳа афзоиш меёбад ва мувофиқан шумораи гузоришҳо меафзояд. Аломати аввалиндараҷаи вақти нокифоя баргардонидани паёмҳо дар бораи флеши буферии тӯлонӣ ба сабти Fluentd мебошад, яъне аз ҳадди ҳадди ақали slow_flush_log_olgun. Аз ин лаҳза, то аз ҳад гузаштани параметри request_timeout ҳанӯз маржаи хурд вуҷуд дорад, бинобар ин, ба ин паёмҳо сари вақт посух додан ва раванди интихоби танзимоти оптималии дар боло тавсифшударо такрор кардан лозим аст.

хулоса

Танзими дақиқи буфери баромади Fluentd яке аз марҳилаҳои асосии конфигуратсияи стеки EFK, муайян кардани устувории кори он ва ҷойгиркунии дурусти ҳуҷҷатҳо дар индексҳо мебошад. Дар асоси алгоритми конфигуратсияи тавсифшуда, шумо метавонед боварӣ дошта бошед, ки ҳама гузоришҳо ба индекси ElasticSearch бо тартиби дуруст, бидуни такрор ё талафот навишта мешаванд.

Инчунин мақолаҳои дигарро дар блоги мо хонед:

Манбаъ: will.com

Илова Эзоҳ