من دوست دارم مطالبی که یاد میگیرم را با افراد دیگر نیز مطرح کنم. در حال حاضر یادگیری Kafka را شروع کرده ام و گام به گام مواردی که میخوانم را با شما مطرح میکنم. نوشتار کافکا در چند پست جداگانه ای آمده است.
در گام اول کلیاتی از ساختار و معماری کافکا بیان شده است. سپس توضیح کلی از مفاهیمی مانند broker، partition و topic شرح داده شده است. در گام دوم نحوه نصب Kafka و شرح کامل مفاهیم آن و در گام سوم نحوه تولید پیغام توسط producer و مصرف پیغام توسط consumer بیان شده است و در پایان موارد آتی برای استفاده از کافکا آمده است.
ارتباط بین بخش های مختلف یک سیستم به صورت سنتی به حالت request/response است. برای مثال یک سیستم درخواست خودرو را فرض کنین. با ارسال request از مشتری به سیستم درخواست خودرو، ابتدا این سرویس به مسیریاب، درخواست مسیر میدهد، سپس با استفاده از پاسخ آن، درخواست دیگری به سرویس قیمت دهی برای محاسبه ی هزینه ی سفر میدهد، هزینه ی سفر برای کاربر توسط این سرویس حساب شده و به عنوان پاسخ به سرویس booking بازگردانده میشود. سرویس booking نیز هزینه را در غالب response به کاربر نشان داده میشود. با ارسال request دیگری از کاربر مبنی بر تایید هزینه، سیستم request ای به سیستم توزیع کننده ی درخواست(dispatcher service) یا همان خودرو یاب ارسال میکند و خودرو یافت شده این سرویس را در غالب response دیگری برای کاربر ارسال میکند. این روند در شکل زیر نشان داده شده.
این سیستم های مبتنی بر request/response تا مدتها به علت سادگی در معماری و ساختار به خوبی جواب میداد و اکنون نیز برای سیستم های ساده تر به خوبی جوابگو است ولی در صورتی که ارتباطات بین سرویس های مختلف زیاد شود و سرویس ها با یکدیگر ارتباط دو به دو داشته باشند ما یک ارتباط بسیار پیچیده ای داریم که نگهداری آن در گذر زمان با توجه به افزودن شدن نیاز های بیزینسی و داده های جدید بسیار سخت میشود.
راه حل خلاقانه ای که برای رفع این مشکل، استفاده از نوع دیگری از انتقال پیام، به صورت producer-subscriber است. این راه حل به این صورت میباشد که پیام ها publish می شوند و علاقه مندان به آن نوع پیام خود را subscribe کرده و پیام را مصرف میکنند. ( publisher ها message ها را تولید (produce) کرده و subscriber ها آن ها مصرف (consume) میکنند.) براساس این ایده ی انتقال پیغام کافکا ایجاد شد.
کافکا در سال 2010 در LinkedIn برای هندل کردن حجم بالای user activity ایجاد شده است. سپس در سال 2011 به عنوان پروژه ی open source در اختیار عموم قرار گرفت.
کافکا یک سیستم opensource ،distributed و یک پلتفرم streaming است که تبادل داده سریع، مقیاس پذیر(scalable) و قابل اطمینان(reliable) بین بخش های مختلف انجام میدهد.
برای streaming پلتفرم بودن لازم است ویژگی های زیر را داشته باشد.
به طور کلی وظیفه ی آن انتقال داده است. در محاسبات به انتقال داده، پیغام رسانی(messaging) میگویند. بنابراین کافکا یک سیستم پیغام رسانی (messaging system) است. وجه تمایز کافکا با سایر سیستم های پیغام رسانی، امکان استفاده از آن در سیستم هایی با حجم داده های بالا که نیاز دارند مقیاس پذیر و مقاوم در مقابل خطا است. همچنین کافکا به علت سرعت بالا، قابلیت پاسخگویی در لحظه یا ارسال پیغام real-time را دارد و به علت نگهداری پیغام ها بر روی دیسک، data loss آن کم است.
شایع ترین مشکلات سیستم های پیچیده، جابجایی داده بین دو RDBM است که نمیتوان به راحتی داده بین دیتابیس های مختلف جابجا کرد. همچنین تغییر در schema یک دیتابیس نیازمند اعمال تغییر روی تمامی دیتابیسهای مرتبط و داده های کپی گرفته شده است. حجم بالای log فایلهایی که لازم است بین اپلیکیشن ها جابجا شود نیز یکی از مشکلات عمده است. به دلیل سختی در نگهداری از چنین سیستم هایی، نحوه انتقال داده از روش های پیشین به روش های نوین تری تبدیل شد.
به طور کلی کافکا یک Messaging System وtopic based publish-subscribe عمومی است. در اینجا producer ها و consumer ها میتوانند برنامه های نوشته شده ی ما باشند. در کافکا موارد و کلمات مفهومی و پایه ای وجود دارد که تعریف هر کدام از این موارد در ادامه آمده است. در سیستم topic based publish-subscribe پیغام تولید شده توسط publisher یا producer به یک topic خاص مرتبط میشوند و پیغام ها به صورت selective به subscriber یا consumer علاقه مند به همان topic میرسد.(شکل(2) ) Topic ها در حقیقت یک دسته و گروه از پیغام ها هستند. در کافکا پیغام ها توسط تولیدکنندگان برای یکی از این topic ها ارسال میشوند(send میشوند) و مصرف کننده به یکی از این topic ها subscribe میکند و پیغام ها رو دریافت میکند(poll میکند). کافکا محدودیتی در تعداد topic ها برای subscriber ندارد منتها دریافت پیغام از چند تاپیک به علت اینکه ترتیب پیغام ها تنها در یک تاپیک برقرار است، نیازمند دقت و بررسی برای نحوه ی دریافت پیام ها از چند تاپیک است. این مورد در پست های آتی شرح داده میشود.
سیستمی را فرض کنید که در هر ثانیه، 20 پیغام تولید میکند. این پیغام ها را به کافکا ارسال میکند و مصرف کننده تنها میتوان 10 پیغام در هر ثانیه process کند. بنابراین در گذر زمان این پیغام ها ذخیره شده و به صورت آنی به دست کاربر نمیرسد. برای رفع این مشکل تعداد مصرف کنندگان زیاد میکنیم ولی لازم است کافکا پیغام های رسیده به یک مصرف کننده را به مصرف کننده ی دیگری مجدد ارسال نکند، چون اینها با هم برای انجام یک task در یک گروه قرار گرفته اند.
کافکا برای اینکه ارسال همزمان پیغام های هر تاپیک به چند مصرف کننده را هندل کند، لازم است بداند به هر مصرف کننده چه پیغامی ارسال شده است و بتواند همزمان به چند مصرف کننده پیغام ارسال کند. مصرف کننده به ازای هر دریافت پیغام، یک ACK برای کافکا مبنی بر دریافت پیغام ارسال میکند. بنابراین کافکا میداند که تا کجا برای consumer ارسال کرده است و آن را جایی نگه میدارد و خود پیغام را فارغ از رسیدن و مصرف شدن توسط consumer در صف خود نگه میدارد. راه حل کافکا برای اینکه پیغام مشترک به همه ی consumer های یک task ارسال نکند، هر topic را به یک یا چند partition تقسیم میکند و برای هر consumer پیغام های همان partition را ارسال میکند. هر پارتیشن به صورت یک فولدر نگه داری میشود که درون آن دو فایل وجود دارد. یکی برای Index ها و یکی برای ذخیره سازی داده ها.
مصرف کنندگانی که یک task یکسان را انجام میدهند، لازم است پیغام های تکراری دریافت نکنند ولی ممکن استconsumer دیگری اضافه شود که لازم باشد تمامی پیغام ها را دریافت کند. برای هندل کردن اینکار کافکا مصرف کنندگان را به صورت دسته ای تقسیم میکند که به آنها consumer group میگویند. در هنگام ایجاد مصرف کننده با استفاده از متغیری به نام group.id، مشخص میشود که کدام یک از consumer ها در یک دسته قرار دارند. در صورتی که consumer دیگری برای انجام task در کنار این consumer ها اضافه شود و کافکا متوجه شود که این consumer برای انجام تسک یکسانی با بقیه است (consumer group یکسان)، لازم است partition جدیدی به آن اختصاص یابد. به این فرآیند partition rebalance گفته میشود. در صورتی که یک consumer نیز crash کند، partition ها بین consumer های دیگر rebalance میشوند.
در صورتی که بیشتر از تعداد partition ها در یک consumer group، مصرف کننده ای اضافه شود، partitionای به آن اختصاص نمی یابد بنابراین استفاده ای از آن نمیشود. برای مثال consumer4 در شکل زیر پیغامی دریافت نمیکند و idle باقی میماند زیرا کافکا گارانتی کرده است که حداکثر یک consumer به یک partition اختصاص یابد. بنابراین تعداد partition ها مشخص میکند چه تعداد consumer ها میتواند scale شود.
هر پیغام تولید شده یک Topic، key، value و partition دارد. پیغام ها براساس شماره partition در یکی از صف های پیغام آن partition قرار میگیرند. پیغام های ذخیره شده در هر partition یک index مخصوص به خود دارند که به آن offset میگویند. کافکا با استفاده از این offset ترتیب پیغام ها را هندل میکند و consumer ها از هر offset ای که تقاضا دهند میتوانند پیغام را بخوانند. پیغام ها در این partition ها یک مدت زمان مشخصی نگهداری میشوند و بعد از آن از این لیست پاک میشوند و هر پیغامی که به کافکا ارسال میشود در نهایت در یکی از partition ها ذخیره میشود.
سروری که این پیغام های تولید شده را گرفته، نگهداری کرده و به دست consumer میرساند، broker نام دارد. هر broker شامل یک یا چند topic است. بروکر ها پیغام ها در فایل هایی log میکنند، مثل فولدرها هستن که پیغام ها را به صورت فایلهایی نگهداری میکنن. broker ها مانند سرور هستند. تفاوت broker و سرور در این است که سرور میتواند با آمدن تقاضاهای زیاد overload شود ولی در کافکا به علت اینکه پیغام های هر topic، فارغ از مصرف شدن و رسیدن به دست consumer به مقدار زمان قابل تنظیمی ذخیره میشود و بعد از آن از بین میرود overload نخواهد شد. در کافکا به broker ها worker node یا به اختصار node نیز میگویند.(شکل (3))
تعریف cluster: به زبان ساده، cluster گروهی از broker ها میباشد. (شکل(4))
نکته ی قابل توجه در اینجا این است که کافکا برای ارتباط و interaction بخش های مختلف استفاده میشود و نه به عنوان دیتابیسی برای ذخیره سازی داده ها چون داده ها به طور دائم در کافکا ذخیره نمیشود. برای ذخیره سازی داده ها میتوان سرویسی برای ذخیره سازی داده ها در پایگاه داده داشت که در صورت لزوم و اهمیت داده ها برای مثال داده های بانکی، آنها را در پایگاه داده ذخیره کرد تا در موارد آتی برای همیشه به آنها رفرنس داشت و یا داده ها را بازیابی کرد.
در این پست برخی مفاهیم و ویژگی های کافکا و مختصری از معماری آن بیان شد. به نحوه ی نگهداری پیغام ها و نحوه ی توزیع آن بین consumer ها نیز پرداخته شد. در ادامه ابتدا نحوه ی نصب و کانفیگ کافکا و سپس دموی مختصری کافکا آمده است و در نهایت نیز معماری دقیق تری از کافکا و ویژگی های بیشتری از آن بیان میشود.
برای مطالب این نوشتار از درس های Getting Started with Apache Kafka و Designing Event-driven Applications Using Apache Kafka Ecosystem از pluralsight و برخی از سایت ها برای توضیح دقیق تر مفاهیم استفاده شده است.