Rhugl: Pam mae'n bwysig ffurfweddu'r byffer allbwn

Rhugl: Pam mae'n bwysig ffurfweddu'r byffer allbwn

Y dyddiau hyn, mae'n amhosibl dychmygu prosiect yn seiliedig ar Kubernetes heb y pentwr ELK, sy'n arbed logiau o gymwysiadau a chydrannau system y clwstwr. Yn ein harfer, rydym yn defnyddio'r pentwr EFK gyda Fluentd yn lle Logstash.

Mae Fluentd yn gasglwr logiau modern, cyffredinol sy'n dod yn fwyfwy poblogaidd ac mae wedi ymuno â'r Cloud Native Computing Foundation, a dyna pam mae ei fector datblygu yn canolbwyntio ar ddefnydd ar y cyd â Kubernetes.

Nid yw'r ffaith defnyddio Fluentd yn lle Logstash yn newid hanfod cyffredinol y pecyn meddalwedd, fodd bynnag, nodweddir Fluentd gan ei naws penodol ei hun sy'n deillio o'i amlochredd.

Er enghraifft, pan ddechreuon ni ddefnyddio EFK mewn prosiect prysur gyda lefel uchel o logio, roeddem yn wynebu'r ffaith bod rhai negeseuon yn Kibana yn cael eu harddangos dro ar ôl tro sawl gwaith. Yn yr erthygl hon byddwn yn dweud wrthych pam mae'r ffenomen hon yn digwydd a sut i ddatrys y broblem.

Y broblem o ddyblygu dogfennau

Yn ein prosiectau, mae Fluentd yn cael ei ddefnyddio fel DaemonSet (a lansiwyd yn awtomatig mewn un achos ar bob nod o glwstwr Kubernetes) ac mae'n monitro logiau cynwysyddion stdout yn /var/log/containers. Ar ôl casglu a phrosesu, anfonir y logiau ar ffurf dogfennau JSON i ElasticSearch, wedi'u codi ar ffurf clwstwr neu arunig, yn dibynnu ar faint y prosiect a'r gofynion ar gyfer perfformiad a goddefgarwch namau. Defnyddir Kibana fel y rhyngwyneb graffigol.

Wrth ddefnyddio Fluentd gydag ategyn byffro allbwn, daethom ar draws sefyllfa lle'r oedd gan rai dogfennau yn ElasticSearch yr un cynnwys yn union ac yn wahanol yn y dynodwr yn unig. Gallwch wirio mai ailadrodd neges yw hwn gan ddefnyddio log Nginx fel enghraifft. Yn y ffeil log, mae'r neges hon yn bodoli mewn un copi:

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

Fodd bynnag, mae sawl dogfen yn ElasticSearch sy'n cynnwys y neges hon:

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

Ar ben hynny, gall fod mwy na dau ailadrodd.

Wrth drwsio'r broblem hon yn y logiau Fluentd, gallwch weld nifer fawr o rybuddion gyda'r cynnwys canlynol:

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"

Mae'r rhybuddion hyn yn digwydd pan na all ElasticSearch ddychwelyd ymateb i gais o fewn yr amser a nodir gan y paramedr request_timeout, a dyna pam na ellir clirio'r darn byffer a anfonwyd ymlaen. Ar ôl hyn, mae Fluentd yn ceisio anfon y darn byffer i ElasticSearch eto ac ar ôl nifer mympwyol o ymdrechion, mae'r llawdriniaeth yn cwblhau'n llwyddiannus:

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"

Fodd bynnag, mae ElasticSearch yn trin pob un o'r darnau byffer a drosglwyddwyd fel rhai unigryw ac yn aseinio gwerthoedd maes _id unigryw iddynt yn ystod mynegeio. Dyma sut mae copïau o negeseuon yn ymddangos.

Yn Kibana mae'n edrych fel hyn:

Rhugl: Pam mae'n bwysig ffurfweddu'r byffer allbwn

Yr ateb

