درک کارگزاران پیام آموزش مکانیک پیام رسانی با ActiveMQ و Kafka. فصل 3. کافکا

ادامه ترجمه کتاب کوچک:
درک کارگزاران پیام
نویسنده: Jakub Korab، ناشر: O'Reilly Media, Inc.، تاریخ انتشار: ژوئن 2017، شابک: 9781492049296.

قسمت قبلی ترجمه شده: درک کارگزاران پیام آموزش مکانیک پیام رسانی با ActiveMQ و Kafka. فصل 1 مقدمه

فصل 3

کافکا

کافکا توسط LinkedIn برای دور زدن برخی از محدودیت‌های واسطه‌های پیام سنتی و اجتناب از راه‌اندازی واسطه‌های پیام متعدد برای تعاملات مختلف نقطه به نقطه، که در این کتاب در بخش «افزایش و کاهش» در صفحه 28 توضیح داده شده است، ایجاد شده است. موارد استفاده لینکدین تا حد زیادی متکی به دریافت یک طرفه مقادیر بسیار زیادی از داده‌ها، مانند کلیک‌های صفحه و گزارش‌های دسترسی است، در حالی که همچنان اجازه می‌دهد این داده‌ها توسط چندین سیستم بدون تأثیر بر بهره‌وری تولیدکنندگان یا سایر مصرف‌کنندگان استفاده شود. در واقع، دلیل وجود کافکا، دستیابی به معماری پیام رسانی است که خط لوله داده جهانی توصیف می کند.

با توجه به این هدف نهایی، طبیعتا الزامات دیگری نیز پدید آمد. کافکا باید:

  • فوق العاده سریع باشید
  • هنگام کار با پیام ها پهنای باند بیشتری ارائه دهید
  • از مدل های ناشر-مشترک و نقطه به نقطه پشتیبانی کنید
  • با اضافه کردن مصرف کنندگان سرعت خود را کاهش ندهید. به عنوان مثال، عملکرد هر دو صف و موضوع در ActiveMQ با افزایش تعداد مصرف کنندگان در مقصد کاهش می یابد.
  • به صورت افقی مقیاس پذیر باشد. اگر یک کارگزاری که پیام‌ها را ادامه می‌دهد فقط می‌تواند این کار را با حداکثر سرعت دیسک انجام دهد، منطقی است که برای افزایش عملکرد از یک نمونه کارگزار فراتر برویم.
  • دسترسی به ذخیره و بازیابی پیام ها را محدود کنید

برای دستیابی به همه اینها، کافکا معماری را اتخاذ کرد که نقش و مسئولیت های مشتریان و کارگزاران پیام را بازتعریف کرد. مدل JMS بسیار بروکر محور است، جایی که کارگزار مسئولیت توزیع پیام ها را بر عهده دارد و مشتریان فقط باید نگران ارسال و دریافت پیام باشند. از سوی دیگر، کافکا مشتری محور است و مشتری بسیاری از ویژگی های یک کارگزار سنتی، مانند توزیع عادلانه پیام های مربوطه به مصرف کنندگان، در ازای یک کارگزار بسیار سریع و مقیاس پذیر را در اختیار می گیرد. برای افرادی که با سیستم‌های پیام‌رسان سنتی کار کرده‌اند، کار با کافکا نیازمند تغییر ذهنی اساسی است.
این جهت مهندسی منجر به ایجاد یک زیرساخت پیام رسانی شده است که قادر به افزایش توان عملیاتی در مقایسه با یک کارگزار معمولی است. همانطور که خواهیم دید، این رویکرد با معاوضه هایی همراه است، به این معنی که کافکا برای انواع خاصی از حجم کاری و نرم افزارهای نصب شده مناسب نیست.

مدل مقصد یکپارچه

کافکا برای برآورده کردن الزاماتی که در بالا توضیح داده شد، انتشار-اشتراک و پیام‌رسانی نقطه به نقطه را تحت یک نوع مقصد ترکیب کرده است. موضوع. این برای افرادی که با سیستم‌های پیام‌رسانی کار کرده‌اند گیج‌کننده است، جایی که کلمه «موضوع» به مکانیزم پخشی اشاره دارد که خواندن از آن (از مبحث) غیرقابل تحمل است. موضوعات کافکا را باید یک نوع مقصد ترکیبی در نظر گرفت، همانطور که در مقدمه این کتاب تعریف شده است.

در ادامه این فصل، مگر اینکه به صراحت خلاف آن را بیان کنیم، اصطلاح «موضوع» به موضوع کافکا اشاره خواهد کرد.

برای درک کامل اینکه موضوعات چگونه رفتار می کنند و چه تضمینی ارائه می کنند، ابتدا باید به نحوه اجرای آنها در کافکا نگاه کنیم.
هر موضوع در کافکا لاگ مخصوص به خود دارد.
تولیدکنندگانی که برای کافکا پیام می‌فرستند به این گزارش می‌نویسند و مصرف‌کنندگان با استفاده از اشاره‌گرهایی که دائماً به جلو حرکت می‌کنند، از لاگ می‌خوانند. کافکا به طور دوره‌ای قدیمی‌ترین بخش‌های گزارش را حذف می‌کند، چه پیام‌های آن قسمت‌ها خوانده شده باشند یا نه. بخش مرکزی طراحی کافکا این است که کارگزار اهمیتی نمی دهد که پیام ها خوانده می شوند یا نه - این مسئولیت مشتری است.

اصطلاحات "log" و "نشانگر" در ظاهر نمی شوند اسناد کافکا. این اصطلاحات شناخته شده در اینجا برای کمک به درک استفاده می شوند.

این مدل کاملاً متفاوت از ActiveMQ است که در آن پیام‌ها از تمام صف‌ها در یک گزارش ذخیره می‌شوند و کارگزار پیام‌ها را پس از خوانده شدن حذف شده علامت‌گذاری می‌کند.
بیایید اکنون کمی عمیق تر بگردیم و به گزارش تاپیک با جزئیات بیشتری نگاه کنیم.
لاگ کافکا از چندین پارتیشن تشکیل شده است (شکل 3 1). کافکا نظم دقیق در هر پارتیشن را تضمین می کند. این بدان معنی است که پیام هایی که به ترتیب خاصی در پارتیشن نوشته شده اند به همان ترتیب خوانده می شوند. هر پارتیشن به عنوان یک فایل گزارش رولینگ پیاده سازی می شود که شامل زیرمجموعه (زیرمجموعه) از تمام پیام های ارسال شده به موضوع توسط تولید کنندگان آن. موضوع ایجاد شده به طور پیش فرض شامل یک پارتیشن است. ایده پارتیشن ها ایده اصلی کافکا برای مقیاس بندی افقی است.

درک کارگزاران پیام آموزش مکانیک پیام رسانی با ActiveMQ و Kafka. فصل 3. کافکا
شکل 3-1. پارتیشن های کافکا

وقتی یک تهیه کننده پیامی به موضوع کافکا می فرستد، تصمیم می گیرد که پیام را به کدام پارتیشن ارسال کند. بعداً با جزئیات بیشتری به این موضوع خواهیم پرداخت.

خواندن پیام ها

سرویس گیرنده ای که می خواهد پیام ها را بخواند، یک اشاره گر با نام به نام را مدیریت می کند گروه مصرف کننده، که به انحراف پیام های موجود در پارتیشن افست یک موقعیت افزایشی است که در ابتدای یک پارتیشن از 0 شروع می شود. این گروه مصرف کننده که در API از طریق group_id تعریف شده توسط کاربر ارجاع داده شده است، مطابقت دارد یک مصرف کننده یا سیستم منطقی.

اکثر سیستم های پیام رسان داده ها را از مقصد با استفاده از چندین نمونه و رشته برای پردازش پیام ها به صورت موازی می خوانند. بنابراین، معمولاً موارد مصرف کننده بسیاری وجود خواهد داشت که گروه مصرف کننده یکسانی را به اشتراک می گذارند.

مشکل خواندن را می توان به صورت زیر نشان داد:

  • تاپیک چندین پارتیشن دارد
  • چندین گروه از مصرف کنندگان می توانند همزمان از یک موضوع استفاده کنند
  • گروهی از مصرف کنندگان می توانند چندین نمونه جداگانه داشته باشند

این یک مشکل چند به چند غیر پیش پا افتاده است. برای درک اینکه کافکا چگونه روابط بین گروه‌های مصرف‌کننده، نمونه‌های مصرف‌کننده و پارتیشن‌ها را مدیریت می‌کند، اجازه دهید به مجموعه‌ای از سناریوهای خواندنی به تدریج پیچیده‌تر نگاه کنیم.

مصرف کنندگان و گروه های مصرف کننده

بیایید یک موضوع با یک پارتیشن را به عنوان نقطه شروع در نظر بگیریم (شکل 3 2).

درک کارگزاران پیام آموزش مکانیک پیام رسانی با ActiveMQ و Kafka. فصل 3. کافکا
شکل 3-2. مصرف کننده از پارتیشن می خواند

هنگامی که یک نمونه مصرف کننده با group_id خود به این موضوع متصل می شود، یک پارتیشن خواندنی و یک افست در آن پارتیشن به آن اختصاص داده می شود. موقعیت این افست در کلاینت به عنوان اشاره گر به آخرین موقعیت (جدیدترین پیام) یا زودترین موقعیت (قدیمی ترین پیام) قابل تنظیم است. مصرف کننده پیام هایی را از موضوع درخواست می کند (نظرسنجی) که باعث می شود آنها به طور متوالی از گزارش خوانده شوند.
موقعیت افست مرتباً به کافکا باز می گردد و به عنوان پیام در یک موضوع داخلی ذخیره می شود جبران_مصرف کننده. برخلاف یک کارگزار معمولی، پیام‌های خوانده شده همچنان حذف نمی‌شوند، و مشتری می‌تواند برای پردازش مجدد پیام‌های مشاهده شده، افست را به عقب برگرداند.

هنگامی که یک مصرف کننده منطقی دوم با استفاده از یک group_id دیگر متصل می شود، نشانگر دومی را مدیریت می کند که مستقل از اولی است (شکل 3 3). بنابراین، یک موضوع کافکا مانند یک صف که در آن یک مصرف کننده وجود دارد و مانند یک موضوع عادی انتشار-اشتراک (pub-sub) که چندین مصرف کننده در آن مشترک می شوند عمل می کند، با این مزیت اضافه که همه پیام ها ذخیره می شوند و می توانند چندین بار پردازش شوند.

درک کارگزاران پیام آموزش مکانیک پیام رسانی با ActiveMQ و Kafka. فصل 3. کافکا
شکل 3-3. دو مصرف کننده در گروه های مصرف کننده مختلف از یک پارتیشن می خوانند

مصرف کنندگان در یک گروه مصرف کننده

هنگامی که یک نمونه مصرف کننده داده ها را از یک پارتیشن می خواند، کنترل کامل نشانگر را دارد و پیام ها را همانطور که در بخش قبل توضیح داده شد پردازش می کند.
اگر چندین نمونه از مصرف کنندگان با همان group_id به موضوعی با یک پارتیشن متصل شده باشند، نمونه ای که آخرین وصل شده است کنترل نشانگر را در اختیار خواهد داشت و از آن لحظه به بعد همه پیام ها را دریافت می کند (شکل 3 4).

درک کارگزاران پیام آموزش مکانیک پیام رسانی با ActiveMQ و Kafka. فصل 3. کافکا
شکل 3-4. دو مصرف کننده در یک گروه مصرف کننده از یک پارتیشن می خوانند

این شیوه پردازش که در آن تعداد نمونه های مصرف کننده از تعداد پارتیشن ها بیشتر است، می تواند به عنوان نوعی مصرف کننده انحصاری در نظر گرفته شود. اگر به خوشه‌بندی «فعال-غیرفعال» (یا «گرم-گرم») نمونه‌های مصرف‌کننده خود نیاز دارید، این می‌تواند مفید باشد، اگرچه اجرای چندین مصرف‌کننده به صورت موازی («فعال-فعال» یا «گرم-گرم») بسیار معمول‌تر از مصرف کنندگان در حالت آماده به کار

این رفتار توزیع پیام که در بالا توضیح داده شد می تواند در مقایسه با نحوه رفتار یک صف معمولی JMS شگفت آور باشد. در این مدل، پیام های ارسال شده به صف به طور مساوی بین دو مصرف کننده توزیع می شود.

اغلب، زمانی که چندین نمونه از مصرف کنندگان ایجاد می کنیم، این کار را یا برای پردازش پیام ها به صورت موازی، یا برای افزایش سرعت خواندن یا افزایش ثبات فرآیند خواندن انجام می دهیم. از آنجایی که فقط یک نمونه مصرف کننده می تواند داده ها را از یک پارتیشن در یک زمان بخواند، چگونه این امر در کافکا به دست می آید؟

یکی از راه‌های انجام این کار استفاده از یک نمونه مصرف‌کننده برای خواندن همه پیام‌ها و ارسال آن‌ها به Thread Pool است. در حالی که این رویکرد توان پردازشی را افزایش می دهد، پیچیدگی منطق مصرف کننده را افزایش می دهد و هیچ کاری برای افزایش استحکام سیستم خواندن انجام نمی دهد. اگر یک کپی از مصرف کننده به دلیل قطع برق یا رویداد مشابه از بین برود، آنگاه تفریق متوقف می شود.

راه متعارف حل این مشکل در کافکا استفاده از b استОپارتیشن های بیشتر

پارتیشن بندی

پارتیشن ها مکانیسم اصلی برای موازی کردن خواندن و مقیاس بندی یک موضوع فراتر از پهنای باند یک نمونه کارگزار هستند. برای درک بهتر این موضوع، اجازه دهید وضعیتی را در نظر بگیریم که در آن یک موضوع با دو پارتیشن وجود دارد و یک مصرف کننده در این موضوع مشترک شده است (شکل 3 5).

درک کارگزاران پیام آموزش مکانیک پیام رسانی با ActiveMQ و Kafka. فصل 3. کافکا
شکل 3-5. یک مصرف کننده از چندین پارتیشن می خواند

در این سناریو، به مصرف کننده کنترل روی نشانگرهای مربوط به group_id در هر دو پارتیشن داده می شود و شروع به خواندن پیام ها از هر دو پارتیشن می کند.
هنگامی که یک مصرف کننده اضافی برای همان group_id به این موضوع اضافه می شود، کافکا یکی از پارتیشن ها را از مصرف کننده اول به مصرف کننده دوم مجدداً اختصاص می دهد. پس از آن، هر نمونه از مصرف کننده از یک پارتیشن موضوع (شکل 3 6).

برای اطمینان از اینکه پیام ها به صورت موازی در 20 رشته پردازش می شوند، حداقل به 20 پارتیشن نیاز دارید. اگر پارتیشن‌های کمتری وجود داشته باشد، مصرف‌کنندگانی باقی می‌مانند که چیزی برای کار کردن ندارند، همانطور که قبلا در بحث مصرف‌کنندگان انحصاری توضیح داده شد.

درک کارگزاران پیام آموزش مکانیک پیام رسانی با ActiveMQ و Kafka. فصل 3. کافکا
شکل 3-6. دو مصرف کننده در یک گروه مصرف کننده از پارتیشن های مختلف می خوانند

این طرح پیچیدگی کارگزار کافکا را در مقایسه با توزیع پیام مورد نیاز برای حفظ صف JMS بسیار کاهش می دهد. در اینجا لازم نیست نگران نکات زیر باشید:

  • کدام مصرف کننده باید پیام بعدی را بر اساس تخصیص دور، ظرفیت فعلی بافرهای پیش واکشی یا پیام های قبلی (مانند گروه های پیام JMS) دریافت کند.
  • کدام پیام ها برای کدام مصرف کنندگان ارسال می شود و آیا در صورت خرابی باید دوباره تحویل داده شوند.

تنها کاری که کارگزار کافکا باید انجام دهد این است که در صورت درخواست مشتری، پیام‌ها را به صورت متوالی به مشتری ارسال کند.

با این حال، الزامات موازی کردن تصحیح و ارسال مجدد پیام های ناموفق از بین نمی روند - مسئولیت آنها به سادگی از کارگزار به مشتری منتقل می شود. این بدان معنی است که آنها باید در کد شما در نظر گرفته شوند.

ارسال پیام

این مسئولیت تولید کننده آن پیام است که تصمیم بگیرد به کدام پارتیشن پیام ارسال کند. برای درک مکانیسمی که توسط آن انجام می شود، ابتدا باید در نظر بگیریم که واقعاً چه چیزی را ارسال می کنیم.

در حالی که در JMS از ساختار پیام با ابرداده (سرصفحه ها و ویژگی ها) و بدنه حاوی بار (بارگذاری بار) استفاده می کنیم، در کافکا پیام این است. جفت "کلید-مقدار". محموله پیام به عنوان یک مقدار ارسال می شود. از طرف دیگر، کلید عمدتاً برای پارتیشن بندی استفاده می شود و باید حاوی باشد کلید خاص منطق کسب و کاربرای قرار دادن پیام های مرتبط در همان پارتیشن.

در فصل 2، سناریوی شرط بندی آنلاین را مورد بحث قرار دادیم که در آن رویدادهای مرتبط باید به ترتیب توسط یک مصرف کننده پردازش شوند:

  1. حساب کاربری پیکربندی شده است.
  2. پول به حساب واریز می شود.
  3. شرط بندی انجام می شود که پول را از حساب برداشت می کند.

اگر هر رویداد پیامی است که به یک موضوع ارسال شده است، کلید طبیعی شناسه حساب خواهد بود.
هنگامی که یک پیام با استفاده از API تولید کننده کافکا ارسال می شود، به یک تابع پارتیشن ارسال می شود که با توجه به پیام و وضعیت فعلی خوشه کافکا، شناسه پارتیشنی که پیام باید به آن ارسال شود را برمی گرداند. این ویژگی در جاوا از طریق رابط Partitioner پیاده سازی می شود.

این رابط به شکل زیر است:

interface Partitioner {
    int partition(String topic,
        Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster);
}

پیاده‌سازی پارتیشن از الگوریتم هش کردن همه منظوره پیش‌فرض روی کلید برای تعیین پارتیشن استفاده می‌کند، یا اگر کلیدی مشخص نشده باشد، از دور روبین استفاده می‌کند. این مقدار پیش فرض در اکثر موارد به خوبی کار می کند. با این حال، در آینده می خواهید خودتان بنویسید.

استراتژی پارتیشن بندی خود را بنویسید

بیایید به مثالی نگاه کنیم که در آن می‌خواهید ابرداده را همراه با بار پیام ارسال کنید. محموله در مثال ما دستورالعملی برای واریز به حساب بازی است. یک دستورالعمل چیزی است که ما می‌خواهیم تضمین شود که در هنگام انتقال تغییر نمی‌کند و می‌خواهیم مطمئن باشیم که فقط یک سیستم بالادستی قابل اعتماد می‌تواند آن دستورالعمل را آغاز کند. در این مورد، سیستم های ارسال و دریافت کننده در مورد استفاده از یک امضا برای احراز هویت پیام توافق می کنند.
در JMS معمولی، ما به سادگی یک ویژگی "امضای پیام" را تعریف کرده و آن را به پیام اضافه می کنیم. با این حال، کافکا مکانیزمی برای انتقال ابرداده در اختیار ما قرار نمی دهد، فقط یک کلید و یک مقدار را ارائه می دهد.

از آنجایی که مقدار یک محموله انتقال بانکی است که می‌خواهیم یکپارچگی آن را حفظ کنیم، چاره‌ای جز تعریف ساختار داده برای استفاده در کلید نداریم. با فرض اینکه برای پارتیشن بندی به شناسه حساب نیاز داریم، از آنجایی که تمام پیام های مربوط به یک حساب باید به ترتیب پردازش شوند، ساختار JSON زیر را خواهیم داشت:

{
  "signature": "541661622185851c248b41bf0cea7ad0",
  "accountId": "10007865234"
}

از آنجا که مقدار امضا بسته به بار متفاوت خواهد بود، استراتژی هش پیش‌فرض رابط Partitioner پیام‌های مرتبط را به‌طور قابل اعتمادی گروه‌بندی نمی‌کند. بنابراین، ما باید استراتژی خود را بنویسیم که این کلید را تجزیه کرده و مقدار accountId را پارتیشن بندی کند.

کافکا شامل چک‌سام‌هایی برای تشخیص خرابی پیام‌ها در فروشگاه است و دارای مجموعه کاملی از ویژگی‌های امنیتی است. با این حال، گاهی اوقات الزامات خاص صنعت، مانند مورد فوق ظاهر می شود.

استراتژی پارتیشن بندی کاربر باید اطمینان حاصل کند که تمام پیام های مرتبط به یک پارتیشن ختم می شوند. در حالی که این ساده به نظر می رسد، این نیاز را می توان به دلیل اهمیت سفارش پیام های مرتبط و میزان ثابت بودن تعداد پارتیشن ها در یک موضوع پیچیده تر کرد.

تعداد پارتیشن‌ها در یک موضوع می‌تواند در طول زمان تغییر کند، زیرا اگر ترافیک فراتر از انتظارات اولیه باشد، می‌توان آنها را اضافه کرد. بنابراین، کلیدهای پیام را می توان با پارتیشنی که در ابتدا به آن ارسال شده بود مرتبط کرد، که به معنای اشتراک گذاری یک حالت بین نمونه های تولیدکننده است.

عامل دیگری که باید در نظر گرفت توزیع یکنواخت پیام ها در بین پارتیشن ها است. به طور معمول، کلیدها به طور یکنواخت بین پیام ها توزیع نمی شوند و توابع هش توزیع عادلانه پیام ها را برای مجموعه کوچکی از کلیدها تضمین نمی کند.
توجه به این نکته مهم است که هر طور که بخواهید پیام‌ها را تقسیم کنید، خود جداکننده ممکن است نیاز به استفاده مجدد داشته باشد.

نیاز به تکثیر داده ها بین خوشه های کافکا در مکان های جغرافیایی مختلف را در نظر بگیرید. برای این منظور، کافکا یک ابزار خط فرمان به نام MirrorMaker را به همراه دارد که برای خواندن پیام ها از یک خوشه و انتقال آنها به خوشه دیگر استفاده می شود.

MirrorMaker باید کلیدهای موضوع تکرار شده را بفهمد تا نظم نسبی بین پیام‌ها را هنگام تکرار بین خوشه‌ها حفظ کند، زیرا ممکن است تعداد پارتیشن‌های آن موضوع در دو خوشه یکسان نباشد.

استراتژی های پارتیشن بندی سفارشی نسبتاً نادر هستند، زیرا هش پیش فرض یا دور رابین در اکثر سناریوها به خوبی کار می کند. با این حال، اگر به ضمانت‌های سفارش قوی نیاز دارید یا نیاز به استخراج ابرداده از محموله‌ها دارید، پارتیشن‌بندی چیزی است که باید به آن دقت کنید.

مقیاس پذیری و مزایای عملکرد کافکا از انتقال برخی از مسئولیت های کارگزار سنتی به مشتری ناشی می شود. در این مورد، تصمیم به توزیع پیام‌های مرتبط بالقوه بین چندین مصرف‌کننده که به طور موازی کار می‌کنند، گرفته می‌شود.

کارگزاران JMS نیز باید با چنین الزاماتی مقابله کنند. جالب توجه است، مکانیسم ارسال پیام‌های مرتبط به یک مصرف‌کننده، که از طریق گروه‌های پیام JMS (تغییر استراتژی متعادل‌سازی بار چسبنده (SLB)) پیاده‌سازی شده است، همچنین از فرستنده می‌خواهد پیام‌ها را به‌عنوان مرتبط علامت‌گذاری کند. در مورد JMS، کارگزار مسئول ارسال این گروه از پیام های مرتبط به یک مصرف کننده از بین تعداد زیادی است و در صورت سقوط مصرف کننده، مالکیت گروه را منتقل می کند.

قراردادهای تولیدکننده

پارتیشن بندی تنها چیزی نیست که باید هنگام ارسال پیام در نظر گرفت. بیایید نگاهی به متدهای send() کلاس Producer در Java API بیندازیم:

Future < RecordMetadata > send(ProducerRecord < K, V > record);
Future < RecordMetadata > send(ProducerRecord < K, V > record, Callback callback);

بلافاصله باید توجه داشت که هر دو روش Future را برمی گرداند که نشان می دهد عملیات ارسال بلافاصله انجام نمی شود. نتیجه این است که یک پیام (ProducerRecord) در بافر ارسال برای هر پارتیشن فعال نوشته می شود و به عنوان یک رشته پس زمینه در کتابخانه مشتری کافکا برای کارگزار ارسال می شود. در حالی که این باعث می‌شود کارها به طرز باورنکردنی سریع باشد، به این معنی است که یک برنامه بی‌تجربه می‌تواند در صورت توقف فرآیند، پیام‌ها را از دست بدهد.

مانند همیشه، راهی وجود دارد که عملیات ارسال را با هزینه عملکرد قابل اعتمادتر کند. اندازه این بافر را می توان روی 0 تنظیم کرد و رشته برنامه ارسال کننده مجبور می شود منتظر بماند تا انتقال پیام به کارگزار به صورت زیر انجام شود:

RecordMetadata metadata = producer.send(record).get();

بیشتر در مورد خواندن پیام ها

خواندن پیام ها دارای پیچیدگی های دیگری است که باید در مورد آنها حدس زد. برخلاف JMS API که می‌تواند یک شنونده پیام را در پاسخ به یک پیام اجرا کند مصرف کننده کافکا فقط نظرسنجی می کند. بیایید نگاهی دقیق تر به روش بیندازیم نظرسنجی()برای این منظور استفاده می شود:

ConsumerRecords < K, V > poll(long timeout);

مقدار برگشتی متد یک ساختار ظرف حاوی چندین شی است رکورد مصرف کننده از چندین پارتیشن بالقوه رکورد مصرف کننده خود یک شی نگهدارنده برای یک جفت کلید-مقدار با ابرداده مرتبط است، مانند پارتیشنی که از آن مشتق شده است.

همانطور که در فصل 2 بحث شد، باید به خاطر داشته باشیم که پس از پردازش موفقیت آمیز یا ناموفق پیام ها چه اتفاقی برای آنها می افتد، برای مثال، اگر مشتری قادر به پردازش پیام نباشد یا اگر پیام متوقف شود. در JMS، این کار از طریق یک حالت تصدیق انجام می شد. کارگزار یا پیامی که با موفقیت پردازش شده را حذف می کند یا پیام خام یا جعلی را مجدداً تحویل می دهد (با فرض اینکه از تراکنش ها استفاده شده باشد).
کافکا بسیار متفاوت عمل می کند. پیام‌ها پس از تصحیح در کارگزار حذف نمی‌شوند و آنچه در صورت خرابی اتفاق می‌افتد به عهده خود کد تصحیح است.

همانطور که گفتیم گروه مصرف کننده با افست در لاگ همراه است. موقعیت گزارش مربوط به این افست مربوط به پیام بعدی است که در پاسخ به آن صادر می شود نظرسنجی(). نقطه زمانی که این افست افزایش می یابد برای خواندن تعیین کننده است.

با بازگشت به مدل خواندنی که قبلاً بحث شد، پردازش پیام شامل سه مرحله است:

  1. بازیابی پیام برای خواندن
  2. پیام را پردازش کنید
  3. تایید پیام

مصرف کننده کافکا دارای یک گزینه پیکربندی است enable.auto.commit. این یک تنظیم پیش فرض است که اغلب استفاده می شود، همانطور که با تنظیمات حاوی کلمه "auto" معمول است.

قبل از کافکا 0.10، مشتری با استفاده از این گزینه، آخرین پیام خوانده شده در تماس بعدی را ارسال می کرد. نظرسنجی() پس از پردازش این بدان معناست که هر پیامی که قبلاً واکشی شده بود، می‌توانست دوباره پردازش شود، اگر مشتری قبلاً آنها را پردازش کرده باشد، اما قبل از تماس به طور غیرمنتظره‌ای از بین رفته باشد. نظرسنجی(). از آنجایی که کارگزار هیچ حالتی را در مورد تعداد دفعات خوانده شدن یک پیام حفظ نمی کند، مصرف کننده بعدی که آن پیام را بازیابی می کند متوجه نمی شود که اتفاق بدی افتاده است. این رفتار شبه معاملاتی بود. آفست فقط در صورتی انجام می شد که پیام با موفقیت پردازش شود، اما اگر مشتری سقط شود، کارگزار همان پیام را دوباره برای مشتری دیگر ارسال می کرد. این رفتار با ضمانت تحویل پیام مطابقت داشت.حد اقل یک بار".

در کافکا 0.10، کد سرویس گیرنده تغییر کرده است به طوری که commit به صورت دوره ای توسط کتابخانه مشتری، همانطور که پیکربندی شده است، راه اندازی می شود. auto.commit.interval.ms. این رفتار جایی بین حالت‌های JMS AUTO_ACKNOWLEDGE و DUPS_OK_ACKNOWLEDGE است. هنگام استفاده از Autocommit، پیام‌ها می‌توانند بدون توجه به اینکه واقعا پردازش شده‌اند، متعهد شوند - این ممکن است در مورد مصرف‌کننده کند اتفاق بیفتد. اگر مصرف‌کننده‌ای سقط شود، پیام‌ها توسط مصرف‌کننده بعدی واکشی می‌شوند که از موقعیت متعهد شروع می‌شود، که می‌تواند منجر به پیام از دست رفته شود. در این مورد، کافکا پیام ها را از دست نداده است، کد خواندن فقط آنها را پردازش نکرده است.

این حالت همان وعده نسخه 0.9 را دارد: پیام ها را می توان پردازش کرد، اما در صورت عدم موفقیت، ممکن است افست انجام نشود و به طور بالقوه باعث دو برابر شدن تحویل شود. پیام های بیشتری را هنگام اجرا واکشی می کنید نظرسنجی()، این مشکل بیشتر است.

همانطور که در «خواندن پیام‌ها از یک صف» در صفحه 21 بحث شد، وقتی حالت‌های خرابی در نظر گرفته می‌شوند، چیزی به نام تحویل یک‌باره پیام در یک سیستم پیام‌رسان وجود ندارد.

در کافکا، دو راه برای ارتکاب (ارتکاب) یک افست (افست) وجود دارد: خودکار و دستی. در هر دو مورد، اگر پیام پردازش شده باشد اما قبل از commit شکست خورده باشد، می توان پیام ها را چندین بار پردازش کرد. همچنین اگر commit در پس‌زمینه اتفاق افتاده باشد و کد شما قبل از پردازش کامل شده باشد (شاید در کافکا 0.9 و قبل‌تر) می‌توانید انتخاب کنید که اصلاً پیام را پردازش نکنید.

شما می توانید با تنظیم پارامتر، فرآیند commit offset دستی را در API مصرف کننده Kafka کنترل کنید enable.auto.commit به false و صریح فراخوانی یکی از روش های زیر:

void commitSync();
void commitAsync();

اگر می خواهید پیام "حداقل یک بار" را پردازش کنید، باید offset را به صورت دستی با آن انجام دهید commitSync()با اجرای این دستور بلافاصله پس از پردازش پیام ها.

این روش‌ها اجازه نمی‌دهند که پیام‌ها قبل از پردازش تایید شوند، اما هیچ کاری برای حذف تاخیرهای احتمالی پردازش انجام نمی‌دهند و در عین حال ظاهر تراکنشی بودن را نشان می‌دهند. هیچ معامله ای در کافکا وجود ندارد. مشتری توانایی انجام کارهای زیر را ندارد:

  • به طور خودکار یک پیام جعلی را برگردانید. مصرف کنندگان خود باید استثنائات ناشی از بارهای مشکل ساز و قطعی های پشتیبان را مدیریت کنند، زیرا نمی توانند برای ارسال مجدد پیام ها به کارگزار اعتماد کنند.
  • در یک عملیات اتمی به چندین موضوع پیام بفرستید. همانطور که به زودی خواهیم دید، کنترل بر موضوعات و پارتیشن‌های مختلف می‌تواند در ماشین‌های مختلف در خوشه کافکا باشد که هنگام ارسال، تراکنش‌ها را هماهنگ نمی‌کنند. در زمان نگارش این مقاله، کارهایی انجام شده است تا این امکان با KIP-98 فراهم شود.
  • خواندن یک پیام از یک موضوع را با ارسال پیام دیگر به موضوع دیگر مرتبط کنید. باز هم، معماری کافکا به بسیاری از ماشین های مستقل وابسته است که به صورت یک اتوبوس کار می کنند و هیچ تلاشی برای پنهان کردن این موضوع صورت نمی گیرد. به عنوان مثال، هیچ مؤلفه API وجود ندارد که به شما اجازه پیوند دهد مصرف كننده и تهیه کننده در یک معامله در JMS، این توسط شی ارائه می شود جلسهکه از آن ایجاد می شوند MessageProducers и پیام مصرف کنندگان.

اگر نمی‌توانیم به تراکنش‌ها تکیه کنیم، چگونه می‌توانیم معنایی نزدیک‌تر به آنچه توسط سیستم‌های پیام‌رسان سنتی ارائه می‌شود ارائه کنیم؟

اگر احتمال افزایش افست مصرف‌کننده قبل از پردازش پیام وجود داشته باشد، مثلاً در هنگام خرابی مصرف‌کننده، در این صورت مصرف‌کننده راهی ندارد که بفهمد گروه مصرف‌کننده‌اش پیام را زمانی که به آن پارتیشن اختصاص داده شده از دست داده است یا خیر. بنابراین یک استراتژی این است که افست را به موقعیت قبلی برگردانید. API مصرف کننده کافکا روش های زیر را برای این کار ارائه می دهد:

void seek(TopicPartition partition, long offset);
void seekToBeginning(Collection < TopicPartition > partitions);

