காஃப்கா எப்படி நிஜம் ஆனார்

காஃப்கா எப்படி நிஜம் ஆனார்

ஹே ஹப்ர்!

நான் Tinkoff குழுவில் வேலை செய்கிறேன், அது அதன் சொந்த அறிவிப்பு மையத்தை உருவாக்குகிறது. நான் பெரும்பாலும் ஸ்பிரிங் பூட்டைப் பயன்படுத்தி ஜாவாவில் உருவாக்கி, ஒரு திட்டத்தில் எழும் பல்வேறு தொழில்நுட்ப சிக்கல்களைத் தீர்க்கிறேன்.

எங்களின் பெரும்பாலான மைக்ரோ சர்வீஸ்கள் ஒரு செய்தி தரகர் மூலம் ஒருவருக்கொருவர் ஒத்திசைவற்ற முறையில் தொடர்பு கொள்கின்றன. முன்னதாக, நாங்கள் IBM MQ ஐ ஒரு தரகராகப் பயன்படுத்தினோம், அது இனி சுமையைச் சமாளிக்க முடியாது, ஆனால் அதே நேரத்தில் அதிக விநியோக உத்தரவாதங்களைக் கொண்டிருந்தது.

மாற்றாக, எங்களுக்கு Apache Kafka வழங்கப்பட்டது, இது அதிக அளவிடுதல் திறனைக் கொண்டுள்ளது, ஆனால், துரதிர்ஷ்டவசமாக, வெவ்வேறு காட்சிகளுக்கான உள்ளமைவுக்கு கிட்டத்தட்ட தனிப்பட்ட அணுகுமுறை தேவைப்படுகிறது. கூடுதலாக, காஃப்காவில் இயல்பாக வேலை செய்யும் குறைந்தபட்சம் ஒரு முறை டெலிவரி பொறிமுறையானது, பெட்டிக்கு வெளியே தேவையான நிலைத்தன்மையை பராமரிக்க அனுமதிக்கவில்லை. அடுத்து, காஃப்கா உள்ளமைவில் எங்கள் அனுபவத்தைப் பகிர்ந்து கொள்கிறேன், குறிப்பாக, டெலிவரிக்கு சரியாக ஒரு முறை எப்படி கட்டமைப்பது மற்றும் வாழ்வது என்பதை நான் உங்களுக்குச் சொல்கிறேன்.

உத்தரவாத டெலிவரி மற்றும் பல

கீழே விவாதிக்கப்பட்ட அமைப்புகள் இயல்புநிலை இணைப்பு அமைப்புகளில் பல சிக்கல்களைத் தடுக்க உதவும். ஆனால் முதலில் நான் ஒரு அளவுருவில் கவனம் செலுத்த விரும்புகிறேன், அது சாத்தியமான பிழைத்திருத்தத்தை எளிதாக்கும்.

இது உதவும் 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 ஐப் பயன்படுத்த விரும்பினால், இது ஒரு சிக்கலாக இருக்கலாம். இந்த வழக்கில், பயன்பாட்டின் பெயரையும், எடுத்துக்காட்டாக, கிளையன்ட்.ஐடி மதிப்பாக தலைப்பின் பெயரையும் இணைப்பது சிறந்தது. எங்கள் கட்டமைப்பின் முடிவை கட்டளை வெளியீட்டில் காணலாம் காஃப்கா-நுகர்வோர்-குழுக்கள் சங்கமத்தில் இருந்து பயன்பாடுகள்:

காஃப்கா எப்படி நிஜம் ஆனார்

இப்போது உத்தரவாதமான செய்தி விநியோகத்திற்கான காட்சியைப் பார்ப்போம். காஃப்கா தயாரிப்பாளரிடம் ஒரு அளவுரு உள்ளது ஆக்ஸ், க்ளஸ்டர் லீடர் எத்தனை ஒப்புதல்களுக்குப் பிறகு வெற்றிகரமாக எழுதப்பட்ட செய்தியைக் கருத்தில் கொள்ள வேண்டும் என்பதை உள்ளமைக்க இது உங்களை அனுமதிக்கிறது. இந்த அளவுரு பின்வரும் மதிப்புகளை எடுக்கலாம்:

  • 0 - ஒப்புகை பரிசீலிக்கப்படாது.
  • 1 என்பது இயல்புநிலை அளவுருவாகும், ஒப்புக்கொள்ள 1 பிரதி மட்டுமே தேவை.
  • −1 — அனைத்து ஒத்திசைக்கப்பட்ட பிரதிகளிலிருந்தும் ஒப்புதல் தேவை (கிளஸ்டர் அமைப்பு min.insync.replicas).

பட்டியலிடப்பட்ட மதிப்புகளிலிருந்து, −1 க்கு சமமான அக்குகள் செய்தி இழக்கப்படாது என்பதற்கு வலுவான உத்தரவாதத்தை அளிக்கிறது என்பது தெளிவாகிறது.

நாம் அனைவரும் அறிந்தபடி, விநியோகிக்கப்பட்ட அமைப்புகள் நம்பகத்தன்மையற்றவை. நிலையற்ற தவறுகளிலிருந்து பாதுகாக்க, காஃப்கா தயாரிப்பாளர் விருப்பத்தை வழங்குகிறது மீண்டும் முயற்சிக்கிறது, இது மீண்டும் அனுப்பும் முயற்சிகளின் எண்ணிக்கையை அமைக்க உங்களை அனுமதிக்கிறது delivery.timeout.ms. மறுமுயற்சிகள் அளவுருவில் Integer.MAX_VALUE (2147483647) இன் இயல்புநிலை மதிப்பு இருப்பதால், delivery.timeout.ms ஐ மட்டும் மாற்றுவதன் மூலம் செய்தி மறு முயற்சிகளின் எண்ணிக்கையை சரிசெய்ய முடியும்.

நாங்கள் சரியாக ஒரு முறை டெலிவரியை நோக்கி நகர்கிறோம்

பட்டியலிடப்பட்ட அமைப்புகள் எங்கள் தயாரிப்பாளரை அதிக உத்தரவாதத்துடன் செய்திகளை வழங்க அனுமதிக்கின்றன. ஒரு செய்தியின் ஒரு நகல் மட்டும் காஃப்கா தலைப்பில் எழுதப்பட்டிருப்பதை எவ்வாறு உறுதி செய்வது என்பது பற்றி இப்போது பேசலாமா? எளிமையான வழக்கில், இதைச் செய்ய, நீங்கள் தயாரிப்பாளரில் அளவுருவை அமைக்க வேண்டும் இயலுமை உண்மை. ஒரு தலைப்பின் ஒரு குறிப்பிட்ட பகிர்வுக்கு ஒரே ஒரு செய்தி மட்டுமே எழுதப்பட்டிருப்பதை Idempotency உத்தரவாதம் செய்கிறது. ஐடிம்போடென்சியை செயல்படுத்துவதற்கான முன்நிபந்தனை மதிப்புகள் acks = அனைத்தும், மீண்டும் முயற்சிக்கவும் > 0, max.in.flight.requests.per.connection ≤ 5. இந்த அளவுருக்கள் டெவலப்பரால் குறிப்பிடப்படவில்லை என்றால், மேலே உள்ள மதிப்புகள் தானாகவே அமைக்கப்படும்.

idempotency கட்டமைக்கப்படும் போது, ​​ஒவ்வொரு முறையும் அதே செய்திகள் ஒரே பகிர்வுகளில் முடிவடைவதை உறுதி செய்வது அவசியம். partitioner.class கீ மற்றும் அளவுருவை தயாரிப்பாளருக்கு அமைப்பதன் மூலம் இதைச் செய்யலாம். சாவியுடன் ஆரம்பிக்கலாம். ஒவ்வொரு சமர்ப்பிப்பிற்கும் ஒரே மாதிரியாக இருக்க வேண்டும். அசல் இடுகையிலிருந்து ஏதேனும் வணிக ஐடிகளைப் பயன்படுத்துவதன் மூலம் இதை எளிதாக அடையலாம். partitioner.class அளவுருவில் இயல்புநிலை மதிப்பு உள்ளது - DefaultPartitioner. இந்த பகிர்வு உத்தி மூலம், முன்னிருப்பாக நாம் இப்படி செயல்படுகிறோம்:

  • செய்தியை அனுப்பும்போது பகிர்வு வெளிப்படையாகக் குறிப்பிடப்பட்டால், நாங்கள் அதைப் பயன்படுத்துகிறோம்.
  • பகிர்வு குறிப்பிடப்படவில்லை, ஆனால் விசை குறிப்பிடப்பட்டிருந்தால், விசையின் ஹாஷ் மூலம் பகிர்வைத் தேர்ந்தெடுக்கவும்.
  • பகிர்வு மற்றும் விசை குறிப்பிடப்படவில்லை என்றால், பகிர்வுகளை ஒவ்வொன்றாக தேர்ந்தெடுக்கவும் (ரவுண்ட்-ராபின்).

மேலும், ஒரு விசையைப் பயன்படுத்துதல் மற்றும் ஒரு அளவுருவுடன் சக்தியற்ற அனுப்புதல் max.in.flight.requests.per.connection = 1 நுகர்வோர் மீது நெறிப்படுத்தப்பட்ட செய்தி செயலாக்கத்தை உங்களுக்கு வழங்குகிறது. உங்கள் கிளஸ்டரில் அணுகல் கட்டுப்பாடு கட்டமைக்கப்பட்டிருந்தால், ஒரு தலைப்பில் திறமையற்ற முறையில் எழுத உங்களுக்கு உரிமைகள் தேவைப்படும் என்பதையும் நினைவில் கொள்வது மதிப்பு.

விசை அல்லது தயாரிப்பாளரின் தரப்பில் உள்ள தர்க்கத்தின் மூலம் பல்வேறு பகிர்வுகளுக்கு இடையில் தரவு நிலைத்தன்மையைப் பேணுவது அவசியமாக இருந்தால், திடீரென்று உங்களுக்குப் பரிவர்த்தனைகள் மீட்புக்கு வரும். கூடுதலாக, ஒரு சங்கிலி பரிவர்த்தனையைப் பயன்படுத்தி, நீங்கள் காஃப்காவில் ஒரு பதிவை நிபந்தனையுடன் ஒத்திசைக்கலாம், எடுத்துக்காட்டாக, தரவுத்தளத்தில் ஒரு பதிவு. தயாரிப்பாளருக்கு பரிவர்த்தனை அனுப்புதலை இயக்க, அது வலுவற்றதாகவும் கூடுதலாகவும் அமைக்கப்பட வேண்டும் Transactional.id. உங்கள் காஃப்கா கிளஸ்டருக்கு அணுகல் கட்டுப்பாடு உள்ளமைக்கப்பட்டிருந்தால், ஒரு பரிவர்த்தனை பதிவு, ஒரு ஐடிம்போடென்ட் பதிவு போன்றவற்றுக்கு எழுத அனுமதிகள் தேவைப்படும், இது Transactional.id இல் சேமிக்கப்பட்டுள்ள மதிப்பைப் பயன்படுத்தி முகமூடி மூலம் வழங்கப்படலாம்.

முறைப்படி, பயன்பாட்டின் பெயர் போன்ற எந்த சரத்தையும் பரிவர்த்தனை அடையாளங்காட்டியாகப் பயன்படுத்தலாம். ஆனால் நீங்கள் ஒரே ஆப்ஸின் பல நிகழ்வுகளை ஒரே Transactional.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 சரியாகக் கையாளப்படாவிட்டால், செய்தி இழக்கப்படலாம்.

மொத்தத்திற்கு பதிலாக

நீங்கள் பார்ப்பது போல், காஃப்காவுக்கு செய்திகளை அனுப்பினால் மட்டும் போதாது. நீங்கள் அளவுருக்களின் கலவையைத் தேர்வு செய்ய வேண்டும் மற்றும் விரைவான மாற்றங்களைச் செய்ய தயாராக இருக்க வேண்டும். இந்தக் கட்டுரையில், சரியாக ஒருமுறை டெலிவரி செட்டப்பை விரிவாகக் காட்ட முயற்சித்தேன், நாங்கள் எதிர்கொண்ட கிளையன்ட்.ஐடி மற்றும் டிராக்ஷனல்.ஐடி உள்ளமைவுகளில் உள்ள பல சிக்கல்களை விவரித்தேன். தயாரிப்பாளர் மற்றும் நுகர்வோர் அமைப்புகளின் சுருக்கம் கீழே உள்ளது.

தயாரிப்பாளர்:

  1. அக்குகள் = அனைத்தும்
  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

கருத்தைச் சேர்