Fluentd: Эмне үчүн чыгаруу буферин конфигурациялоо маанилүү?

Fluentd: Эмне үчүн чыгаруу буферин конфигурациялоо маанилүү?

Бүгүнкү күндө Кубернетеске негизделген долбоорду ELK стексиз элестетүү мүмкүн эмес, ал колдонмолордун да, кластердин системалык компоненттеринин да журналдарын сактайт. Биздин практикада биз Logstashтын ордуна Fluentd менен EFK стекин колдонобуз.

Fluentd - бул барган сайын популярдуулукка ээ болгон жана Cloud Native Computing Фондуна кошулган заманбап, универсалдуу журнал коллектору, ошондуктан анын өнүгүү вектору Kubernetes менен бирге колдонууга багытталган.

Logstash ордуна Fluentd колдонуу фактысы программалык пакеттин жалпы маңызын өзгөртпөйт, бирок Fluentd анын ар тараптуулугунан келип чыккан өзүнүн өзгөчө нюанстары менен мүнөздөлөт.

Мисалы, биз EFKди логистиканын жогорку интенсивдүүлүгү менен алек болгон долбоордо колдоно баштаганыбызда, Кибанада кээ бир билдирүүлөр бир нече жолу кайталанып турганына туш болдук. Бул макалада биз бул көрүнүш эмне үчүн пайда жана көйгөйдү чечүү үчүн айтып берет.

Документти кайталоо маселеси

Биздин долбоорлордо Fluentd DaemonSet катары орнотулган (Кубернетес кластеринин ар бир түйүнүндө автоматтык түрдө бир инстанцияда ишке киргизилген) жана /var/log/containers ичиндеги stdout контейнер журналдарын көзөмөлдөйт. Чогултулгандан жана иштетилгенден кийин JSON документтери түрүндөгү журналдар долбоордун масштабына жана аткаруу жана катачылыкка чыдамкайлыкка карата талаптарга жараша кластердик же өз алдынча формада көтөрүлгөн ElasticSearchке жөнөтүлөт. Кибана графикалык интерфейс катары колдонулат.

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 босогосунан ашкандыгы тууралуу билдирүүлөрдү күтүңүз. Өткөн_убакыт талаасындагы эскертүү тексти буфер тазаланган реалдуу убакытты көрсөтөт.
  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_threshold босогосунан ашып кетүү. Ушул учурдан тартып, request_timeout параметринен ашканга чейин дагы эле кичинекей маржа бар, ошондуктан бул билдирүүлөргө өз убагында жооп берүү жана жогоруда сүрөттөлгөн оптималдуу орнотууларды тандоо процессин кайталоо керек.

жыйынтыктоо

Fluentd чыгаруу буферин так жөндөө - EFK стектерин конфигурациялоонун, анын иштешинин туруктуулугун аныктоонун жана документтердин индекстерде туура жайгаштырылышынын негизги этаптарынын бири. Сүрөттөлгөн конфигурация алгоритминин негизинде сиз бардык журналдар ElasticSearch индексине туура тартипте, кайталанууларсыз жана жоготууларсыз жазылаарына ишене аласыз.

Биздин блогдогу башка макалаларды да окуңуз:

Source: www.habr.com

Комментарий кошуу