Mae yna nifer o opsiynau i ddatrys y broblem hon. Un ohonynt yw'r mecanwaith sydd wedi'i ymgorffori yn yr ategyn rhugl-plugin-elasticsearch ar gyfer cynhyrchu stwnsh unigryw ar gyfer pob dogfen. Os ydych chi'n defnyddio'r mecanwaith hwn, bydd ElasticSearch yn cydnabod ailadroddiadau yn y cam anfon ymlaen ac yn atal dogfennau dyblyg. Ond rhaid inni gymryd i ystyriaeth bod y dull hwn o ddatrys y broblem yn cael trafferth gyda'r ymchwiliad ac nid yw'n dileu'r gwall gyda diffyg amser, felly fe wnaethom roi'r gorau i'w ddefnyddio.

Rydym yn defnyddio ategyn byffro ar yr allbwn rhugl i atal colli boncyff mewn achos o broblemau rhwydwaith tymor byr neu gynnydd mewn dwysedd logio. Os nad yw ElasticSearch yn gallu ysgrifennu dogfen ar unwaith i'r mynegai am ryw reswm, mae'r ddogfen yn cael ei ciwio a'i storio ar ddisg. Felly, yn ein hachos ni, er mwyn dileu ffynhonnell y broblem sy'n arwain at y gwall a ddisgrifir uchod, mae angen gosod y gwerthoedd cywir ar gyfer y paramedrau byffro, lle bydd y byffer allbwn Fluentd o faint digonol a ar yr un pryd yn llwyddo i gael eu clirio yn yr amser penodedig.

Mae'n werth nodi bod gwerthoedd y paramedrau a drafodir isod yn unigol ym mhob achos penodol o ddefnyddio byffro mewn ategion allbwn, gan eu bod yn dibynnu ar lawer o ffactorau: dwyster ysgrifennu negeseuon i'r log gan wasanaethau, perfformiad system ddisg, rhwydwaith llwyth sianel a'i lled band. Felly, er mwyn cael gosodiadau byffer sy'n addas ar gyfer pob achos unigol, ond heb fod yn ddiangen, gan osgoi chwiliadau hir yn ddall, gallwch ddefnyddio'r wybodaeth dadfygio y mae Fluentd yn ei ysgrifennu at ei log yn ystod y llawdriniaeth a chael y gwerthoedd cywir yn gymharol gyflym.

Ar yr adeg y cofnodwyd y broblem, roedd y ffurfweddiad yn edrych fel hyn:

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

Wrth ddatrys y broblem, dewiswyd gwerthoedd y paramedrau canlynol â llaw:
chunk_limit_size — maint y talpiau y mae negeseuon yn y byffer wedi'u rhannu iddynt.

  • flush_interval — cyfnod amser ar ôl hynny bydd y byffer yn cael ei glirio.
  • queue_limit_length — y nifer uchaf o dalpiau yn y ciw.
  • request_timeout yw'r amser y mae'r cysylltiad rhwng Fluentd ac ElasticSearch wedi'i sefydlu ar ei gyfer.

Gellir cyfrifo cyfanswm maint y byffer trwy luosi’r paramedrau queue_limit_length a chunk_limit_size, y gellir eu dehongli fel “nifer uchaf y talpiau yn y ciw, y mae gan bob un ohonynt faint penodol.” Os yw maint y byffer yn annigonol, bydd y rhybudd canlynol yn ymddangos yn y logiau:

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

Mae'n golygu nad oes gan y byffer amser i'w glirio yn yr amser a neilltuwyd ac mae'r data sy'n mynd i mewn i'r byffer llawn yn cael ei rwystro, a fydd yn arwain at golli rhan o'r logiau.

Gallwch gynyddu'r byffer mewn dwy ffordd: trwy gynyddu naill ai maint pob talp yn y ciw, neu nifer y talpiau a all fod yn y ciw.

Os ydych chi'n gosod maint y talp chunk_limit_size i fwy na 32 megabeit, yna ni fydd ElasticSeacrh yn ei dderbyn, gan y bydd y pecyn sy'n dod i mewn yn rhy fawr. Felly, os oes angen i chi gynyddu'r byffer ymhellach, mae'n well cynyddu hyd y ciw uchaf queue_limit_length.

