کافکا کیسے حقیقت بن گیا۔

کافکا کیسے حقیقت بن گیا۔

ارے حبر!

میں Tinkoff ٹیم پر کام کرتا ہوں، جو اپنا اطلاعی مرکز تیار کر رہی ہے۔ میں زیادہ تر اسپرنگ بوٹ کا استعمال کرتے ہوئے جاوا میں تیار کرتا ہوں اور پروجیکٹ میں پیدا ہونے والے مختلف تکنیکی مسائل کو حل کرتا ہوں۔

ہماری زیادہ تر مائیکرو سروسز میسج بروکر کے ذریعے ایک دوسرے کے ساتھ متضاد طور پر بات چیت کرتی ہیں۔ پہلے، ہم نے IBM MQ کو بروکر کے طور پر استعمال کیا تھا، جو مزید بوجھ کا مقابلہ نہیں کر سکتا تھا، لیکن ساتھ ہی اس میں اعلیٰ ترسیل کی ضمانتیں تھیں۔

متبادل کے طور پر، ہمیں اپاچی کافکا کی پیشکش کی گئی، جس میں اسکیلنگ کی اعلیٰ صلاحیت ہے، لیکن بدقسمتی سے، مختلف منظرناموں کے لیے ترتیب کے لیے تقریباً انفرادی نقطہ نظر کی ضرورت ہے۔ اس کے علاوہ، کم از کم ایک بار ڈیلیوری کا طریقہ کار جو کافکا میں بطور ڈیفالٹ کام کرتا ہے، اس نے باکس سے باہر مستقل مزاجی کی مطلوبہ سطح کو برقرار رکھنے کی اجازت نہیں دی۔ اس کے بعد، میں کافکا کنفیگریشن میں اپنے تجربے کا اشتراک کروں گا، خاص طور پر، میں آپ کو بتاؤں گا کہ کس طرح ترتیب دینا ہے اور بالکل ایک بار ڈیلیوری کے ساتھ رہنا ہے۔

ضمانت شدہ ترسیل اور مزید

ذیل میں زیر بحث سیٹنگز ڈیفالٹ کنکشن سیٹنگز کے ساتھ متعدد مسائل کو روکنے میں مدد کریں گی۔ لیکن پہلے میں ایک پیرامیٹر پر توجہ دینا چاہوں گا جو ممکنہ ڈیبگ کی سہولت فراہم کرے گا۔

اس سے مدد ملے گی۔ 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 ویلیو استعمال کرنا بہتر ہے۔ ہماری ترتیب کا نتیجہ کمانڈ آؤٹ پٹ میں دیکھا جا سکتا ہے۔ کافکا صارفین کے گروپس Confluent سے افادیت سے:

کافکا کیسے حقیقت بن گیا۔

اب آئیے گارنٹی شدہ پیغام کی ترسیل کے منظر نامے کو دیکھتے ہیں۔ کافکا پروڈیوسر کا ایک پیرامیٹر ہوتا ہے۔ اکس، جو آپ کو کنفیگر کرنے کی اجازت دیتا ہے کہ کلسٹر لیڈر کو کامیابی سے لکھے گئے پیغام پر غور کرنے کے لیے کتنے تسلیم کرنے کی ضرورت ہے۔ یہ پیرامیٹر درج ذیل اقدار لے سکتا ہے:

  • 0 - تسلیم کرنے پر غور نہیں کیا جائے گا۔
  • 1 ڈیفالٹ پیرامیٹر ہے، تسلیم کرنے کے لیے صرف 1 نقل درکار ہے۔
  • −1 - تمام مطابقت پذیر نقلوں سے تسلیم کرنا ضروری ہے (کلسٹر سیٹ اپ min.insync.replicas).

درج کردہ اقدار سے یہ واضح ہے کہ −1 کے برابر acks سب سے مضبوط ضمانت دیتا ہے کہ پیغام ضائع نہیں ہوگا۔

جیسا کہ ہم سب جانتے ہیں، تقسیم شدہ نظام ناقابل اعتبار ہیں۔ عارضی خرابیوں سے بچانے کے لیے، کافکا پروڈیوسر آپشن فراہم کرتا ہے۔ دوبارہ کوشش کرتا ہے، جو آپ کو دوبارہ بھیجنے کی کوششوں کی تعداد مقرر کرنے کی اجازت دیتا ہے۔ ڈیلیوری.timeout.ms. چونکہ دوبارہ کوشش کرنے والے پیرامیٹر میں Integer.MAX_VALUE (2147483647) کی ڈیفالٹ قدر ہوتی ہے، اس لیے پیغام کی دوبارہ کوششوں کی تعداد صرف ڈیلیوری.timeout.ms کو تبدیل کر کے ایڈجسٹ کی جا سکتی ہے۔

ہم بالکل ایک بار ترسیل کی طرف بڑھ رہے ہیں۔