روش جستجو () می توان با روش استفاده کرد
offsetsForTimes(نقشه مهرهای زمانی برای جستجو) برگشتن به حالتی در نقطه ای خاص در گذشته.

به طور ضمنی، استفاده از این رویکرد به این معنی است که احتمال زیادی وجود دارد که برخی از پیام‌هایی که قبلا پردازش شده‌اند دوباره خوانده و پردازش شوند. برای جلوگیری از این امر، می‌توانیم از خواندن بی‌توان، همانطور که در فصل 4 توضیح داده شد، برای پیگیری پیام‌های مشاهده شده قبلی و حذف موارد تکراری استفاده کنیم.

متناوبا، تا زمانی که پیام از دست دادن یا تکراری قابل قبول باشد، کد مصرف کننده شما می تواند ساده نگه داشته شود. وقتی به موارد استفاده ای که معمولاً از کافکا برای آنها استفاده می شود، مانند رسیدگی به رویدادهای گزارش، معیارها، ردیابی کلیک و غیره نگاه می کنیم، متوجه می شویم که از دست دادن پیام های فردی بعید است که تأثیر قابل توجهی بر برنامه های اطراف داشته باشد. در چنین مواردی، مقادیر پیش فرض کاملاً قابل قبول است. از طرف دیگر، اگر درخواست شما نیاز به ارسال پرداخت دارد، باید به دقت مراقب هر پیام فردی باشید. همه چیز به زمینه مربوط می شود.

مشاهدات شخصی نشان می دهد که با افزایش شدت پیام ها، ارزش هر پیام فردی کاهش می یابد. پیام‌های بزرگ زمانی که به صورت انبوه دیده می‌شوند ارزشمند هستند.

در دسترس بودن بالا

رویکرد کافکا به دسترسی بالا بسیار متفاوت از رویکرد ActiveMQ است. کافکا حول گروه‌های کوچک‌تر طراحی شده است که در آن تمام نمونه‌های کارگزار پیام‌ها را همزمان دریافت و توزیع می‌کنند.

یک خوشه کافکا از چندین نمونه کارگزار تشکیل شده است که بر روی سرورهای مختلف اجرا می شوند. کافکا برای اجرا بر روی سخت‌افزار مستقل معمولی طراحی شده است، جایی که هر گره فضای ذخیره‌سازی اختصاصی خود را دارد. استفاده از ذخیره سازی متصل به شبکه (SAN) توصیه نمی شود زیرا چندین گره محاسباتی می توانند برای زمان رقابت کنند.Ыفواصل ذخیره سازی و ایجاد تضاد.

کافکا است همیشه روشن سیستم. بسیاری از کاربران بزرگ کافکا هرگز خوشه های خود را خاموش نمی کنند و نرم افزار همیشه با یک راه اندازی مجدد متوالی به روز می شود. این امر با تضمین سازگاری با نسخه قبلی برای پیام ها و تعاملات بین کارگزاران به دست می آید.

کارگزاران متصل به یک خوشه سرور نگهبان باغ وحش، که به عنوان یک رجیستری داده های پیکربندی عمل می کند و برای هماهنگ کردن نقش های هر کارگزار استفاده می شود. ZooKeeper خود یک سیستم توزیع شده است که دسترسی بالایی را از طریق تکرار اطلاعات با ایجاد حد نصاب.

در حالت پایه، موضوعی در یک خوشه کافکا با ویژگی های زیر ایجاد می شود:

  • تعداد پارتیشن ها همانطور که قبلاً بحث شد، مقدار دقیق استفاده شده در اینجا به سطح مطلوب خواندن موازی بستگی دارد.
  • ضریب تکرار (عامل) تعیین می‌کند که چه تعداد از نمونه‌های کارگزار در خوشه باید شامل لاگ برای این پارتیشن باشد.

با استفاده از ZooKeepers برای هماهنگی، کافکا تلاش می کند تا پارتیشن های جدید را به طور عادلانه بین کارگزاران در خوشه توزیع کند. این کار توسط یک نمونه انجام می شود که به عنوان یک کنترلر عمل می کند.

در زمان اجرا برای هر پارتیشن موضوعی کنترل کننده نقش ها را به یک کارگزار اختصاص دهید رهبر (رهبر، استاد، مجری) و پیروان (پیروان، بردگان، زیردستان). کارگزار که به عنوان رهبر این پارتیشن عمل می کند، مسئولیت دریافت کلیه پیام های ارسال شده توسط تولید کنندگان و توزیع پیام ها را برای مصرف کنندگان بر عهده دارد. هنگامی که پیام‌ها به یک پارتیشن موضوعی ارسال می‌شوند، آن‌ها به تمام گره‌های کارگزار که به‌عنوان دنبال‌کننده برای آن پارتیشن عمل می‌کنند، کپی می‌شوند. هر گره حاوی لاگ های یک پارتیشن فراخوانی می شود المثنی، کپی دقیق. یک کارگزار می تواند به عنوان یک رهبر برای برخی از پارتیشن ها و به عنوان یک فالوور برای برخی دیگر عمل کند.

دنبال کننده ای که حاوی تمام پیام هایی است که رهبر نگه داشته می شود نامیده می شود ماکت هماهنگ شده (ماکتی که در حالت همگام سازی قرار دارد، ماکت همزمان). اگر کارگزاری که به عنوان رهبر یک پارتیشن عمل می کند از کار بیفتد، هر کارگزاری که به روز باشد یا برای آن پارتیشن هماهنگ شده باشد می تواند نقش رهبر را بر عهده بگیرد. این یک طراحی فوق العاده پایدار است.

