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 журналын пайдаланып, бұл хабардың қайталануы екенін тексеруге болады. Журнал файлында бұл хабар бір көшірмеде бар:
Бұл мәселені 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 сұрауға сұрау_timeout параметрімен көрсетілген уақыт ішінде жауапты қайтара алмағанда пайда болады, сондықтан қайта жіберілген буфер фрагментін тазалау мүмкін емес. Осыдан кейін Fluentd буфер фрагментін ElasticSearch қызметіне қайта жіберуге әрекеттенеді және ерікті санды әрекеттерден кейін операция сәтті аяқталады:
Дегенмен, ElasticSearch тасымалданатын буфер фрагменттерінің әрқайсысын бірегей ретінде қарастырады және индекстеу кезінде оларға бірегей _id өріс мәндерін тағайындайды. Хабарлардың көшірмелері осылай пайда болады.
Кибанада ол келесідей көрінеді:
сөйлеген сөзінде
Бұл мәселені шешудің бірнеше нұсқасы бар. Олардың бірі - әрбір құжат үшін бірегей хэшті құруға арналған fluent-plugin-elasticsearch плагиніне енгізілген механизм. Бұл механизмді пайдалансаңыз, ElasticSearch қайта жіберу сатысында қайталауларды таниды және қайталанатын құжаттардың алдын алады. Бірақ біз мәселені шешудің бұл әдісі тергеумен күресетінін және күту уақытының жетіспеушілігімен қатені жоймайтынын ескеруіміз керек, сондықтан біз оны пайдаланудан бас тарттық.
Қысқа мерзімді желі ақаулары немесе тіркеу қарқындылығы жоғарылаған жағдайда журналдың жоғалуын болдырмау үшін Fluentd шығысында буферлеу плагинін қолданамыз. Егер қандай да бір себептермен ElasticSearch құжатты индекске бірден жаза алмаса, құжат кезекке қойылады және дискіде сақталады. Сондықтан, біздің жағдайда, жоғарыда сипатталған қатеге әкелетін мәселенің көзін жою үшін, буферлеу параметрлері үшін дұрыс мәндерді орнату қажет, бұл кезде Fluentd шығыс буфері жеткілікті мөлшерде болады және бір мезгілде белгіленген уақытта тазартуға үлгереді.
Төменде талқыланған параметрлердің мәндері шығыс плагиндерінде буферлеуді пайдаланудың әрбір нақты жағдайында жеке болып табылатынын атап өткен жөн, өйткені олар көптеген факторларға байланысты: қызметтер бойынша журналға хабарламаларды жазу қарқындылығы, диск жүйесінің өнімділігі, желі арна жүктемесі және оның өткізу қабілеті. Сондықтан, әрбір жеке жағдайға сәйкес келетін, бірақ артық емес, ұзақ іздеулерді соқыр түрде болдырмайтын буфер параметрлерін алу үшін, жұмыс кезінде Fluentd журналына жазатын жөндеу ақпаратын пайдалануға және дұрыс мәндерді салыстырмалы түрде жылдам алуға болады.
Мәселе жазылған кезде конфигурация келесідей болды:
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 параметрінің мәнін таңдаған кезде пайдаланамыз.
Жалпылама таңдау алгоритмі келесідей:
request_timeout параметрін қажетті мәннен үлкенірек (жүздеген секунд) болатын мәнге орнатыңыз. Орнату кезінде осы параметрді дұрыс орнатудың негізгі критерийі күту уақытының болмауы туралы ескертулердің жоғалуы болады.
slow_flush_log_threshold шегінен асу туралы хабарларды күтіңіз. Өткен_уақыт өрісіндегі ескерту мәтіні буфер тазартылған нақты уақытты көрсетеді.
сұрау_уақыты параметрін бақылау кезеңінде алынған максималды өткен_уақыт мәнінен үлкен мәнге орнатыңыз. Біз сұрау_уақыты мәнін өткен_уақыт + 50% деп есептейміз.
Журналдан ұзақ буферді тазартулар туралы ескертулерді жою үшін 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 индексіне дұрыс ретпен қайталанусыз немесе жоғалтпай жазылатынына сенімді бола аласыз.
Сондай-ақ біздің блогтағы басқа мақалаларды оқыңыз: