Fluentd: Nə üçün çıxış buferini konfiqurasiya etmək vacibdir?

Fluentd: Nə üçün çıxış buferini konfiqurasiya etmək vacibdir?

Bu gün Kubernetes əsaslı layihəni həm tətbiqlərin, həm də klasterin sistem komponentlərinin qeydlərini saxlayan ELK yığını olmadan təsəvvür etmək mümkün deyil. Təcrübəmizdə Logstash əvəzinə Fluentd ilə EFK stekindən istifadə edirik.

Fluentd getdikcə daha çox populyarlıq qazanan və Bulud Native Computing Fonduna qoşulan müasir, universal log kollektorudur, buna görə də onun inkişaf vektoru Kubernetes ilə birlikdə istifadəyə yönəlib.

Logstash əvəzinə Fluentd-dən istifadə faktı proqram paketinin ümumi mahiyyətini dəyişmir, lakin Fluentd çox yönlü olmasından irəli gələn özünəməxsus nüansları ilə xarakterizə olunur.

Məsələn, biz EFK-dan girişin yüksək intensivliyi ilə məşğul olan layihədə istifadə etməyə başladıqda, Kibana-da bəzi mesajların bir neçə dəfə təkrar-təkrar nümayiş olunması ilə qarşılaşdıq. Bu yazıda bu fenomenin niyə baş verdiyini və problemi necə həll edəcəyinizi sizə xəbər verəcəyik.

Sənədlərin təkrarlanması problemi

Layihələrimizdə Fluentd DaemonSet kimi yerləşdirilir (Avtomatik olaraq Kubernetes klasterinin hər qovşağında bir instansiyada işə salınır) və /var/log/containers-də stdout konteyner qeydlərinə nəzarət edir. Yığıldıqdan və işləndikdən sonra JSON sənədləri formasındakı jurnallar layihənin miqyasından, performans və nasazlıqlara qarşı dözümlülük tələblərindən asılı olaraq klaster və ya müstəqil formada qaldırılan ElasticSearch-ə göndərilir. Kibana qrafik interfeys kimi istifadə olunur.

Fluentd-dən çıxış buferləmə plaqini ilə istifadə edərkən biz ElasticSearch-dəki bəzi sənədlərin tam olaraq eyni məzmuna malik olduğu və yalnız identifikatorda fərqləndiyi bir vəziyyətlə qarşılaşdıq. Nginx jurnalından nümunə olaraq istifadə edərək bunun bir mesaj təkrarı olduğunu yoxlaya bilərsiniz. Günlük faylında bu mesaj bir nüsxədə mövcuddur:

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

Bununla belə, ElasticSearch-də bu mesajı ehtiva edən bir neçə sənəd var:

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

Üstəlik, ikidən çox təkrar ola bilər.

Fluentd qeydlərində bu problemi həll edərkən siz aşağıdakı məzmunlu çoxlu sayda xəbərdarlıqları görə bilərsiniz:

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"

Bu xəbərdarlıqlar o zaman baş verir ki, ElasticSearch request_timeout parametri ilə müəyyən edilmiş vaxt ərzində sorğuya cavab qaytara bilmir, buna görə də yönləndirilmiş bufer fraqmenti silinə bilməz. Bundan sonra Fluentd bufer fraqmentini yenidən ElasticSearch-ə göndərməyə çalışır və ixtiyari sayda cəhddən sonra əməliyyat uğurla başa çatır:

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"

Bununla belə, ElasticSearch köçürülmüş bufer fraqmentlərinin hər birinə unikal kimi yanaşır və indeksləşdirmə zamanı onlara unikal _id sahəsi dəyərləri təyin edir. Mesajların surətləri belə görünür.

Kibanada belə görünür:

Fluentd: Nə üçün çıxış buferini konfiqurasiya etmək vacibdir?

Həlli

Bu problemi həll etmək üçün bir neçə variant var. Onlardan biri hər bir sənəd üçün unikal hash yaratmaq üçün fluent-plugin-elasticsearch plaginində quraşdırılmış mexanizmdir. Bu mexanizmdən istifadə etsəniz, ElasticSearch yönləndirmə mərhələsində təkrarları tanıyacaq və dublikat sənədlərin qarşısını alacaq. Ancaq nəzərə almalıyıq ki, problemin həlli üçün bu üsul araşdırma ilə mübarizə aparır və fasilənin olmaması ilə səhvi aradan qaldırmır, ona görə də onun istifadəsindən imtina etdik.

Qısa müddətli şəbəkə problemləri və ya giriş intensivliyinin artması halında log itkisinin qarşısını almaq üçün Fluentd çıxışında bufer plaqindən istifadə edirik. Əgər nədənsə ElasticSearch sənədi dərhal indeksə yaza bilmirsə, sənəd növbəyə qoyulur və diskdə saxlanılır. Buna görə də, bizim vəziyyətimizdə, yuxarıda təsvir edilən səhvə səbəb olan problemin mənbəyini aradan qaldırmaq üçün, Fluentd çıxış buferinin kifayət qədər ölçüdə olacağı və buferləmə parametrləri üçün düzgün dəyərlər təyin etmək lazımdır. eyni zamanda ayrılmış vaxtda təmizlənməyi bacarır.

Qeyd etmək lazımdır ki, aşağıda müzakirə olunan parametrlərin dəyərləri çıxış plaginlərində buferdən istifadənin hər bir konkret halda fərdidir, çünki onlar bir çox amillərdən asılıdır: xidmətlər tərəfindən jurnala mesaj yazma intensivliyi, disk sisteminin performansı, şəbəkə. kanal yükü və onun ötürmə qabiliyyəti. Buna görə də, hər bir fərdi hal üçün uyğun olan, lakin lazımsız olmayan, kor-koranə uzun axtarışlardan qaçan bufer parametrlərini əldə etmək üçün siz Fluentd-in əməliyyat zamanı jurnalına yazdığı sazlama məlumatından istifadə edə və düzgün dəyərləri nisbətən tez əldə edə bilərsiniz.

Problem qeydə alınarkən konfiqurasiya belə görünürdü:

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

Problemi həll edərkən aşağıdakı parametrlərin dəyərləri əl ilə seçildi:
chunk_limit_size — buferdəki mesajların bölündüyü parçaların ölçüsü.

  • flush_interval — buferin təmizləndiyi vaxt intervalı.
  • queue_limit_length — növbədəki parçaların maksimum sayı.
  • request_timeout Fluentd və ElasticSearch arasında əlaqənin qurulduğu vaxtdır.

Buferin ümumi ölçüsü növbə_limit_length və chunk_limit_size parametrlərini vurmaqla hesablana bilər ki, bu da "növbədə hər biri müəyyən ölçüyə malik olan parçaların maksimum sayı" kimi şərh edilə bilər. Bufer ölçüsü kifayət deyilsə, qeydlərdə aşağıdakı xəbərdarlıq görünəcək:

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

Bu o deməkdir ki, buferin ayrılmış vaxtda təmizlənməsi üçün vaxt yoxdur və tam buferə daxil olan məlumat bloklanır, bu da qeydlərin bir hissəsinin itirilməsinə səbəb olacaqdır.

Buferi iki yolla artıra bilərsiniz: ya növbədəki hər bir parçanın ölçüsünü, ya da növbədə ola biləcək parçaların sayını artırmaqla.

Əgər chunk_limit_size ölçüsünü 32 meqabaytdan çox təyin etsəniz, ElasticSeacrh onu qəbul etməyəcək, çünki daxil olan paket çox böyük olacaq. Buna görə də, buferi daha da artırmaq lazımdırsa, maksimum növbə uzunluğunu queue_limit_length artırmaq daha yaxşıdır.

Bufer daşmağı dayandırdıqda və yalnız vaxt aşımı qeyri-kafi mesajı qaldıqda, request_timeout parametrini artırmağa başlaya bilərsiniz. Bununla belə, dəyəri 20 saniyədən çox təyin etsəniz, Fluentd qeydlərində aşağıdakı xəbərdarlıqlar görünməyə başlayacaq:

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" 

Bu mesaj heç bir şəkildə sistemin işinə təsir göstərmir və o deməkdir ki, buferin yuyulma müddəti slow_flush_log_threshold parametri ilə təyin olunandan daha uzun çəkib. Bu, sazlama məlumatıdır və biz ondan request_timeout parametrinin dəyərini seçərkən istifadə edirik.

Ümumiləşdirilmiş seçim alqoritmi aşağıdakı kimidir:

  1. request_timeout parametrini lazım olandan daha böyük olacağına zəmanət verilən dəyərə təyin edin (yüzlərlə saniyə). Quraşdırma zamanı bu parametrin düzgün qurulmasının əsas meyarı, fasilənin olmaması üçün xəbərdarlıqların yox olması olacaq.
  2. slow_flush_log_threshold həddini keçmək barədə mesajları gözləyin. Keçən_zaman sahəsindəki xəbərdarlıq mətni buferin təmizləndiyi real vaxtı göstərəcək.
  3. Müşahidə müddəti ərzində əldə edilmiş maksimum keçən_zaman dəyərindən daha böyük bir dəyər üçün sorğu_vaxt aşımı təyin edin. Biz sorğu_vaxtının dəyərini keçən_zaman + 50% kimi hesablayırıq.
  4. Jurnaldan uzun bufer silmələri ilə bağlı xəbərdarlıqları silmək üçün siz slow_flush_log_threshold dəyərini artıra bilərsiniz. Bu dəyəri keçən_zaman + 25% kimi hesablayırıq.

Bu parametrlərin son dəyərləri, əvvəllər qeyd edildiyi kimi, hər bir hal üçün fərdi olaraq alınır. Yuxarıda göstərilən alqoritmə əməl etməklə, təkrar mesajlara səbəb olan xətanı aradan qaldıracağımıza zəmanət verilir.

Aşağıdakı cədvəl, mesajların təkrarlanmasına səbəb olan gündə səhvlərin sayının, yuxarıda təsvir olunan parametrlərin dəyərlərinin seçilməsi prosesində necə dəyişdiyini göstərir:

qovşaq-1
qovşaq-2
qovşaq-3
qovşaq-4

Əvvəl sonra
Əvvəl sonra
Əvvəl sonra
Əvvəl sonra

tamponu yuya bilmədi
1749/2
694/2
47/0
1121/2

yenidən cəhd uğur qazandı
410/2
205/1
24/0
241/2

Əlavə olaraq qeyd etmək lazımdır ki, nəticədə yaranan parametrlər layihə böyüdükcə və müvafiq olaraq qeydlərin sayı artdıqca aktuallığını itirə bilər. Qeyri-kafi fasilənin əsas əlaməti Fluentd jurnalına uzun bufer flush haqqında mesajların qaytarılmasıdır, yəni slow_flush_log_threshold həddini aşmaqdır. Bu andan etibarən request_timeout parametri keçməzdən əvvəl hələ də kiçik bir marja var, buna görə də bu mesajlara vaxtında cavab vermək və yuxarıda təsvir edilən optimal parametrləri seçmək prosesini təkrarlamaq lazımdır.

Nəticə

Fluentd çıxış buferinin dəqiq tənzimlənməsi EFK steminin konfiqurasiyasının, onun işləməsinin sabitliyinin və sənədlərin indekslərdə düzgün yerləşdirilməsinin müəyyən edilməsinin əsas mərhələlərindən biridir. Təsvir edilən konfiqurasiya alqoritmi əsasında əmin ola bilərsiniz ki, bütün jurnallar ElasticSearch indeksinə düzgün ardıcıllıqla, təkrarlar və itkilər olmadan yazılacaq.

Bloqumuzdakı digər məqalələri də oxuyun:

Mənbə: www.habr.com

Добавить комментарий