Fluentd: Mengapa penting untuk mengkonfigurasi penimbal output

Fluentd: Mengapa penting untuk mengkonfigurasi penimbal output

Pada masa kini, adalah mustahil untuk membayangkan projek berasaskan Kubernetes tanpa tindanan ELK, yang menyimpan log kedua-dua aplikasi dan komponen sistem kluster. Dalam amalan kami, kami menggunakan timbunan EFK dengan Fluentd dan bukannya Logstash.

Fluentd ialah pengumpul log moden dan universal yang semakin popular dan telah menyertai Yayasan Pengkomputeran Asli Awan, itulah sebabnya vektor pembangunannya tertumpu pada penggunaan bersama Kubernetes.

Fakta menggunakan Fluentd dan bukannya Logstash tidak mengubah intipati umum pakej perisian, bagaimanapun, Fluentd dicirikan oleh nuansa khususnya sendiri yang terhasil daripada serba boleh.

Sebagai contoh, apabila kami mula menggunakan EFK dalam projek yang sibuk dengan intensiti pembalakan yang tinggi, kami berhadapan dengan fakta bahawa di Kibana beberapa mesej dipaparkan berulang kali beberapa kali. Dalam artikel ini kami akan memberitahu anda mengapa fenomena ini berlaku dan bagaimana untuk menyelesaikan masalah tersebut.

Masalah pertindihan dokumen

Dalam projek kami, Fluentd digunakan sebagai DaemonSet (dilancarkan secara automatik dalam satu contoh pada setiap nod gugusan Kubernetes) dan memantau log kontena stdout dalam /var/log/containers. Selepas pengumpulan dan pemprosesan, log dalam bentuk dokumen JSON dihantar ke ElasticSearch, dibangkitkan dalam bentuk kelompok atau kendiri, bergantung pada skala projek dan keperluan untuk prestasi dan toleransi kesalahan. Kibana digunakan sebagai antara muka grafik.

Apabila menggunakan Fluentd dengan pemalam penimbalan output, kami menghadapi situasi di mana beberapa dokumen dalam ElasticSearch mempunyai kandungan yang sama dan hanya berbeza dalam pengecam. Anda boleh mengesahkan bahawa ini adalah pengulangan mesej menggunakan log Nginx sebagai contoh. Dalam fail log, mesej ini wujud dalam satu salinan:

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

Walau bagaimanapun, terdapat beberapa dokumen dalam ElasticSearch yang mengandungi mesej ini:

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

Lebih-lebih lagi, boleh ada lebih daripada dua ulangan.

Semasa membetulkan masalah ini dalam log Fluentd, anda boleh melihat sejumlah besar amaran dengan kandungan berikut:

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"

Amaran ini berlaku apabila ElasticSearch tidak dapat mengembalikan respons kepada permintaan dalam masa yang ditentukan oleh parameter request_timeout, itulah sebabnya serpihan penimbal yang dimajukan tidak boleh dikosongkan. Selepas ini, Fluentd cuba menghantar serpihan penimbal kepada ElasticSearch sekali lagi dan selepas beberapa percubaan sewenang-wenangnya, operasi berjaya diselesaikan:

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"

Walau bagaimanapun, ElasticSearch menganggap setiap serpihan penimbal yang dipindahkan sebagai unik dan memberikannya nilai medan _id unik semasa pengindeksan. Beginilah cara salinan mesej muncul.

Di Kibana ia kelihatan seperti ini:

Fluentd: Mengapa penting untuk mengkonfigurasi penimbal output

Penyelesaian

Terdapat beberapa pilihan untuk menyelesaikan masalah ini. Salah satunya ialah mekanisme terbina dalam pemalam fluent-plugin-elasticsearch untuk menjana cincang unik untuk setiap dokumen. Jika anda menggunakan mekanisme ini, ElasticSearch akan mengenali ulangan pada peringkat pemajuan dan menghalang dokumen pendua. Tetapi kita mesti mengambil kira bahawa kaedah menyelesaikan masalah ini bergelut dengan penyiasatan dan tidak menghapuskan ralat dengan kekurangan masa tamat, jadi kami meninggalkan penggunaannya.

Kami menggunakan pemalam penimbalan pada output Fluentd untuk mengelakkan kehilangan log sekiranya berlaku masalah rangkaian jangka pendek atau peningkatan intensiti pembalakan. Jika atas sebab tertentu ElasticSearch tidak dapat menulis dokumen dengan serta-merta ke indeks, dokumen itu akan beratur dan disimpan pada cakera. Oleh itu, dalam kes kami, untuk menghapuskan punca masalah yang membawa kepada ralat yang diterangkan di atas, adalah perlu untuk menetapkan nilai yang betul untuk parameter penimbalan, di mana penimbal keluaran Fluentd akan mempunyai saiz yang mencukupi dan pada masa yang sama berjaya dibersihkan dalam masa yang ditetapkan.

Perlu diingat bahawa nilai parameter yang dibincangkan di bawah adalah individu dalam setiap kes khusus menggunakan penimbal dalam pemalam keluaran, kerana ia bergantung kepada banyak faktor: keamatan menulis mesej ke perkhidmatan log mengikut, prestasi sistem cakera, rangkaian beban saluran dan lebar jalurnya. Oleh itu, untuk mendapatkan tetapan penimbal yang sesuai untuk setiap kes individu, tetapi tidak berlebihan, mengelakkan carian yang panjang secara membuta tuli, anda boleh menggunakan maklumat penyahpepijatan yang Fluentd tulis pada lognya semasa operasi dan memperoleh nilai yang betul secara relatifnya.

