ڪافڪا ڪيئن حقيقت بڻجي ويو

ڪافڪا ڪيئن حقيقت بڻجي ويو

اي حبر!

مان Tinkoff ٽيم تي ڪم ڪريان ٿو، جيڪو پنهنجو نوٽيفڪيشن سينٽر ٺاهي رهيو آهي. مان گهڻو ڪري جاوا ۾ اسپرنگ بوٽ استعمال ڪندي ترقي ڪريان ٿو ۽ پروجيڪٽ ۾ پيدا ٿيندڙ مختلف ٽيڪنيڪل مسئلا حل ڪريان ٿو.

اسان جون گھڻا مائيڪرو سروسز ھڪ ٻئي سان ھڪ ٻئي سان ڳالھ ٻولھ ڪن ٿيون ھڪ ميسيج بروکر جي ذريعي. اڳي، اسان استعمال ڪيو IBM MQ هڪ بروکر جي طور تي، جيڪو هاڻي لوڊ سان مقابلو نه ڪري سگهيو، پر ساڳئي وقت اعلي ترسيل گارنٽي هئي.

متبادل طور تي، اسان کي پيش ڪيو ويو Apache Kafka، جنهن ۾ اعلي اسڪيلنگ جي صلاحيت آهي، پر، بدقسمتي سان، مختلف منظرنامي لاء ترتيب ڏيڻ لاء تقريبن انفرادي طريقي جي ضرورت آهي. ان کان علاوه، گهٽ ۾ گهٽ هڪ ڀيرو پهچائڻ واري ميڪانيزم جيڪا ڪافڪا ۾ ڊفالٽ طور ڪم ڪري ٿي، باڪس کان ٻاهر گهربل سطح جي تسلسل کي برقرار رکڻ جي اجازت نه ڏني. اڳيون، مان اسان جو تجربو حصيداري ڪندس ڪافڪا جي ترتيب ۾، خاص طور تي، مان توهان کي ٻڌايان ٿو ته ڪيئن ترتيب ڏيڻ ۽ صحيح طور تي هڪ ڀيرو پهچائڻ سان گڏ.

ضمانت جي ترسيل ۽ وڌيڪ

هيٺ ڏنل بحث ڪيل سيٽنگون ڊفالٽ ڪنيڪشن سيٽنگن سان ڪيترن ئي مسئلن کي روڪڻ ۾ مدد ڪندي. پر پهريان آئون هڪ پيٽرولر تي ڌيان ڏيڻ چاهيندس جيڪو ممڪن ڊيبگ کي آسان بڻائي سگهندو.

هي مدد ڪندو client.id پيدا ڪندڙ ۽ صارفين لاء. پهرين نظر ۾، توهان استعمال ڪري سگهو ٿا ايپليڪيشن جو نالو قدر جي طور تي، ۽ اڪثر ڪيسن ۾ اهو ڪم ڪندو. جيتوڻيڪ صورتحال جڏهن هڪ ايپليڪيشن ڪيترن ئي صارفين کي استعمال ڪري ٿي ۽ توهان انهن کي ساڳيو 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 قدر جي طور تي. اسان جي ٺاھ جوڙ جو نتيجو ڪمانڊ آئوٽ ۾ ڏسي سگھجي ٿو kafka-صارف-گروپ Confluent کان يوٽيلٽيز مان:

ڪافڪا ڪيئن حقيقت بڻجي ويو

ھاڻي اچو ته گارنٽيڊ پيغام پهچائڻ لاءِ منظرنامو ڏسو. ڪافڪا پروڊيوسر وٽ ھڪڙو پيٽرول آھي acks، جيڪو توهان کي ترتيب ڏيڻ جي اجازت ڏئي ٿو ته ڪلستر ليڊر کي ڪيترين ئي تسليم ڪرڻ کان پوءِ ڪاميابي سان لکيل پيغام تي غور ڪرڻ جي ضرورت آهي. ھي پيٽرول ھيٺين قدر وٺي سگھي ٿو:

  • 0 - تسليم نه ڪيو ويندو.
  • 1 ڊفالٽ پيٽرولر آهي، صرف 1 نقل کي تسليم ڪرڻ جي ضرورت آهي.
  • −1 - سڀني هم وقت سازي ٿيل نقلن مان تسليم ڪيو وڃي (ڪلسٽر سيٽ اپ min.insync.replicas).