Pan fydd y byffer yn stopio gorlifo a dim ond neges annigonol y terfyn amser ar ôl, gallwch chi ddechrau cynyddu'r paramedr request_timeout. Fodd bynnag, os byddwch yn gosod y gwerth i fwy nag 20 eiliad, bydd y rhybuddion canlynol yn dechrau ymddangos yn y logiau rhugl:

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" 

Nid yw'r neges hon yn effeithio ar weithrediad y system mewn unrhyw ffordd ac mae'n golygu bod yr amser fflysio byffer wedi cymryd mwy o amser na'r hyn a osodwyd gan y paramedr slow_flush_log_threshold. Gwybodaeth dadfygio yw hon ac rydym yn ei defnyddio wrth ddewis gwerth y paramedr request_timeout.

Mae'r algorithm dewis cyffredinol fel a ganlyn:

  1. Gosod request_timeout i werth sy'n sicr o fod yn fwy na'r angen (cannoedd o eiliadau). Yn ystod y gosodiad, y prif faen prawf ar gyfer gosod y paramedr hwn yn gywir fydd diflaniad rhybuddion am ddiffyg terfyn amser.
  2. Arhoswch am negeseuon am fynd dros y trothwy slow_flush_log_threshold. Bydd y testun rhybudd yn y maes elapsed_time yn dangos yr amser real y cliriwyd y byffer.
  3. Gosod request_timeout i werth sy'n fwy na'r uchafswm gwerth amser a aeth heibio a gafwyd yn ystod y cyfnod arsylwi. Rydym yn cyfrifo'r gwerth request_timeout fel wedi mynd heibio_time + 50%.
  4. I dynnu rhybuddion am llaciau byffer hir o'r log, gallwch godi gwerth slow_flush_log_threshold. Rydyn ni'n cyfrifo'r gwerth hwn fel 'exapsed_time + 25%.

Ceir gwerthoedd terfynol y paramedrau hyn, fel y nodwyd yn gynharach, yn unigol ar gyfer pob achos. Trwy ddilyn yr algorithm uchod, rydym yn sicr o ddileu'r gwall sy'n arwain at negeseuon dro ar ôl tro.

Mae'r tabl isod yn dangos sut mae nifer y gwallau y dydd, gan arwain at ddyblygu negeseuon, newidiadau yn y broses o ddewis gwerthoedd y paramedrau a ddisgrifir uchod:

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

Cyn Ar ol
Cyn Ar ol
Cyn Ar ol
Cyn Ar ol

wedi methu â fflysio'r byffer
1749/2
694/2
47/0
1121/2

ail geisio llwyddo
410/2
205/1
24/0
241/2

Mae'n werth nodi hefyd y gallai'r gosodiadau canlyniadol golli eu perthnasedd wrth i'r prosiect dyfu ac, yn unol â hynny, mae nifer y boncyffion yn cynyddu. Prif arwydd terfyn amser annigonol yw dychwelyd negeseuon am fflysh byffer hir i'r log Rhugl, hynny yw, yn mynd dros y trothwy slow_flush_log_threshold. O'r pwynt hwn ymlaen, mae yna ymyl bach o hyd cyn mynd y tu hwnt i'r paramedr request_timeout, felly mae angen ymateb i'r negeseuon hyn yn amserol ac ailadrodd y broses o ddewis y gosodiadau gorau posibl a ddisgrifir uchod.

Casgliad

Cywiro'r byffer allbwn Fluentd yw un o'r prif gamau wrth ffurfweddu'r pentwr EFK, gan bennu sefydlogrwydd ei weithrediad a lleoliad cywir dogfennau mewn mynegeion. Yn seiliedig ar yr algorithm cyfluniad a ddisgrifir, gallwch fod yn sicr y bydd yr holl logiau'n cael eu hysgrifennu i'r mynegai ElasticSearch yn y drefn gywir, heb ailadrodd na cholledion.

Darllenwch erthyglau eraill ar ein blog hefyd:

Ffynhonnell: hab.com

Ychwanegu sylw