Pada masa masalah direkodkan, konfigurasi kelihatan seperti ini:

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

Apabila menyelesaikan masalah, nilai parameter berikut dipilih secara manual:
chunk_limit_size β€” saiz ketulan di mana mesej dalam penimbal dibahagikan.

  • flush_interval β€” selang masa selepas itu penimbal dikosongkan.
  • queue_limit_length β€” bilangan maksimum ketulan dalam baris gilir.
  • request_timeout ialah masa sambungan antara Fluentd dan ElasticSearch diwujudkan.

Jumlah saiz penimbal boleh dikira dengan mendarabkan parameter queue_limit_length dan chunk_limit_size, yang boleh ditafsirkan sebagai "bilangan maksimum ketulan dalam baris gilir, setiap satunya mempunyai saiz tertentu." Jika saiz penimbal tidak mencukupi, amaran berikut akan muncul dalam log:

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

Ini bermakna penimbal tidak mempunyai masa untuk dibersihkan dalam masa yang diperuntukkan dan data yang memasuki penimbal penuh disekat, yang akan menyebabkan kehilangan sebahagian daripada log.

Anda boleh meningkatkan penimbal dalam dua cara: dengan meningkatkan sama ada saiz setiap bahagian dalam baris gilir, atau bilangan ketulan yang boleh berada dalam baris gilir.

Jika anda menetapkan saiz chunk_limit_size kepada lebih daripada 32 megabait, maka ElasticSeacrh tidak akan menerimanya, kerana paket yang masuk akan terlalu besar. Oleh itu, jika anda perlu meningkatkan lagi penimbal, adalah lebih baik untuk meningkatkan panjang giliran maksimum queue_limit_length.

Apabila penimbal berhenti melimpah dan hanya tinggal mesej tamat masa yang tidak mencukupi, anda boleh mula meningkatkan parameter request_timeout. Walau bagaimanapun, jika anda menetapkan nilai kepada lebih daripada 20 saat, amaran berikut akan mula muncul dalam log 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" 

Mesej ini tidak menjejaskan pengendalian sistem dalam apa jua cara dan bermakna masa siram penimbal mengambil masa lebih lama daripada yang ditetapkan oleh parameter slow_flush_log_threshold. Ini ialah maklumat penyahpepijatan dan kami menggunakannya apabila memilih nilai parameter request_timeout.

Algoritma pemilihan umum adalah seperti berikut:

  1. Tetapkan request_timeout kepada nilai yang dijamin lebih besar daripada yang diperlukan (beratus-ratus saat). Semasa persediaan, kriteria utama untuk tetapan yang betul bagi parameter ini ialah kehilangan amaran kerana kekurangan tamat masa.
  2. Tunggu mesej tentang melebihi ambang slow_flush_log_threshold. Teks amaran dalam medan elapsed_time akan menunjukkan masa sebenar penimbal telah dikosongkan.
  3. Tetapkan request_timeout kepada nilai yang lebih besar daripada nilai elapsed_time maksimum yang diperoleh semasa tempoh pemerhatian. Kami mengira nilai request_timeout sebagai elapsed_time + 50%.
  4. Untuk mengalih keluar amaran tentang pemadaman penimbal panjang daripada log, anda boleh meningkatkan nilai slow_flush_log_threshold. Kami mengira nilai ini sebagai elapsed_time + 25%.

Nilai akhir parameter ini, seperti yang dinyatakan sebelum ini, diperoleh secara individu untuk setiap kes. Dengan mengikuti algoritma di atas, kami dijamin untuk menghapuskan ralat yang membawa kepada mesej berulang.

Jadual di bawah menunjukkan bagaimana bilangan ralat setiap hari, yang membawa kepada pertindihan mesej, perubahan dalam proses memilih nilai parameter yang diterangkan di atas:

nod-1
nod-2
nod-3
nod-4

Sebelum selepas
Sebelum selepas
Sebelum selepas
Sebelum selepas

gagal menyiram penimbal
1749/2
694/2
47/0
1121/2

cuba semula berjaya
410/2
205/1
24/0
241/2

Perlu diingatkan juga bahawa tetapan yang terhasil mungkin kehilangan kaitannya apabila projek berkembang dan, dengan itu, bilangan log meningkat. Tanda utama tamat masa yang tidak mencukupi ialah pengembalian mesej tentang siram penimbal panjang ke log Fluentd, iaitu, melebihi ambang slow_flush_log_threshold. Mulai saat ini, masih terdapat margin kecil sebelum parameter request_timeout melebihi, jadi adalah perlu untuk membalas mesej ini tepat pada masanya dan mengulangi proses memilih tetapan optimum yang diterangkan di atas.

Kesimpulan

Penalaan halus penimbal keluaran Fluentd ialah salah satu peringkat utama mengkonfigurasi tindanan EFK, menentukan kestabilan operasinya dan penempatan dokumen yang betul dalam indeks. Berdasarkan algoritma konfigurasi yang diterangkan, anda boleh yakin bahawa semua log akan ditulis pada indeks ElasticSearch dalam susunan yang betul, tanpa pengulangan atau kerugian.

Baca juga artikel lain di blog kami:

Sumber: www.habr.com

Tambah komen