درج ڪيل قدرن مان اهو واضح ٿئي ٿو ته −1 جي برابر acks مضبوط ضمانت ڏئي ٿو ته پيغام گم نه ٿيندو.

جيئن ته اسان سڀ ڄاڻون ٿا، ورهايل سسٽم ناقابل اعتبار آهن. عارضي غلطين کان بچائڻ لاءِ، ڪافڪا پروڊيوسر اختيار ڏئي ٿو riesيهر ڪوشش ڪري ٿو، جيڪو توهان کي ٻيهر موڪلڻ جي ڪوششن جو تعداد مقرر ڪرڻ جي اجازت ڏئي ٿو پهچائڻ.timeout.ms. جيئن ته ٻيهر ڪوششن جي پيٽرولر ۾ Integer.MAX_VALUE (2147483647) جي ڊفالٽ قيمت آهي، پيغام جي ٻيهر ڪوششن جو تعداد تبديل ڪري سگھجن ٿا صرف delivery.timeout.ms.

اسان اڳتي وڌي رهيا آهيون بلڪل هڪ ڀيرو پهچائڻ

درج ٿيل سيٽنگون اسان جي پروڊيوسر کي اعلي گارنٽي سان پيغام پهچائڻ جي اجازت ڏين ٿيون. اچو ته هاڻي ان ڳالهه تي ڳالهايون ته ڪيئن يقيني بڻايو وڃي ته هڪ پيغام جي صرف هڪ ڪاپي ڪافڪا جي موضوع تي لکيل آهي؟ آسان ترين صورت ۾، هن کي ڪرڻ لاء، توهان کي پروسيسر تي پيٽرولر مقرر ڪرڻ جي ضرورت آهي enable.idempotence سچ ڪرڻ. Idempotency ضمانت ڏئي ٿي ته صرف هڪ پيغام هڪ موضوع جي مخصوص ورهاڱي تي لکيل آهي. Idempotency کي فعال ڪرڻ لاءِ اڳوڻو شرط قدر آهي acks = سڀ، ٻيهر ڪوشش > 0, max.in.flight.requests.per.connection ≤ 5. جيڪڏهن اهي پيٽرولر ڊولپر طرفان بيان نه ڪيا ويا آهن، مٿين قدر خودڪار طور تي مقرر ڪيا ويندا.

جڏهن idempotency ترتيب ڏني وئي آهي، ان کي يقيني بڻائڻ ضروري آهي ته ساڳيو پيغام هر وقت ساڳئي ورهاڱي ۾ ختم ٿي وڃي. اهو ڪري سگهجي ٿو partitioner.class ڪيئي ۽ پيٽرولر کي پروڊيوسر کي ترتيب ڏيڻ سان. اچو ته ڪنجي سان شروع ڪريون. اهو هر جمع ڪرائڻ لاء ساڳيو هجڻ گهرجي. اهو آساني سان حاصل ڪري سگهجي ٿو ڪنهن به ڪاروباري ID کي استعمال ڪندي اصل پوسٽ مان. partitioner.class پيراميٽر وٽ ڊفالٽ ويل آهي - Default Partitioner. هن ورهاڱي واري حڪمت عملي سان، ڊفالٽ طور اسان هن طرح ڪم ڪريون ٿا:

  • جيڪڏهن ورهاڱي واضح طور تي بيان ڪيو ويو آهي جڏهن پيغام موڪلڻ، پوء اسان ان کي استعمال ڪندا آهيون.
  • جيڪڏهن ورهاڱي جي وضاحت نه ڪئي وئي آهي، پر ڪنجي بيان ڪئي وئي آهي، ورهاڱي کي چيڪ جي هيش ذريعي چونڊيو.
  • جيڪڏهن ورهاڱي ۽ ڪنجي بيان نه ڪئي وئي آهي، هڪ هڪ ڪري ڊويزن چونڊيو (رائونڊ-رابن).

به، هڪ اهم ۽ idempotent موڪلڻ استعمال ڪندي هڪ پيراگراف سان max.in.flight.requests.per.connection = 1 توهان کي صارف تي سڌو سنئون پيغام پروسيسنگ ڏئي ٿو. اهو پڻ ياد رکڻ جي قابل آهي ته جيڪڏهن رسائي ڪنٽرول توهان جي ڪلستر تي ترتيب ڏني وئي آهي، ته پوء توهان کي حق جي ضرورت پوندي هڪ موضوع تي صحيح طور تي لکڻ لاء.

