Fluentd: Гаралтын буферийг тохируулах нь яагаад чухал вэ?

Fluentd: Гаралтын буферийг тохируулах нь яагаад чухал вэ?

Өнөө үед Кубернетес дээр суурилсан төслийг ELK стекгүйгээр төсөөлөхийн аргагүй бөгөөд энэ нь кластерын програмууд болон системийн бүрэлдэхүүн хэсгүүдийн бүртгэлийг хадгалдаг. Манай практикт бид Logstash-ийн оронд Fluentd-тэй EFK стекийг ашигладаг.

Fluentd бол орчин үеийн, бүх нийтийн лог цуглуулагч бөгөөд улам бүр түгээмэл болж, Cloud Native Computing Foundation-д элссэн тул түүний хөгжлийн векторыг Kubernetes-тэй хамтран ашиглахад чиглэв.

Logstash-ийн оронд Fluentd-ийг ашиглах нь програм хангамжийн багцын ерөнхий мөн чанарыг өөрчилдөггүй боловч Fluentd нь олон талт байдлаас үүдэлтэй өөрийн өвөрмөц онцлог шинж чанартай байдаг.

Жишээлбэл, бид мод бэлтгэлийн өндөр эрчимтэй завгүй төсөлд EFK-г ашиглаж эхлэхэд Кибана хотод зарим мессежүүд хэд хэдэн удаа гарч ирдэг гэсэн асуудалтай тулгарсан. Энэ нийтлэлд бид энэ үзэгдэл яагаад тохиолддог, асуудлыг хэрхэн шийдвэрлэх талаар танд хэлэх болно.

Баримт бичгийн давхардлын асуудал

Манай төслүүдэд Fluentd нь DaemonSet (Kubernetes кластерын зангилаа бүр дээр автоматаар нэг тохиолдлоор эхлүүлсэн) хэлбэрээр байрлуулсан бөгөөд /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 үүнийг хүлээн авахгүй, учир нь ирж буй пакет хэт том байх болно. Тиймээс, хэрэв та буферийг цаашид нэмэгдүүлэх шаардлагатай бол дарааллын хамгийн их уртын дарааллын_хязгаар_уртыг нэмэгдүүлэх нь дээр.

Буфер дүүрэхээ больж, зөвхөн хугацаа хэтэрсэн мессеж л үлдэх үед та 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. Удаан_угаах_лог_босгыг давсан тухай мессежийг хүлээнэ үү. Өнгөрсөн_цаг хугацааны талбар дахь анхааруулах текст нь буфер арилсан бодит цагийг харуулах болно.
  3. Хүсэлт_хугацааг ажиглалтын хугацаанд олж авсан хамгийн их зарцуулсан_цаг хугацааны утгаас их болгож тохируулна уу. Бид хүсэлтийн_цаг хугацаа + 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 бүртгэл рүү буферийн урт зайлах тухай мессежийг буцаах, өөрөөр хэлбэл, удаашруулах_логийн_босгыг давах явдал юм. Энэ мөчөөс эхлэн request_timeout параметрийг хэтрүүлэхээс өмнө бага зэрэг зөрүүтэй хэвээр байгаа тул эдгээр мессежүүдэд цаг тухайд нь хариу өгч, дээр дурдсан оновчтой тохиргоог сонгох үйл явцыг давтах шаардлагатай байна.

дүгнэлт

Fluentd гаралтын буферийг нарийн тохируулах нь EFK стекийг тохируулах, түүний үйл ажиллагааны тогтвортой байдал, баримт бичгийг индекст зөв байрлуулах үндсэн үе шатуудын нэг юм. Тайлбарласан тохиргооны алгоритм дээр үндэслэн бүх бүртгэлийг ElasticSearch индекс рүү зөв дарааллаар, давталт, алдагдалгүйгээр бичих болно гэдэгт итгэлтэй байж болно.

Мөн манай блог дээрх бусад нийтлэлүүдийг уншина уу:

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх