Skip to content

فصل ۱ — معرفی Kafka

آنچه در این فصل می‌آید

  • چرا ممکن است بخواهید از Kafka استفاده کنید
  • افسانه‌های رایج دربارهٔ big data و سیستم‌های پیام‌رسانی
  • موارد استفادهٔ دنیای واقعی برای پشتیبانی از پیام‌رسانی، streaming و پردازش دادهٔ IoT

با توجه به اینکه بسیاری از توسعه‌دهندگان با دنیایی پر از دادهٔ تولیدشده از هر زاویه روبه‌رو هستند، اغلب با این واقعیت مواجه می‌شوند که سیستم‌های legacy شاید بهترین گزینه برای آینده نباشند. یکی از قطعات بنیادین زیرساخت‌های دادهٔ جدید که چشم‌انداز IT را فرا گرفته، Apache Kafka® است.[^1] Kafka استانداردهای پلتفرم‌های داده را تغییر می‌دهد. راه را برای حرکت از گردش‌کارهای ETL (extract, transform, load) و batch — که در آن کار اغلب در یک زمان از پیش تعیین‌شده به‌صورت انبوه نگه داشته و پردازش می‌شد — به feedهای دادهٔ نزدیک به real-time هموار می‌کند [۱]. پردازش batch که زمانی اسب کاری استاندارد پردازش داده در سازمان‌ها بود، شاید پس از دیدن مجموعهٔ قدرتمند ویژگی‌های Kafka چیز قابل بازگشتی نباشد. در واقع، مگر اینکه رویکردی تازه اتخاذ شود، شاید نتوانید با توپ برفی رو به رشد داده‌ای که به سمت سازمان‌های هر اندازه می‌غلتد کنار بیایید.

با این همه داده، سیستم‌ها به‌راحتی overload می‌شوند. سیستم‌های legacy ممکن است با پنجره‌های پردازش شبانه‌ای روبه‌رو شوند که تا روز بعد ادامه می‌یابند. برای هم‌گام ماندن با این جریان دائمی یا در حال تکامل داده، پردازش اطلاعات در لحظهٔ وقوع راهی برای به‌روز ماندن و آگاه بودن از وضعیت سیستم است.

Kafka بسیاری از جدیدترین و عملی‌ترین روندهای امروز در حوزه‌های IT را لمس می‌کند و کار روزمره را آسان‌تر می‌سازد. برای مثال، Kafka از قبل راه خود را به طراحی microservice و اینترنت اشیا (Internet of Things یا IoT) باز کرده است. به‌عنوان فناوری de facto برای شرکت‌های فزاینده، Kafka فقط برای super geekها یا alpha-chaserها نیست. با نگاهی به ویژگی‌های Kafka، معرفی خود Kafka و درک بیشتر چهرهٔ پلتفرم‌های streaming مدرن شروع می‌کنیم.

[^1]: Apache، Apache Kafka و Kafka علائم تجاری Apache Software Foundation هستند.

۱.۱ Kafka چیست؟