بخشی از پیکربندی سازنده، پارامتر است آکس، که تعیین می کند چه تعداد از ماکت ها باید دریافت پیام را تأیید کنند (تایید کنند) قبل از اینکه رشته برنامه به ارسال ادامه دهد: 0، 1 یا همه. اگر تنظیم شود تمام، سپس هنگامی که یک پیام دریافت می شود، رهبر به محض دریافت تأییدیه (تأییدات) رکورد از چندین نشانه (از جمله خودش) که توسط تنظیم موضوع تعریف شده است، تأییدیه را برای تهیه کننده ارسال می کند. min.insync.replicas (پیش فرض 1). اگر پیام را نتوان با موفقیت تکرار کرد، تولید کننده یک استثنای برنامه را ایجاد می کند (NotEnoughReplicas یا NotEnoughReplicasAfterAppend).

یک پیکربندی معمولی یک موضوع با ضریب تکرار 3 (1 رهبر، 2 دنبال کننده در هر پارتیشن) و پارامتر ایجاد می کند. min.insync.replicas روی 2 تنظیم شده است. در این حالت، خوشه به یکی از کارگزارانی که پارتیشن موضوع را مدیریت می کند اجازه می دهد بدون تأثیر بر برنامه های مشتری، پایین بیاید.

این ما را به مبادله از قبل آشنا بین عملکرد و قابلیت اطمینان بازمی گرداند. تکرار به هزینه زمان انتظار اضافی برای تایید (تشکر) از طرفداران رخ می دهد. اگرچه، چون به صورت موازی اجرا می شود، تکرار به حداقل سه گره عملکردی مشابه دو گره دارد (بدون توجه به افزایش استفاده از پهنای باند شبکه).

با استفاده از این طرح تکرار، کافکا هوشمندانه از نیاز به نوشتن فیزیکی هر پیام روی دیسک با عملیات اجتناب می کند. همگام سازی (). هر پیامی که توسط سازنده ارسال می‌شود در گزارش پارتیشن نوشته می‌شود، اما همانطور که در فصل 2 بحث شد، نوشتن روی یک فایل در ابتدا در بافر سیستم عامل انجام می‌شود. اگر این پیام به نمونه دیگری از کافکا تکرار شود و در حافظه آن باشد، از دست دادن رهبر به این معنی نیست که خود پیام از بین رفته است - می‌توان آن را توسط یک ماکت همگام‌سازی شده تصاحب کرد.
امتناع از انجام عمل همگام سازی () به این معنی که کافکا می تواند پیام ها را به همان سرعتی که می تواند در حافظه بنویسد، دریافت کند. برعکس، هر چه مدت زمان بیشتری بتوانید از فلاش کردن حافظه روی دیسک جلوگیری کنید، بهتر است. به همین دلیل، تخصیص حافظه 64 گیگابایتی یا بیشتر به کارگزاران کافکا غیر معمول نیست. این استفاده از حافظه بدان معناست که یک نمونه کافکا می تواند به راحتی با سرعتی هزاران بار سریعتر از یک واسطه پیام سنتی اجرا شود.

کافکا همچنین می تواند برای اعمال عملیات پیکربندی شود همگام سازی () برای پیام دادن به بسته ها از آنجایی که همه چیز در کافکا بسته محور است، در واقع برای بسیاری از موارد استفاده به خوبی کار می کند و ابزار مفیدی برای کاربرانی است که به ضمانت های بسیار قوی نیاز دارند. بیشتر عملکرد خالص کافکا از پیام هایی است که به عنوان بسته برای کارگزار ارسال می شود و این پیام ها از طرف کارگزار در بلوک های متوالی با استفاده از آنها خوانده می شود. کپی صفر عملیات (عملیاتی که طی آن وظیفه کپی کردن داده ها از یک ناحیه حافظه به ناحیه دیگر انجام نمی شود). دومی یک عملکرد و منبع بزرگ است و تنها از طریق استفاده از یک ساختار داده log زیربنایی که طرح پارتیشن را تعریف می کند امکان پذیر است.

عملکرد بسیار بهتری در یک خوشه کافکا نسبت به یک کارگزار کافکا ممکن است، زیرا پارتیشن‌های موضوعی می‌توانند در بسیاری از ماشین‌های جداگانه بزرگ شوند.

نمایش نتایج: از

در این فصل، ما به این موضوع نگاه کردیم که چگونه معماری کافکا رابطه بین مشتریان و کارگزاران را برای ارائه یک خط لوله پیام‌رسانی فوق‌العاده قوی، با توان عملیاتی چندین برابر بیشتر از یک واسطه پیام مرسوم، تجسم می‌کند. ما در مورد عملکردی که برای دستیابی به آن استفاده می کند بحث کرده ایم و به طور خلاصه به معماری برنامه هایی که این قابلیت را ارائه می دهند نگاه کرده ایم. در فصل بعدی، ما به مشکلات رایجی که برنامه‌های کاربردی مبتنی بر پیام‌رسانی نیاز به حل آن‌ها دارند می‌پردازیم و درباره استراتژی‌های مقابله با آنها بحث می‌کنیم. ما این فصل را با تشریح نحوه صحبت در مورد فناوری های پیام رسانی به طور کلی به پایان می رسانیم تا بتوانید مناسب بودن آنها را برای موارد استفاده خود ارزیابی کنید.

قسمت قبلی ترجمه شده: درک کارگزاران پیام آموزش مکانیک پیام رسانی با ActiveMQ و Kafka. فصل 1

ترجمه انجام شد: tele.gg/middle_java

ادامه ...

فقط کاربران ثبت نام شده می توانند در نظرسنجی شرکت کنند. ورود، لطفا.

آیا از کافکا در سازمان شما استفاده می شود؟

  • بله

  • بدون

  • قبلا استفاده شده بود الان نه

  • قصد داریم استفاده کنیم

38 کاربر رای دادند. 8 کاربر رای ممتنع دادند.

منبع: www.habr.com

اضافه کردن نظر