درج کردہ ترتیبات ہمارے پروڈیوسر کو اعلی گارنٹی کے ساتھ پیغامات ڈیلیور کرنے کی اجازت دیتی ہیں۔ آئیے اب بات کرتے ہیں کہ یہ کیسے یقینی بنایا جائے کہ کافکا کے موضوع پر پیغام کی صرف ایک کاپی لکھی جائے؟ آسان ترین صورت میں، ایسا کرنے کے لیے، آپ کو پروڈیوسر پر پیرامیٹر سیٹ کرنا ہوگا۔ enable.idempotence سچ کرنے کے لئے. Idempotency اس بات کی ضمانت دیتا ہے کہ ایک موضوع کی مخصوص تقسیم پر صرف ایک پیغام لکھا جاتا ہے۔ آئیڈیمپوٹینسی کو فعال کرنے کی شرط اقدار ہیں۔ acks = تمام، دوبارہ کوشش کریں > 0، max.in.flight.requests.per.connection ≤ 5. اگر یہ پیرامیٹرز ڈویلپر کے ذریعہ متعین نہیں کیے گئے ہیں، تو مندرجہ بالا اقدار خود بخود سیٹ ہو جائیں گی۔

جب idempotency کو کنفیگر کیا جاتا ہے، تو اس بات کو یقینی بنانا ضروری ہے کہ ایک ہی پیغامات ہر بار ایک ہی پارٹیشنز میں ختم ہوں۔ یہ partitioner.class کلید اور پیرامیٹر کو Producer پر سیٹ کر کے کیا جا سکتا ہے۔ آئیے کلید کے ساتھ شروع کریں۔ یہ ہر جمع کرانے کے لیے یکساں ہونا چاہیے۔ اصل پوسٹ سے کسی بھی کاروباری آئی ڈی کو استعمال کر کے یہ آسانی سے حاصل کیا جا سکتا ہے۔ partitioner.class پیرامیٹر کی ایک ڈیفالٹ ویلیو ہوتی ہے۔ ڈیفالٹ پارٹیشنر. اس تقسیم کی حکمت عملی کے ساتھ، بطور ڈیفالٹ ہم اس طرح کام کرتے ہیں:

  • اگر پیغام بھیجتے وقت پارٹیشن واضح طور پر بیان کیا گیا ہے، تو ہم اسے استعمال کرتے ہیں۔
  • اگر پارٹیشن کی وضاحت نہیں کی گئی ہے، لیکن کلید کی وضاحت کی گئی ہے، تو بٹن کو کلید کے ہیش سے منتخب کریں۔
  • اگر پارٹیشن اور کلید متعین نہیں ہے تو ایک ایک کرکے پارٹیشنز کو منتخب کریں (راؤنڈ رابن)۔

اس کے علاوہ، ایک پیرامیٹر کے ساتھ ایک کلید اور idempotent بھیجنے کا استعمال کرتے ہوئے 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.

اس مسئلے کو حل کرنے کے لیے، ہم میزبان نام کی شکل میں ایپلیکیشن کے نام میں ایک لاحقہ شامل کرتے ہیں، جو ہم ماحولیاتی متغیرات سے حاصل کرتے ہیں۔

پروڈیوسر کو ترتیب دیا گیا ہے، لیکن کافکا پر لین دین صرف پیغام کے دائرہ کار کو کنٹرول کرتا ہے۔ لین دین کی حیثیت سے قطع نظر، پیغام فوری طور پر موضوع پر چلا جاتا ہے، لیکن اس میں اضافی نظام کی خصوصیات ہیں۔

اس طرح کے پیغامات کو صارف وقت سے پہلے پڑھنے سے روکنے کے لیے، اسے پیرامیٹر سیٹ کرنے کی ضرورت ہے۔ isolation.level کمٹڈ ویلیو کو پڑھنے کے لیے۔ ایسا صارف پہلے کی طرح غیر لین دین کے پیغامات اور لین دین کے پیغامات کو ایک عہد کے بعد ہی پڑھ سکے گا۔
اگر آپ نے پہلے درج تمام ترتیبات کو ترتیب دیا ہے، تو آپ نے ڈیلیوری کے بعد بالکل ٹھیک ترتیب دی ہے۔ مبارک ہو!

لیکن ایک اور nuance ہے. Transactional.id، جسے ہم نے اوپر کنفیگر کیا ہے، دراصل ٹرانزیکشن کا سابقہ ​​ہے۔ ٹرانزیکشن مینیجر پر، اس میں ایک ترتیب نمبر شامل کیا جاتا ہے۔ موصولہ شناخت کنندہ کو جاری کیا جاتا ہے۔ transactional.id.expiration.ms، جو کافکا کلسٹر پر ترتیب دیا گیا ہے اور اس کی ڈیفالٹ قدر "7 دن" ہے۔ اگر اس وقت کے دوران ایپلی کیشن کو کوئی پیغام موصول نہیں ہوا ہے، تو جب آپ اگلی ٹرانزیکشنل بھیجنے کی کوشش کریں گے تو آپ کو موصول ہوگا۔ InvalidPidMappingException. اس کے بعد ٹرانزیکشن کوآرڈینیٹر اگلی ٹرانزیکشن کے لیے ایک نیا ترتیب نمبر جاری کرے گا۔ تاہم، اگر 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

نیا تبصرہ شامل کریں