جيڪڏهن اوچتو توهان وٽ ڪيئي ذريعي موڪلڻ جي صلاحيت جي کوٽ آهي يا پروڊيوسر طرف منطق مختلف حصن جي وچ ۾ ڊيٽا جي تسلسل کي برقرار رکڻ جي ضرورت آهي، پوء ٽرانزيڪشن بچاء لاء ايندا. اضافي طور تي، هڪ زنجير ٽرانزيڪشن استعمال ڪندي، توهان شرطي طور تي ڪافڪا ۾ رڪارڊ کي هم وقت سازي ڪري سگهو ٿا، مثال طور، ڊيٽابيس ۾ رڪارڊ سان. پروڊيوسر ڏانهن ٽرانزيڪشن موڪلڻ کي چالو ڪرڻ لاءِ، ان کي لازمي طور تي قابليت ۽ اضافي طور تي مقرر ڪيو وڃي transactional.id. جيڪڏهن توهان جي ڪافڪا ڪلستر وٽ رسائي ڪنٽرول ترتيب ڏنل آهي، ته پوءِ هڪ ٽرانزيڪشنل رڪارڊ، جهڙوڪ هڪ idempotent رڪارڊ، لکڻ جي اجازتن جي ضرورت پوندي، جيڪا 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.

ھن مسئلي کي حل ڪرڻ لاءِ، اسان ھوسٽ اسم جي صورت ۾ ايپليڪيشن جي نالي ۾ ھڪڙو لاتعداد شامل ڪندا آھيون، جيڪو اسان ماحوليات جي متغيرن مان حاصل ڪندا آھيون.

پيدا ڪندڙ ترتيب ڏنل آهي، پر ڪافڪا تي ٽرانزيڪشن صرف پيغام جي دائري کي ڪنٽرول ڪن ٿا. ٽرانزيڪشن جي صورتحال کان سواء، پيغام فوري طور تي موضوع ڏانهن وڃي ٿو، پر اضافي سسٽم خاصيتون آهن.

اهڙين پيغامن کي صارف پاران وقت کان اڳ پڙهڻ کان روڪڻ لاءِ، ان کي پيٽرول مقرر ڪرڻ جي ضرورت آهي isolation.level to read_committed value. اهڙو صارف غير ٽرانزيڪشنل پيغامن کي پڙهڻ جي قابل هوندو جيئن اڳ ۾، ۽ ٽرانزيڪشنل پيغامن کي صرف هڪ عزم کان پوء.
جيڪڏهن توهان سڀني سيٽنگون ترتيب ڏنيون آهن جيڪي پهريان فهرست ڏنل آهن، پوء توهان ترتيب ڏني آهي هڪ ڀيرو پهچائڻ. مبارڪون هجن!

پر اتي هڪ وڌيڪ nuance آهي. Transactional.id، جنهن کي اسان مٿي ترتيب ڏنو آهي، اصل ۾ ٽرانزيڪشن پريفڪس آهي. ٽرانزيڪشن مئنيجر تي، هڪ ترتيب نمبر ان ۾ شامل ڪيو ويو آهي. حاصل ڪيل سڃاڻپ ڪندڙ کي جاري ڪيو ويو آهي transactional.id.expiration.ms، جيڪو ڪافڪا ڪلستر تي ترتيب ڏنل آهي ۽ "7 ڏينهن" جي ڊفالٽ قيمت آهي. جيڪڏهن هن عرصي دوران ايپليڪيشن کي ڪوبه پيغام نه مليو آهي، ته پوءِ جڏهن توهان ڪوشش ڪندا ته ايندڙ ٽرانزيڪشنل موڪلون توهان کي ملي وينديون غلطPidMappingException. ٽرانزيڪشن ڪوآرڊينيٽر وري ايندڙ ٽرانزيڪشن لاءِ نئون تسلسل نمبر جاري ڪندو. بهرحال، پيغام گم ٿي سگهي ٿو جيڪڏهن 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 = پڙهو

مستقبل جي ايپليڪيشنن ۾ غلطيون گھٽائڻ لاءِ، اسان بهار جي ٺاھ جوڙ تي پنھنجو پنھنجو لفافو ٺاھيو، جتي ڪجھ درج ڪيل پيرا ميٽرن لاءِ قدر اڳ ۾ ئي مقرر ٿيل آھن.

هتي خود مطالعي لاء ڪجهه مواد آهن:

جو ذريعو: www.habr.com

تبصرو شامل ڪريو