కాఫ్కా ఎలా నిజమైంది

కాఫ్కా ఎలా నిజమైంది

హే హబ్ర్!

నేను Tinkoff టీమ్‌లో పని చేస్తున్నాను, ఇది దాని స్వంత నోటిఫికేషన్ కేంద్రాన్ని అభివృద్ధి చేస్తోంది. నేను ఎక్కువగా జావాలో స్ప్రింగ్ బూట్‌ని ఉపయోగించి అభివృద్ధి చేస్తాను మరియు ప్రాజెక్ట్‌లో తలెత్తే వివిధ సాంకేతిక సమస్యలను పరిష్కరిస్తాను.

మా మైక్రోసర్వీస్‌లు చాలా వరకు మెసేజ్ బ్రోకర్ ద్వారా ఒకదానితో ఒకటి అసమకాలికంగా సంభాషించుకుంటాయి. మునుపు, మేము IBM MQని బ్రోకర్‌గా ఉపయోగించాము, ఇది ఇకపై లోడ్‌ను ఎదుర్కోలేకపోయింది, కానీ అదే సమయంలో అధిక డెలివరీ హామీలను కలిగి ఉంది.

ప్రత్యామ్నాయంగా, మాకు అపాచీ కాఫ్కా అందించబడింది, ఇది అధిక స్కేలింగ్ సామర్థ్యాన్ని కలిగి ఉంది, కానీ, దురదృష్టవశాత్తు, విభిన్న దృశ్యాల కోసం కాన్ఫిగరేషన్‌కు దాదాపు వ్యక్తిగత విధానం అవసరం. అదనంగా, డిఫాల్ట్‌గా కాఫ్కాలో పని చేసే కనీసం ఒక్కసారైనా డెలివరీ మెకానిజం బాక్స్ వెలుపల అవసరమైన స్థాయి స్థిరత్వాన్ని నిర్వహించడానికి అనుమతించలేదు. తరువాత, నేను కాఫ్కా కాన్ఫిగరేషన్‌లో మా అనుభవాన్ని పంచుకుంటాను, ప్రత్యేకించి, డెలివరీతో సరిగ్గా ఒకసారి ఎలా కాన్ఫిగర్ చేయాలో మరియు జీవించాలో నేను మీకు చెప్తాను.

హామీ డెలివరీ మరియు మరిన్ని

దిగువ చర్చించబడిన సెట్టింగ్‌లు డిఫాల్ట్ కనెక్షన్ సెట్టింగ్‌లతో అనేక సమస్యలను నివారించడంలో సహాయపడతాయి. కానీ మొదట నేను సాధ్యమయ్యే డీబగ్‌ను సులభతరం చేసే ఒక పరామితికి శ్రద్ధ వహించాలనుకుంటున్నాను.

ఇది సహాయం చేస్తుంది client.id నిర్మాత మరియు వినియోగదారు కోసం. మొదటి చూపులో, మీరు అప్లికేషన్ పేరును విలువగా ఉపయోగించవచ్చు మరియు చాలా సందర్భాలలో ఇది పని చేస్తుంది. ఒక అప్లికేషన్ అనేక మంది వినియోగదారులను ఉపయోగించినప్పుడు మరియు మీరు వారికి ఒకే క్లయింట్.ఐడిని ఇచ్చినప్పటికీ, కింది హెచ్చరికలో ఫలితాలు:

org.apache.kafka.common.utils.AppInfoParser — Error registering AppInfo mbean javax.management.InstanceAlreadyExistsException: kafka.consumer:type=app-info,id=kafka.test-0

మీరు కాఫ్కాతో అప్లికేషన్‌లో JMXని ఉపయోగించాలనుకుంటే, ఇది సమస్య కావచ్చు. ఈ సందర్భంలో, అప్లికేషన్ పేరు యొక్క కలయికను ఉపయోగించడం ఉత్తమం మరియు ఉదాహరణకు, అంశం పేరును client.id విలువగా ఉపయోగించడం. మా కాన్ఫిగరేషన్ ఫలితాన్ని కమాండ్ అవుట్‌పుట్‌లో చూడవచ్చు కాఫ్కా-వినియోగదారుల సమూహాలు సంగమం నుండి యుటిలిటీల నుండి:

కాఫ్కా ఎలా నిజమైంది

ఇప్పుడు గ్యారెంటీ మెసేజ్ డెలివరీ కోసం దృష్టాంతాన్ని చూద్దాం. కాఫ్కా నిర్మాతకు ఒక పరామితి ఉంది అచ్చులు, క్లస్టర్ లీడర్ విజయవంతంగా వ్రాసిన సందేశాన్ని పరిగణనలోకి తీసుకోవడానికి ఎన్ని ఒప్పందాల తర్వాత కాన్ఫిగర్ చేయడానికి మిమ్మల్ని అనుమతిస్తుంది. ఈ పరామితి క్రింది విలువలను తీసుకోవచ్చు:

  • 0 - గుర్తింపు పరిగణించబడదు.
  • 1 డిఫాల్ట్ పరామితి, గుర్తించడానికి 1 ప్రతిరూపం మాత్రమే అవసరం.
  • −1 — అన్ని సమకాలీకరించబడిన ప్రతిరూపాల నుండి గుర్తింపు అవసరం (క్లస్టర్ సెటప్ min.insync.replicas).

జాబితా చేయబడిన విలువల నుండి −1కి సమానమైన యాక్‌లు సందేశాన్ని కోల్పోవని బలమైన హామీని ఇస్తాయని స్పష్టమవుతుంది.

మనందరికీ తెలిసినట్లుగా, పంపిణీ వ్యవస్థలు నమ్మదగనివి. తాత్కాలిక లోపాల నుండి రక్షించడానికి, కాఫ్కా ప్రొడ్యూసర్ ఎంపికను అందిస్తుంది మళ్లీ ప్రయత్నిస్తుంది, ఇది లోపల మళ్లీ పంపే ప్రయత్నాల సంఖ్యను సెట్ చేయడానికి మిమ్మల్ని అనుమతిస్తుంది delivery.timeout.ms. పునఃప్రయత్నాల పరామితి Integer.MAX_VALUE (2147483647) డిఫాల్ట్ విలువను కలిగి ఉన్నందున, delivery.timeout.msని మాత్రమే మార్చడం ద్వారా సందేశ పునఃప్రయత్నాల సంఖ్యను సర్దుబాటు చేయవచ్చు.

మేము ఖచ్చితంగా ఒకసారి డెలివరీ వైపు వెళ్తున్నాము

జాబితా చేయబడిన సెట్టింగ్‌లు అధిక హామీతో సందేశాలను అందించడానికి మా నిర్మాతను అనుమతిస్తాయి. కాఫ్కా టాపిక్‌కి సందేశం యొక్క ఒక కాపీ మాత్రమే వ్రాయబడిందని నిర్ధారించుకోవడం గురించి ఇప్పుడు మాట్లాడుదాం? సరళమైన సందర్భంలో, దీన్ని చేయడానికి, మీరు నిర్మాతపై పరామితిని సెట్ చేయాలి enable.deempotence నిజం. ఒక అంశం యొక్క నిర్దిష్ట విభజనకు ఒక సందేశం మాత్రమే వ్రాయబడిందని Idempotency హామీ ఇస్తుంది. ఐడెంపోటెన్సీని ఎనేబుల్ చేయడానికి ముందస్తు షరతు విలువలు acks = అన్నీ, మళ్లీ ప్రయత్నించండి > 0, max.in.flight.requests.per.connection ≤ 5. ఈ పారామితులు డెవలపర్ ద్వారా పేర్కొనబడకపోతే, పై విలువలు స్వయంచాలకంగా సెట్ చేయబడతాయి.

idempotency కాన్ఫిగర్ చేయబడినప్పుడు, అదే సందేశాలు ప్రతిసారీ అదే విభజనలలో ముగిసేలా చూసుకోవాలి. partitioner.class కీ మరియు పారామీటర్‌ని ప్రొడ్యూసర్‌కి సెట్ చేయడం ద్వారా ఇది చేయవచ్చు. కీతో ప్రారంభిద్దాం. ప్రతి సమర్పణకు ఇది తప్పనిసరిగా ఒకే విధంగా ఉండాలి. అసలు పోస్ట్ నుండి ఏదైనా వ్యాపార IDలను ఉపయోగించడం ద్వారా దీన్ని సులభంగా సాధించవచ్చు. partitioner.class పరామితి డిఫాల్ట్ విలువను కలిగి ఉంది - డిఫాల్ట్ పార్టిషనర్. ఈ విభజన వ్యూహంతో, డిఫాల్ట్‌గా మనం ఇలా వ్యవహరిస్తాము:

  • సందేశాన్ని పంపేటప్పుడు విభజన స్పష్టంగా పేర్కొనబడితే, మేము దానిని ఉపయోగిస్తాము.
  • విభజన పేర్కొనబడకపోతే, కానీ కీ పేర్కొనబడితే, కీ యొక్క హాష్ ద్వారా విభజనను ఎంచుకోండి.
  • విభజన మరియు కీ పేర్కొనబడకపోతే, విభజనలను ఒక్కొక్కటిగా ఎంచుకోండి (రౌండ్-రాబిన్).

అలాగే, ఒక పరామితితో కీ మరియు ఐడెంపోటెంట్ పంపడం ఉపయోగించి max.in.flight.requests.per.connection = 1 వినియోగదారుపై మీకు స్ట్రీమ్‌లైన్డ్ మెసేజ్ ప్రాసెసింగ్‌ని అందిస్తుంది. యాక్సెస్ కంట్రోల్ మీ క్లస్టర్‌లో కాన్ఫిగర్ చేయబడి ఉంటే, ఒక టాపిక్‌కు నిష్పాక్షికంగా వ్రాయడానికి మీకు హక్కులు అవసరమని గుర్తుంచుకోవడం విలువ.

అకస్మాత్తుగా మీకు కీ ద్వారా ఐడెంపోటెంట్ పంపే సామర్థ్యాలు లేకుంటే లేదా ప్రొడ్యూసర్ వైపు లాజిక్ వివిధ విభజనల మధ్య డేటా అనుగుణ్యతను కొనసాగించాల్సిన అవసరం ఉంటే, అప్పుడు లావాదేవీలు రక్షించబడతాయి. అదనంగా, గొలుసు లావాదేవీని ఉపయోగించి, మీరు కాఫ్కాలో రికార్డును షరతులతో సమకాలీకరించవచ్చు, ఉదాహరణకు, డేటాబేస్లో రికార్డుతో. ప్రొడ్యూసర్‌కి లావాదేవీ పంపడాన్ని ప్రారంభించడానికి, అది తప్పనిసరిగా ఐడెంపోటెంట్‌గా మరియు అదనంగా సెట్ చేయబడి ఉండాలి Transactional.id. మీ కాఫ్కా క్లస్టర్ యాక్సెస్ నియంత్రణను కాన్ఫిగర్ చేసి ఉంటే, ఐడెమ్‌పోటెంట్ రికార్డ్ వంటి లావాదేవీల రికార్డ్‌కు వ్రాత అనుమతులు అవసరం, లావాదేవీలు.idలో నిల్వ చేసిన విలువను ఉపయోగించి మాస్క్ ద్వారా మంజూరు చేయవచ్చు.

అధికారికంగా, అప్లికేషన్ పేరు వంటి ఏదైనా స్ట్రింగ్‌ను లావాదేవీ ఐడెంటిఫైయర్‌గా ఉపయోగించవచ్చు. కానీ మీరు ఒకే అప్లికేషన్‌కి సంబంధించిన అనేక సందర్భాలను ఒకే లావాదేవీ.idతో ప్రారంభించినట్లయితే, కాఫ్కా దీనిని జోంబీ ప్రక్రియగా పరిగణిస్తుంది కాబట్టి, మొదటి లాంచ్ చేసిన సందర్భం లోపంతో ఆపివేయబడుతుంది.

org.apache.kafka.common.errors.ProducerFencedException: Producer attempted an operation with an old epoch. Either there is a newer producer with the same transactionalId, or the producer's transaction has been expired by the broker.

ఈ సమస్యను పరిష్కరించడానికి, మేము ఎన్విరాన్మెంట్ వేరియబుల్స్ నుండి పొందే హోస్ట్ పేరు రూపంలో అప్లికేషన్ పేరుకు ప్రత్యయాన్ని జోడిస్తాము.

నిర్మాత కాన్ఫిగర్ చేయబడింది, కానీ కాఫ్కాపై లావాదేవీలు సందేశం యొక్క పరిధిని మాత్రమే నియంత్రిస్తాయి. లావాదేవీ స్థితితో సంబంధం లేకుండా, సందేశం వెంటనే అంశానికి వెళుతుంది, కానీ అదనపు సిస్టమ్ లక్షణాలను కలిగి ఉంటుంది.

అటువంటి సందేశాలను వినియోగదారు ముందుగా చదవకుండా నిరోధించడానికి, అతను పరామితిని సెట్ చేయాలి ఐసోలేషన్.స్థాయి రీడ్_కమిటెడ్ విలువకు. అటువంటి వినియోగదారుడు లావాదేవీలు కాని సందేశాలను మునుపటిలా చదవగలరు మరియు లావాదేవీ సందేశాలను కమిట్ అయిన తర్వాత మాత్రమే చదవగలరు.
మీరు ఇంతకు ముందు జాబితా చేసిన అన్ని సెట్టింగ్‌లను సెట్ చేసినట్లయితే, మీరు డెలివరీని ఒకసారి కాన్ఫిగర్ చేసారు. అభినందనలు!

కానీ మరొక స్వల్పభేదాన్ని ఉంది. మేము పైన కాన్ఫిగర్ చేసిన Transactional.id, వాస్తవానికి లావాదేవీ ఉపసర్గ. లావాదేవీ మేనేజర్‌లో, దానికి సీక్వెన్స్ నంబర్ జోడించబడుతుంది. స్వీకరించిన ఐడెంటిఫైయర్ వీరికి జారీ చేయబడింది Transactional.id.expiration.ms, ఇది కాఫ్కా క్లస్టర్‌పై కాన్ఫిగర్ చేయబడింది మరియు “7 రోజులు” డిఫాల్ట్ విలువను కలిగి ఉంటుంది. ఈ సమయంలో అప్లికేషన్‌కు ఎటువంటి సందేశాలు రాకుంటే, మీరు తదుపరి లావాదేవీని ప్రయత్నించినప్పుడు మీరు స్వీకరిస్తారు చెల్లని పిడ్‌మ్యాపింగ్ మినహాయింపు. లావాదేవీ సమన్వయకర్త తదుపరి లావాదేవీకి కొత్త సీక్వెన్స్ నంబర్‌ను జారీ చేస్తారు. అయినప్పటికీ, InvalidPidMappingException సరిగ్గా నిర్వహించబడకపోతే సందేశం కోల్పోవచ్చు.

ఫలితాలకు బదులుగా

మీరు గమనిస్తే, కాఫ్కాకు సందేశాలు పంపడం మాత్రమే సరిపోదు. మీరు పారామితుల కలయికను ఎంచుకోవాలి మరియు త్వరిత మార్పులు చేయడానికి సిద్ధంగా ఉండాలి. ఈ కథనంలో, నేను సరిగ్గా ఒకసారి డెలివరీ సెటప్‌ను వివరంగా చూపించడానికి ప్రయత్నించాను మరియు మేము ఎదుర్కొన్న client.id మరియు Transactional.id కాన్ఫిగరేషన్‌లతో అనేక సమస్యలను వివరించాను. దిగువ నిర్మాత మరియు వినియోగదారు సెట్టింగ్‌ల సారాంశం.

నిర్మాత:

  1. acks = అన్నీ
  2. మళ్లీ ప్రయత్నిస్తుంది > 0
  3. enable.idempotence = నిజం
  4. max.in.flight.requests.per.connection ≤ 5 (క్రమబద్ధంగా పంపడం కోసం 1)
  5. Transactional.id = ${application-name}-${hostname}

వినియోగదారు:

  1. isolation.level = read_committed

భవిష్యత్ అప్లికేషన్‌లలో లోపాలను తగ్గించడానికి, మేము స్ప్రింగ్ కాన్ఫిగరేషన్‌పై మా స్వంత రేపర్‌ని తయారు చేసాము, ఇక్కడ జాబితా చేయబడిన కొన్ని పారామీటర్‌ల విలువలు ఇప్పటికే సెట్ చేయబడ్డాయి.

స్వీయ-అధ్యయనం కోసం ఇక్కడ కొన్ని మెటీరియల్స్ ఉన్నాయి:

మూలం: www.habr.com

ఒక వ్యాఖ్యను జోడించండి