سایت Apache Kafka (http://kafka.apache.org/intro) Kafka را به‌عنوان یک پلتفرم streaming توزیع‌شده تعریف می‌کند. سه قابلیت اصلی دارد:

  • خواندن و نوشتن recordها مانند یک message queue
  • ذخیرهٔ recordها با fault tolerance
  • پردازش streamها در لحظهٔ وقوع [۲]

خوانندگانی که با queueها یا message brokerها در کار روزمره‌شان آشنایی کمتری دارند، ممکن است در بحث دربارهٔ هدف کلی و جریان چنین سیستمی به کمک نیاز داشته باشند. به‌طور کلی، بخش هسته‌ای Kafka را می‌توان معادل IT یک receiver در سیستم سرگرمی خانگی دانست. شکل ۱-۱ جریان داده بین receiverها و کاربران نهایی را نشان می‌دهد.

شکل ۱-۱. نمای کلی producerها، receiverها و جریان داده

Producerها و منابع داده: VCR، Blu-ray، Satellite — جریان داده به receiver مرکزی — سپس جریان داده به Speaker 1، TV و Speaker 2 — مصرف‌کنندگان نهایی داده

همان‌طور که شکل ۱-۱ نشان می‌دهد، ماهوارهٔ دیجیتال، کابل و پخش‌کننده‌های Blu-ray™ می‌توانند به یک receiver مرکزی متصل شوند. می‌توانید آن قطعات منفرد را به‌عنوان منبع‌هایی در نظر بگیرید که به‌طور منظم داده را در قالبی که می‌شناسند ارسال می‌کنند. آن جریان داده را می‌توان تقریباً ثابت در نظر گرفت، در حالی که فیلم یا CD در حال پخش است. receiver با این جریان ثابت داده سر و کار دارد و آن را به قالب قابل استفاده برای دستگاه‌های خارجی متصل به طرف دیگر تبدیل می‌کند (receiver تصویر را به تلویزیون و صدا را هم به decoder و هم به بلندگوها می‌فرستد). پس این دقیقاً چه ربطی به Kafka دارد؟ همان رابطه را از منظر Kafka در شکل ۱-۲ ببینید.

شکل ۱-۲. جریان Kafka از producerها به consumerها

DVD 1 Producer، DVD 2 Producer، DVD 3 Producer — منبع داده مانند ماهواره، DVD یا Blu-ray player در Kafka producer نامیده می‌شود — Kafka cluster (receiver) — TV 1 consumer، TV 2 consumer، Stereo consumer — TV و استریوهایی که از داده استفاده می‌کنند در Kafka consumer نامیده می‌شوند

Kafka شامل clientهایی برای ارتباط با سیستم‌های دیگر است. یکی از انواع client، producer نامیده می‌شود که چندین جریان داده را به brokerهای Kafka می‌فرستد. brokerها عملکردی مشابه receiver در شکل ۱-۱ دارند. Kafka همچنین consumerها را شامل می‌شود؛ clientهایی که می‌توانند داده را از brokerها بخوانند و پردازش کنند. داده محدود به یک مقصد واحد نیست. producerها و consumerها کاملاً decouple شده‌اند و به هر client اجازه می‌دهند مستقل کار کند. جزئیات نحوهٔ انجام این کار را در فصل‌های بعد بررسی می‌کنیم.

همان‌طور که سایر پلتفرم‌های پیام‌رسانی، Kafka (به‌صورت ساده‌شده) مانند واسطه‌ای برای دادهٔ ورودی به سیستم (از producerها) و خروجی از سیستم (برای consumerها یا کاربران نهایی) عمل می‌کند. decoupling شل را می‌توان با اجازه دادن به این جداسازی بین producer و کاربر نهایی پیام به دست آورد. producer می‌تواند هر پیامی که بخواهد بفرستد و همچنان هیچ اطلاعی از اینکه کسی subscribe کرده یا نه نداشته باشد. علاوه بر این، Kafka راه‌های مختلفی برای تحویل پیام دارد تا با مورد کسب‌وکار شما سازگار باشد. تحویل پیام در Kafka حداقل سه روش زیر را پشتیبانی می‌کند [۳]:

  • At-least-once semantics — پیام تا زمان acknowledge شدن، در صورت نیاز ارسال می‌شود.
  • At-most-once semantics — پیام فقط یک‌بار ارسال می‌شود و در صورت شکست دوباره ارسال نمی‌شود.
  • Exactly-once semantics — پیام فقط یک‌بار توسط consumer پیام دیده می‌شود.

بیایید ببینیم این گزینه‌های پیام‌رسانی چه معنایی دارند. ابتدا at-least-once semantics (شکل ۱-۳). در این حالت، Kafka را می‌توان طوری پیکربندی کرد که producer پیام‌ها اجازه دهد همان پیام را بیش از یک‌بار بفرستد و روی brokerها نوشته شود. اگر پیام تضمینی دریافت نکند که روی broker نوشته شده، producer می‌تواند پیام را دوباره بفرستد [۳]. برای مواردی که نمی‌توانید پیامی را از دست بدهید — مثلاً کسی فاکتور پرداخت کرده — این تضمین ممکن است نیاز به فیلتر کردن در سمت consumer داشته باشد، اما یکی از امن‌ترین روش‌های تحویل است.

شکل ۱-۳. جریان پیام at-least-once

اگر پیام از producer شکست بخورد یا acknowledge نشود، producer پیام را دوباره می‌فرستد — broker حداقل دو پیام (یا فقط یکی در صورت شکست) می‌بیند — consumerها به‌اندازهٔ پیام‌هایی که broker دریافت می‌کند پیام می‌گیرند و ممکن است duplicate ببینند

At-most-once semantics (شکل ۱-۴) وقتی است که producer پیام را یک‌بار بفرستد و هرگز retry نکند. در صورت شکست، producer جلو می‌رود و دوباره تلاش نمی‌کند [۳]. چرا کسی با از دست دادن پیام کنار بیاید؟ اگر وب‌سایت محبوبی page view بازدیدکنندگان را ردیابی کند، شاید از دست دادن چند رویداد page view از میان میلیون‌ها مورد در روز قابل قبول باشد. حفظ عملکرد سیستم و منتظر acknowledge ماندن ممکن است از هزینهٔ دادهٔ از دست‌رفته مهم‌تر باشد.

Kafka exactly-once semantics، معروف به EOS، را در نسخهٔ ۰.۱۱.۰ به مجموعهٔ ویژگی‌ها افزود. EOS با انتشارش بحث‌های متنوعی ایجاد کرد [۳]. از یک سو، exactly-once semantics (شکل ۱-۵) برای بسیاری از موارد استفاده ایده‌آل است. این تضمین منطقی برای حذف duplicate به نظر می‌رسید. اما بیشتر توسعه‌دهندگان قدردان ارسال یک پیام و دریافت همان پیام در سمت consumer هستند.

شکل ۱-۴. جریان پیام at-most-once

اگر پیام از producer شکست بخورد یا acknowledge نشود، producer پیام را دوباره نمی‌فرستد — broker حداکثر یک پیام (یا صفر در صورت شکست) می‌بیند — consumerها پیام‌هایی را می‌بینند که broker دریافت کرده؛ در صورت شکست، consumer هرگز آن پیام را نمی‌بیند

شکل ۱-۵. جریان پیام exactly-once

اگر پیام از producer شکست بخورد یا acknowledge نشود، producer پیام را دوباره می‌فرستد — broker فقط یک پیام را مجاز می‌داند — consumerها پیام را فقط یک‌بار می‌بینند — دربارهٔ exactly-once semantics بعداً بیشتر بحث می‌کنیم

بحث دیگری که پس از انتشار EOS دنبال شد، این بود که آیا exactly once اصلاً ممکن است. اگرچه این به نظریهٔ عمیق‌تر علوم کامپیوتر می‌رود، آگاه بودن از تعریف Kafka برای ویژگی EOS مفید است [۴]. اگر producer پیام را بیش از یک‌بار بفرستد، همچنان فقط یک‌بار به consumer نهایی تحویل می‌شود. EOS در همهٔ لایه‌های Kafka — producerها، topicها، brokerها و consumerها — نقاط تماس دارد و بعداً در این کتاب به‌اختصار بررسی می‌شود.

علاوه بر گزینه‌های مختلف تحویل، مزیت رایج دیگر message broker این است که اگر برنامهٔ consuming به‌دلیل خطا یا نگهداری down باشد، producer نیازی ندارد منتظر consumer برای پردازش پیام بماند. وقتی consumerها دوباره online می‌شوند و داده را پردازش می‌کنند، باید بتوانند از جایی که رها کرده بودند ادامه دهند و هیچ پیامی را از دست ندهند.

۱.۲ کاربرد Kafka

با توجه به اینکه بسیاری از شرکت‌های سنتی با چالش فناوریک‌تر و software-driven شدن روبه‌رو هستند، یک سؤال در اولویت است: چگونه برای آینده آماده می‌شوند؟ یک پاسخ ممکن Kafka است. Kafka به‌عنوان یک workhorse تحویل پیام با کارایی بالا شناخته می‌شود که replication و fault tolerance را به‌صورت پیش‌فرض دارد.

با Kafka، نیازهای عظیم پردازش داده در production مدیریت می‌شوند [۵]. همهٔ این‌ها با ابزاری که تا ۲۰۱۷ به نسخهٔ ۱.۰ نرسیده بود! با این حال، علاوه بر این حقایق headline-grabbing، چرا کاربران باید به Kafka نگاه کنند؟

۱.۲.۱ Kafka برای توسعه‌دهنده

چرا یک توسعه‌دهندهٔ نرم‌افزار به Kafka علاقه‌مند باشد؟ استفاده از Kafka در حال انفجار است و تقاضای توسعه‌دهنده برآورده نمی‌شود [۶]. تغییر در شیوهٔ سنتی تفکر پردازش داده لازم است. تجربیات مشترک یا دردهای گذشته می‌تواند به توسعه‌دهندگان نشان دهد چرا Kafka گام جذابی در معماری داده‌شان باشد.

یکی از on-rampهای مختلف برای توسعه‌دهندگان تازه‌کار Kafka، اعمال چیزهایی است که می‌دانند تا با ناشناخته‌ها کنار بیایند. برای مثال، توسعه‌دهندگان Java® می‌توانند از مفاهیم Spring® استفاده کنند و Spring for Kafka با Dependency Injection (DI) (https://projects.spring.io/spring-kafka) از چند نسخهٔ major عبور کرده است. پروژه‌های پشتیبان و خود Kafka اکوسystem ابزار در حال رشد خود را دارند.

به‌عنوان یک توسعه‌دهندهٔ معمولی، بیشتر برنامه‌نویسان احتمالاً با چالش coupling روبه‌رو شده‌اند. مثلاً می‌خواهید تغییری در یک برنامه بدهید، اما برنامه‌های زیادی مستقیماً به آن وابسته‌اند. یا هنگام unit test تعداد زیادی mock باید بسازید. Kafka، اگر با دقت به کار گرفته شود، در این موارد کمک می‌کند.

مثلاً سیستم HR که کارمندان مرخصی با حقوق ثبت می‌کنند. اگر به سیستم CRUD (create, read, update, delete) عادت دارید، ثبت مرخصی احتمالاً نه‌تنها توسط payroll بلکه توسط نمودار burndown پروژه برای پیش‌بینی کار پردازش می‌شود. آیا دو برنامه را به هم وصل می‌کنید؟ اگر سیستم payroll down شود، آیا باید روی availability ابزار پیش‌بینی تأثیر بگذارد؟

با Kafka مزایای decouple کردن برخی برنامه‌هایی را می‌بینیم که در طراحی‌های قدیمی به هم گره خورده‌اند. (مدل داده را عمیق‌تر در فصل ۱۱ بررسی می‌کنیم.) Kafka می‌تواند در وسط گردش‌کار قرار گیرد [۷]. رابط شما با داده Kafka می‌شود، نه APIها و پایگاه‌های دادهٔ متعدد.

برخی می‌گویند راه‌حل‌های بهتر و ساده‌تری هست. استفاده از ETL برای حداقل بارگذاری داده در پایگاه داده برای هر برنامه چطور؟ فقط یک interface per application و آسان، درست؟ اما اگر منبع اولیهٔ داده corrupted یا outdated باشد چه؟ چقدر به‌روزرسانی‌ها را جستجو می‌کنید و lag یا consistency را می‌پذیرید؟ آیا آن کپی‌ها outdated می‌شوند یا آن‌قدر از منبع فاصله می‌گیرند که اجرای دوبارهٔ همان flow نتیجهٔ یکسان ندهد؟ source of truth چیست؟ Kafka می‌تواند از این مشکلات جلوگیری کند.

موضوع جالب دیگر که به استفاده از Kafka اعتبار می‌بخشد، میزان «dogfooding» آن است. مثلاً وقتی consumerها را در فصل ۵ بررسی می‌کنیم، می‌بینیم Kafka داخلاً از topicها برای مدیریت offsetهای consumer استفاده می‌کند. پس از انتشار v0.11، exactly-once semantics برای Kafka هم از topicهای داخلی استفاده می‌کند. داشتن چند consumer داده از یک پیام، نتایج زیادی را ممکن می‌سازد.

سؤال دیگر توسعه‌دهنده: چرا Kafka Streams، ksqlDB، Apache Spark™ Streaming یا پلتفرم‌های دیگر را یاد نگیریم و core Kafka را رد کنیم؟ تعداد برنامه‌هایی که داخلاً از Kafka استفاده می‌کنند واقعاً چشمگیر است. اگرچه لایه‌های abstraction اغلب مفیدند (و گاهی با این همه قطعه متحرک تقریباً ضروری‌اند)، معتقدیم خود Kafka ارزش یادگیری دارد.

تفاوت بین دانستن اینکه Kafka گزینهٔ channel برای Apache Flume™ است و فهمیدن معنای همهٔ گزینه‌های config وجود دارد. اگرچه Kafka Streams می‌تواند مثال‌های این کتاب را ساده کند، جالب است Kafka Streams قبل از معرفی‌اش چقدر موفق بود. پایهٔ Kafka بنیادی است و امیدواریم بفهمید چرا در برخی برنامه‌ها استفاده می‌شود و داخلاً چه می‌گذرد. اگر می‌خواهید در streaming expert شوید، شناخت بخش‌های توزیع‌شدهٔ زیربنایی برنامه‌ها و همهٔ knobهایی که می‌توانید برای fine-tune کردن بچرخانید مهم است. از منظر فنی، موضوعات هیجان‌انگیز علوم کامپیوتر به‌صورت عملی به کار رفته‌اند. شاید پربحث‌ترینشان مفهوم distributed commit log است که در فصل ۲ عمیق بررسی می‌کنیم، و یکی از علاقه‌مندی‌های شخصی، hierarchical timing wheels [۸]. این مثال‌ها نشان می‌دهند Kafka چگونه مسئلهٔ scale را با ساختار دادهٔ جالب برای حل مسئلهٔ عملی مدیریت می‌کند.

همچنین open source بودن آن برای کاوش در source code و داشتن documentation و مثال با جستجو در اینترنت مثبت است. منابع محدود به دانش داخلی یک محل کار خاص نیست.

۱.۲.۲ توضیح Kafka برای مدیر

اغلب اعضای C-suite کلمهٔ Kafka را می‌شنوند و بیشتر از نامش گیج می‌شوند تا اینکه به کارکردش اهمیت دهند. شاید خوب باشد ارزش این محصول را توضیح دهید. همچنین خوب است از تصویر بزرگ‌تر added value واقعی این ابزار فاصله بگیرید.

یکی از مهم‌ترین ویژگی‌های Kafka توانایی گرفتن حجم زیاد داده و در دسترس قرار دادنش برای واحدهای مختلف کسب‌وکار است. چنین backbone داده‌ای که اطلاعات ورودی به سازمان را برای همهٔ حوزه‌های کسب‌وکار در دسترس می‌گذارد، انعطاف و openness در مقیاس کل شرکت را ممکن می‌سازد. چیزی prescribe نشده، اما دسترسی بیشتر به داده نتیجهٔ بالقوه است. بیشتر مدیران هم می‌دانند با flood شدن داده بیش از ever، شرکت insight را هرچه سریع‌تر می‌خواهد. به‌جای پرداخت برای کهنه شدن داده روی disk، ارزشش را می‌توان هنگام ورود استخراج کرد. Kafka راهی برای دور شدن از batch job روزانه است که محدود می‌کند داده چقدر سریع به ارزش تبدیل شود. fast data اصطلاح جدیدتری است که hint می‌دهد ارزش real روی چیزی متفاوت از وعده‌های big data به تنهایی متمرکز است.

اجرای روی Java virtual machine (JVM®) برای بسیاری از shopهای توسعهٔ سازمانی آشنا و راحت است. توانایی اجرای on-premises برای برخی که داده‌شان نیاز به نظارت on-site دارد، driver حیاتی است. cloud و پلتفرم‌های managed هم گزینه‌اند. Kafka می‌تواند horizontal scale شود و فقط به vertical scaling که شاید به peak گران برسد وابسته نباشد.

شاید یکی از مهم‌ترین دلایل یادگیری Kafka دیدن این باشد که startupها و دیگران در صنعتشان چگونه هزینهٔ once prohibitive قدرت محاسباتی را پشت سر می‌گذارند. به‌جای تکیه بر سرور بزرگ‌تر و beefier یا mainframe که میلیون‌ها دلار هزینه دارد، برنامه‌ها و معماری‌های توزیع‌شده رقبا را با outlay مالی کمتر — امیدواریم — سریع در دسترس قرار می‌دهند.

۱.۳ افسانه‌های Kafka

وقتی فناوری جدیدی یاد می‌گیرید، طبیعی است دانش موجود را به مفاهیم جدید map کنید. اگرچه این تکنیک در یادگیری Kafka قابل استفاده است، می‌خواهیم رایج‌ترین سوءبرداشت‌هایی را که در کارمان دیده‌ایم یادآور شویم.

۱.۳.۱ Kafka فقط با Hadoop® کار می‌کند

همان‌طور که گفته شد، Kafka ابزار قدرتمندی است که در موقعیت‌های مختلف استفاده می‌شود. با این حال، وقتی در اکوسystem Hadoop استفاده می‌شد روی radarها ظاهر شد و شاید برای کاربران اولین‌بار به‌عنوان بخشی از suite Cloudera™ یا Hortonworks™ دیده شد. شنیدن افسانهٔ «Kafka فقط با Hadoop کار می‌کند» غیرمعمول نیست. چه چیزی این سردرگمی را ایجاد می‌کند؟ یکی از علل احتمالاً ابزارهای مختلفی است که Kafka را در محصولاتشان استفاده می‌کنند. Spark Streaming و Flume نمونه‌هایی از ابزارهایی هستند که Kafka را استفاده می‌کنند (یا در یک مقطع استفاده می‌کردند) و با Hadoop هم قابل استفاده‌اند. وابستگی (بسته به نسخهٔ Kafka) به Apache ZooKeeper™ که اغلب در clusterهای Hadoop یافت می‌شود، Kafka را بیشتر به این افسانه گره می‌زند.

افسانهٔ بنیادین دیگر این است که Kafka به Hadoop Distributed Filesystem (HDFS) نیاز دارد. اینطور نیست. وقتی بفهمیم Kafka چگونه کار می‌کند، می‌بینیم سرعت و تکنیک‌های پردازش event احتمالاً با NodeManager در وسط فرایند خیلی کندتر می‌شوند. همچنین block replication که معمولاً بخشی از HDFS است، به همان شکل انجام نمی‌شود. مثلاً در Kafka، replicaها به‌صورت پیش‌فرض recover نمی‌شوند. هر دو محصول replication را به روش‌های مختلف استفاده می‌کنند، اما durability که برای Kafka market می‌شود ممکن است به‌راحتی زیر تم Hadoop — انتظار failure به‌عنوان پیش‌فرض و برنامه‌ریزی برای غلبه — گروه‌بندی شود و هدف کلی مشابهی بین Hadoop و Kafka دارد.

۱.۳.۲ Kafka همان message brokerهای دیگر است

افسانهٔ بزرگ دیگر این است که Kafka فقط یک message broker دیگر است. مقایسهٔ مستقیم ویژگی‌های ابزارهای مختلف (مثل RabbitMQ™ از Pivotal یا MQSeries® از IBM) با Kafka اغلب با asterisk (یا fine print) همراه است و همیشه fair به بهترین use caseهای هر کدام نیست. برخی ابزارها با زمان ویژگی‌های جدید می‌گیرند همان‌طور که Kafka exactly-once semantics را اضافه کرد. و config پیش‌فرض را می‌توان تغییر داد تا ویژگی‌ها به ابزارهای هم‌فضا نزدیک‌تر شوند. به‌طور کلی، برخی از هیجان‌انگیزترین و متمایزترین ویژگی‌هایی که بعداً بررسی می‌کنیم:

  • توانایی replay پیام‌ها به‌صورت پیش‌فرض
  • پردازش موازی داده

Kafka برای داشتن چند consumer طراحی شد. یعنی یک برنامه که پیام را از message broker می‌خواند، آن را از برنامه‌های دیگری که می‌خواهند consume کنند حذف نمی‌کند. یکی از اثرات این است که consumerای که پیام را دیده می‌تواند دوباره آن (و پیام‌های دیگر) را بخواند. در برخی مدل‌های معماری مثل lambda (فصل ۸)، اشتباه برنامه‌نویس به اندازهٔ failure سخت‌افزار انتظار می‌رود. تصور کنید میلیون‌ها پیام consume کرده‌اید و فراموش کرده‌اید از فیلد خاصی از پیام اصلی استفاده کنید. در برخی queueها پیام حذف یا به duplicate/replay location فرستاده می‌شود. اما Kafka راهی می‌دهد consumerها به نقاط خاص seek کنند و پیام‌ها را دوباره بخوانند (با چند محدودیت) فقط با seek به موقعیت قبلی‌تر روی topic.

همان‌طور که به‌اختصار اشاره شد، Kafka پردازش موازی داده را اجازه می‌دهد و می‌تواند چند consumer روی یک topic داشته باشد. Kafka همچنین مفهوم consumer group دارد که در فصل ۵ عمیق پوشش داده می‌شود. عضویت در group تعیین می‌کند کدام consumerها کدام پیام‌ها را می‌گیرند و چه کاری در آن group انجام شده. consumer groupها مستقل از هر group دیگر عمل می‌کنند و به چند برنامه اجازه می‌دهند پیام‌ها را با سرعت خود و با هر تعداد consumer لازم consume کنند. پردازش به روش‌های مختلف می‌تواند باشد: consumption توسط چند consumer روی یک برنامه یا consumption توسط چند برنامه. فارغ از آنچه message brokerهای دیگر پشتیبانی می‌کنند، اکنون روی use caseهای robust که Kafka را به یکی از گزینه‌هایی تبدیل کرده که توسعه‌دهندگان برای انجام کار به سراغش می‌روند تمرکز می‌کنیم.

۱.۴ Kafka در دنیای واقعی

اعمال Kafka در کار عملی هدف اصلی این کتاب است. یکی از نکات دربارهٔ Kafka این است که سخت است بگوییم یک کار خاص را عالی انجام می‌دهد؛ در بسیاری از استفاده‌های خاص excel می‌کند. اگرچه ابتدا باید چند ایدهٔ پایه را بگیریم، شاید مفید باشد در سطح بالا برخی مواردی را که Kafka در use caseهای دنیای واقعی برایش شناخته شده بحث کنیم. سایت Apache Kafka حوزه‌های کلی استفادهٔ Kafka در دنیای واقعی را فهرست می‌کند که در کتاب بررسی می‌کنیم [۹].

۱.۴.۱ مثال‌های اولیه

اولین تجربهٔ برخی کاربران با Kafka (مثل من) استفاده از آن به‌عنوان ابزار پیام‌رسانی بود. شخصاً پس از سال‌ها استفاده از ابزارهایی مثل IBM® WebSphere® MQ (قبلاً MQ Series)، Kafka (که در آن زمان حدود نسخهٔ ۰.۸.۳ بود) برای گرفتن پیام از نقطهٔ A به B ساده به نظر می‌رسید. Kafka از پروتکل‌ها و استانداردهای محبوب — مثل Extensible Messaging and Presence Protocol (XMPP)، Java Message Service (JMS) API (اکنون بخشی از Jakarta EE) یا OASIS® Advanced Message Queuing Protocol (AMQP) — چشم‌پوشی کرده و به‌جای آن از پروتکل binary TCP سفارشی استفاده می‌کند. بعداً استفاده‌های پیچیده‌تر را می‌بینیم.

برای کاربر نهایی که با client Kafka توسعه می‌دهد، بیشتر جزئیات در configuration است و logic نسبتاً straightforward می‌شود (مثلاً «می‌خواهم پیامی روی این topic بگذارم»). داشتن channel بادوام برای ارسال پیام هم دلیل استفاده از Kafka است.

اغلب ذخیرهٔ داده در RAM برای محافظت از داده کافی نیست؛ اگر آن سرور بمیرد، پیام‌ها پس از reboot persist نمی‌شوند. high availability و persistent storage از ابتدا در Kafka ساخته شده‌اند. Apache Flume گزینهٔ Kafka channel دارد چون replication و availability اجازه می‌دهد eventهای Flume بلافاصله پس از crash agent Flume (یا سروری که روی آن اجرا می‌شود) برای sinkهای دیگر در دسترس باشند [۱۰]. Kafka برنامه‌های robust می‌سازد و failureهای مورد انتظار برنامه‌های توزیع‌شده را مدیریت می‌کند.

log aggregation (شکل ۱-۶) در بسیاری موقعیت‌ها مفید است، از جمله جمع‌آوری eventهای برنامه‌ای که در برنامه‌های توزیع‌شده نوشته شده‌اند.

شکل ۱-۶. log aggregation در Kafka

Kafka نقطهٔ مرکزی منطقی برای همهٔ logهای سرور است و اطلاعات را روی brokerها ذخیره می‌کند — logهای مختلف سرور به Kafka جمع می‌شوند — kinaction_audit application و Error-trending application از cluster Kafka In Action consume می‌کنند — Kafka نمای aggregate را به هر برنامه (با فرض اینکه هر برنامه بخشی از group خودش باشد) سرو می‌دهد

فایل‌های log به‌عنوان پیام به Kafka فرستاده می‌شوند و سپس برنامه‌های مختلف یک topic منطقی واحد برای consume آن اطلاعات دارند. با توانایی Kafka در مدیریت حجم زیاد داده، جمع‌آوری event از سرورها یا منابع مختلف ویژگی کلیدی است. بسته به محتوای خود event log، برخی سازمان‌ها از آن برای auditing و failure-detection trending استفاده می‌کنند. Kafka در ابزارهای logging مختلف (یا به‌عنوان گزینهٔ ورودی) هم استفاده می‌شود.

چگونه همهٔ این ورودی‌های log file به Kafka اجازه می‌دهد performance را حفظ کند بدون اینکه سرور از منابع تمام شود؟ throughput پیام‌های کوچک گاهی سیستم را overwhelm می‌کند چون پردازش هر method زمان و overhead می‌گیرد. Kafka از batching پیام برای ارسال و نوشتن داده استفاده می‌کند. نوشتن به انتهای log هم کمک می‌کند، به‌جای random access به filesystem. دربارهٔ log format پیام‌ها در فصل ۷ بیشتر بحث می‌کنیم.

۱.۴.۲ مثال‌های بعدی

microserviceها قبلاً با APIهایی مثل REST با هم صحبت می‌کردند، اما اکنون می‌توانند از Kafka برای ارتباط بین سرویس‌های asynchronous با event استفاده کنند [۱۱]. microserviceها می‌توانند Kafka را به‌عنوان interface تعاملاتشان به‌جای API callهای خاص به کار ببرند. Kafka خود را به قطعهٔ بنیادین برای دسترسی سریع توسعه‌دهندگان به داده تبدیل کرده است. اگرچه Kafka Streams اکنون برای بسیاری default محتمل است هنگام شروع کار، Kafka Streams API در ۲۰۱۶ منتشر شد، Kafka از قبل به‌عنوان راه‌حل موفق جا افتاده بود. Streams API را می‌توان لایه‌ای دانست که روی producerها و consumerها قرار می‌گیرد. این لایهٔ abstraction یک client library است که نمای سطح بالاتری از کار با داده به‌عنوان unbounded stream می‌دهد.

در انتشار Kafka 0.11، exactly-once semantics معرفی شد. بعداً با foundation محکم‌تر معنای عملی آن را پوشش می‌دهیم. با این حال، کاربرانی که workloadهای end-to-end روی Kafka با Streams API اجرا می‌کنند ممکن است از تضمین‌های تحویل hardened بهره ببرند. Streams این use case را آسان‌تر از ever برای تکمیل flow بدون overhead logic سفارشی برنامه، با اطمینان از اینکه پیام فقط یک‌بار از ابتدا تا انتهای transaction پردازش شده، می‌کند.

تعداد دستگاه‌های اینترنت اشیا (شکل ۱-۷) فقط با زمان افزایش می‌یابد. با همهٔ آن دستگاه‌ها که پیام می‌فرستند — گاهی در burst وقتی Wi-Fi یا cellular connection می‌گیرند — چیزی باید آن داده را مؤثر مدیریت کند. همان‌طور که جمع‌بندی کردیم، حجم عظیم داده یکی از حوزه‌های بحرانی است که Kafka می‌درخشد. همان‌طور که قبلاً گفتیم، پیام‌های کوچک برای Kafka مشکل نیستند. beaconها، ماشین‌ها، تلفن‌ها، خانه‌ها و غیره — همه داده می‌فرستند و چیزی باید fire hose داده را مدیریت و برای action در دسترس کند [۱۲].

شکل ۱-۷. اینترنت اشیا (IoT)

Water meter events، Door alarm sensor، Temperature gauge reading — وقتی sensorها یا beaconها Wi-Fi یا cellular signal می‌گیرند، eventهایشان را گزارش می‌کنند که ممکن است زیاد باشد — Kafka brokers — cluster Kafka برای کار با دادهٔ زیاد و پیام‌های کوچک طراحی شده — در فصل ۳ مثال IoT خودمان را داریم

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

۱.۴.۳ وقتی Kafka شاید مناسب نباشد

مهم است بدانیم اگرچه Kafka در use caseهای جالب استفاده شده، همیشه بهترین ابزار برای کار در دست نیست. برخی موارد را بررسی می‌کنیم که ابزار یا کد دیگر بهتر می‌درخشد.

اگر فقط به خلاصهٔ aggregate ماهانه یا حتی سالانه نیاز دارید چه؟ فرض کنید به view on-demand، پاسخ سریع یا حتی توانایی reprocess داده نیاز ندارید. در این موارد شاید به Kafka در کل سال برای آن کارها به تنهایی نیاز ندارید (به‌ویژه اگر آن مقدار داده به‌صورت batch یک‌جا manageable باشد). همان‌طور که همیشه، mileage شما ممکن است متفاوت باشد: آستانهٔ «batch بزرگ» برای کاربران مختلف متفاوت است.

اگر الگوی دسترسی اصلی شما به داده lookup تقریباً random است، Kafka شاید بهترین گزینه نباشد. خواندن و نوشتن linear جایی است که Kafka می‌درخشد و داده را تا حد ممکن سریع نگه می‌دارد. حتی اگر شنیده‌اید Kafka فایل index دارد، واقعاً چیزی نیست که با پایگاه دادهٔ relational با field و primary key مقایسه کنید.

به‌طور مشابه، اگر به ترتیب دقیق پیام‌ها در Kafka برای کل topic نیاز دارید، باید ببینید workload شما در آن وضعیت چقدر عملی است. برای جلوگیری از پیام‌های out-of-order، باید مراقب باشید حداکثر فقط یک producer request thread و هم‌زمان فقط یک partition در topic باشد. workaroundهای مختلفی هست، اما اگر حجم عظیم داده به strict ordering وابسته است، gotchaهای بالقوه‌ای وجود دارد وقتی متوجه شوید consumption به یک consumer per group در هر زمان محدود است.

یکی از موارد عملی دیگر این است که پیام‌های بزرگ چالش هیجان‌انگیزی هستند. اندازهٔ پیش‌فرض پیام حدود ۱ MB است [۱۳]. با پیام‌های بزرگ‌تر، فشار حافظه افزایش می‌یابد. به عبارت دیگر، تعداد کمتر پیام‌هایی که در page cache ذخیره می‌کنید می‌تواند نگران‌کننده شود. اگر قصد دارید archiveهای عظیم بفرستید، شاید راه بهتری برای مدیریت آن پیام‌ها باشد. به خاطر داشته باشید اگرچه احتمالاً می‌توانید هدف نهایی را در موقعیت‌های قبلی با Kafka به دست آورید (همیشه ممکن است)، شاید اولین انتخاب در toolbox شما نباشد.

۱.۵ منابع آنلاین برای شروع

community اطراف Kafka — به نظر ما — یکی از بهترین‌ها برای documentation در دسترس است. Kafka بخشی از Apache است (از Incubator در ۲۰۱۲ فارغ‌التحصیل شد) و documentation فعلی را در https://kafka.apache.org نگه می‌دارد.

منبع عالی دیگر Confluent® (https://www.confluent.io/resources) است. Confluent توسط خالقان اصلی Kafka تأسیس شد و فعالانه بر جهت آیندهٔ کار تأثیر می‌گذارد. آن‌ها همچنین ویژگی‌ها و پشتیبانی enterprise-specific برای شرکت‌ها می‌سازند تا streaming platform توسعه دهند. کارشان از ماهیت open source Kafka پشتیبانی می‌کند و به presentationها و lectureهایی دربارهٔ چالش‌ها و موفقیت‌های production گسترش یافته است.

وقتی در فصل‌های بعد APIها و گزینه‌های configuration بیشتری را بررسی می‌کنیم، این منابع مرجع مفیدی خواهند بود اگر جزئیات بیشتر لازم باشد، به‌جای فهرست کردن همه در هر فصل. در فصل ۲ جزئیات بیشتری کشف می‌کنیم که بتوانیم از اصطلاحات خاص استفاده کنیم و Apache Kafka را به‌شکل ملموس‌تر و hands-on بشناسیم.

خلاصه

  • Apache Kafka پلتفرم streaming است که می‌توانید برای پردازش سریع تعداد زیادی event از آن استفاده کنید.
  • اگرچه Kafka را می‌توان به‌عنوان message bus استفاده کرد، استفادهٔ فقط به‌عنوان آن از قابلیت‌های پردازش real-time داده چشم‌پوشی می‌کند.
  • Kafka شاید در گذشته با راه‌حل‌های big data دیگر associate شده باشد، اما به‌تنهایی سیستم scalable و durable فراهم می‌کند. چون از همان تکنیک‌های fault tolerant و distributed system استفاده می‌کند، Kafka با clustering capabilities خود نیازهای core زیرساخت دادهٔ مدرن را پر می‌کند.
  • در مواردی مثل streaming تعداد زیادی event مانند دادهٔ IoT، Kafka داده را سریع مدیریت می‌کند. با دادهٔ بیشتر برای برنامه‌ها، Kafka نتایج را سریع برای داده‌ای که قبلاً offline در batch پردازش می‌شد فراهم می‌کند.

منابع

  1. R. Moffatt. «The Changing Face of ETL.» Confluent blog (September 17, 2018). https://www.confluent.io/blog/changing-face-etl/ (accessed May 10, 2019).
  2. «Introduction.» Apache Software Foundation (n.d.). https://kafka.apache.org/intro (accessed May 30, 2019).
  3. Documentation. Apache Software Foundation (n.d.). https://kafka.apache.org/documentation/#semantics (accessed May 30, 2020).
  4. N. Narkhede. «Exactly-once Semantics Are Possible: Here's How Apache Kafka Does It.» Confluent blog (June 30, 2017). https://www.confluent.io/blog/exactly-once-semantics-are-possible-heres-how-apache-kafka-does-it (accessed December 27, 2017).
  5. N. Narkhede. «Apache Kafka Hits 1.1 Trillion Messages Per Day – Joins the 4 Comma Club.» Confluent blog (September 1, 2015). https://www.confluent.io/blog/apache-kafka-hits-1-1-trillion-messages-per-day-joins-the-4-comma-club/ (accessed October 20, 2019).
  6. L. Dauber. «The 2017 Apache Kafka Survey: Streaming Data on the Rise.» Confluent blog (May 4, 2017). https://www.confluent.io/blog/2017-apache-kafka-survey-streaming-data-on-the-rise/ (accessed December 23, 2017).
  7. K. Waehner. «How to Build and Deploy Scalable Machine Learning in Production with Apache Kafka.» Confluent blog (September 29, 2017). https://www.confluent.io/blog/build-deploy-scalable-machine-learning-production-apache-kafka/ (accessed December 11, 2018).
  8. Y. Matsuda. «Apache Kafka, Purgatory, and Hierarchical Timing Wheels.» Confluent blog (October 28, 2015). https://www.confluent.io/blog/apache-kafka-purgatory-hierarchical-timing-wheels (accessed December 20, 2018).
  9. «Use cases.» Apache Software Foundation (n.d.). https://kafka.apache.org/uses (accessed May 30, 2017).
  10. «Flume 1.9.0 User Guide.» Apache Software Foundation (n.d.). https://flume.apache.org/FlumeUserGuide.html (accessed May 27, 2017).
  11. B. Stopford. «Building a Microservices Ecosystem with Kafka Streams and KSQL.» Confluent blog (November 9, 2017). https://www.confluent.io/blog/building-a-microservices-ecosystem-with-kafka-streams-and-ksql/ (accessed May 1, 2020).
  12. «Real-Time IoT Data Solution with Confluent.» Confluent documentation (n.d.). https://www.confluent.io/use-case/internet-of-things-iot/ (accessed May 1, 2020).
  13. Documentation. Apache Software Foundation (n.d.). https://kafka.apache.org/documentation/#brokerconfigs_message.max.bytes (accessed May 30, 2020).