بخش اول: مفاهیم پایه، معماری و Kafka Core
بخش دوم : سایر بازیگران اکوسیستم کافکا
بخش سوم ابزارهای جانبی کافکا : کانکت و رجیستری
بخش چهارم : پردازش جریان در عمل
بخش پنجم :‌ مباحث مدیریتی و تکمیلی

آشنایی با تنظیمات اصلی نودهای کافکا و راه اندازی یک کلاستر تک‌نودی

در جلسه‌ی گذشته، کافکا را به‌صورت لوکال (روی سیستم شخصی) نصب کردیم و با مفاهیم اولیه‌ی آن آشنا شدیم.
اما از این جلسه به بعد، چون قصد داریم امکانات متنوع‌تر و پارامترهای اصلی کافکا را بررسی کنیم، بهتر است با یک کلاستر واقعی کافکا کار کنیم.
ساده‌ترین و سریع‌ترین راه برای راه‌اندازی چنین کلاستری، استفاده از Docker و Docker Compose است.

در این جلسه ابتدا یک نسخه‌ی تک‌نودی (Single Node) از کافکا را با Docker Compose بالا می‌آوریم و در ادامه نسخه‌های حرفه‌ای‌تر چندنودی را بررسی می‌کنیم.


🔄 کافکا بدون ZooKeeper (KRaft Mode)

در نسخه‌های جدید کافکا، دیگر خبری از ZooKeeper نیست.
کافکا حالا خودش مکانیزم اجماع و هماهنگی بین نودها را با استفاده از سیستمی به نام KRaft (Kafka Raft) انجام می‌دهد.

در مدل KRaft، هر نود در کلاستر می‌تواند یکی از این سه نقش را داشته باشد:

  1. Controller:
    مسئول مدیریت کل کلاستر است؛ یعنی تصمیم می‌گیرد کدام نود لیدر هر پارتیشن باشد، وضعیت تاپیک‌ها چیست، و هماهنگی‌های اصلی بین بروکرها را انجام می‌دهد.
  2. Broker:
    وظیفه‌اش ذخیره و ارسال پیام‌هاست. وقتی Producer پیامی را می‌فرستد، بروکر آن را در پارتیشن مناسب ذخیره می‌کند و در اختیار Consumer قرار می‌دهد.
  3. Combined Mode (هر دو نقش):
    در محیط‌های ساده‌تر، مانند محیط توسعه، می‌توانیم یک نود داشته باشیم که همزمان نقش Controller و Broker را بازی کند.

⚙️ الگوریتم اجماع Raft در کافکا

وقتی بیش از یک نود در کلاستر داریم، باید بین آن‌ها توافق وجود داشته باشد که کدام نود رهبر (Leader) باشد.
این هماهنگی بدون یک مکانیزم اجماع ممکن نیست.
در گذشته این کار را ZooKeeper انجام می‌داد، اما در KRaft از الگوریتم Raft Consensus استفاده می‌شود.

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

  • انتخاب Controller اصلی (وقتی چند کنترلر وجود دارد)
  • انتخاب Leader برای هر پارتیشن
  • هماهنگی وضعیت متادیتا بین نودها

🐳 راه‌اندازی کافکا با Docker Compose

در اینجا یک فایل Docker Compose ساده برای راه‌اندازی یک کافکای تک‌نودی در حالت KRaft آورده شده است:

version: "3.9"

networks:
  kafka-net:

volumes:
  kafka-data:

services:
  kafka:
    image: apache/kafka:latest
    container_name: kafka-node
    networks:
      - kafka-net
    ports:
      - "۹۰۹۲:۹۰۹۲"   # EXTERNAL listener for producers/consumers
      - "۹۰۹۳:۹۰۹۳"   # CONTROLLER listener
    environment:
      # Node ID
      KAFKA_NODE_ID: 1

      # Roles: combined broker + controller
      KAFKA_PROCESS_ROLES: broker,controller

      # Listeners
      KAFKA_LISTENERS: EXTERNAL://:9092,CONTROLLER://:9093
      KAFKA_ADVERTISED_LISTENERS: EXTERNAL://localhost:9092
      KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: EXTERNAL:PLAINTEXT,CONTROLLER:PLAINTEXT

      # Quorum voters (single node)
      KAFKA_CONTROLLER_QUORUM_VOTERS: 1@localhost:9093

      # Topics & transactions
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
      KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
      KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
      KAFKA_NUM_PARTITIONS: 3
      KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0

      # Log directory
      KAFKA_LOG_DIRS: /var/lib/kafka/data
    volumes:
      - kafka-data:/var/lib/kafka/data

🧩 توضیح پارامترهای اصلی Compose

برای درک بهتر، بیایید تنظیمات بالا را به چند بخش تقسیم کنیم:

۱. 🎯 نقش‌ها و شناسه‌ها
  • KAFKA_NODE_ID: شماره یکتا برای هر نود در کلاستر.
  • KAFKA_PROCESS_ROLES: تعیین می‌کند که این نود broker است، controller یا هر دو.

در این مثال، هر دو نقش را دارد.


۲. 🔌 تنظیمات Listenerها

در کافکا، هر Listener مشخص می‌کند که نود ما از طریق چه پروتکلی، روی چه آدرسی، و از چه پورتی در دسترس است.

فرمت کلی هر listener به صورت زیر است:

<NAME>://<HOST>:<PORT>

در اینجا داریم:

  • EXTERNAL://:9092 → برای ارتباط با Producer و Consumer (بیرون از داکر)
  • CONTROLLER://:9093 → برای ارتباط کنترلرها در داخل کلاستر

🔹 نکته مهم:
کلماتی مثل EXTERNAL یا CONTROLLER فقط برچسب (Label) هستند و برای تنظیمات امنیتی و تعیین نوع ارتباط بین نودها در سایر تنظیمات، از این برچسب ها استفاده می‌کنیم.
در بخش زیر تعیین می‌کنیم هر برچسب از چه پروتکل امنیتی استفاده کند:

KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: EXTERNAL:PLAINTEXT,CONTROLLER:PLAINTEXT

در اینجا هر دو روی حالت ساده‌ی PLAINTEXT (بدون SSL یا SASL) تنظیم شده‌اند.


۳. 🌍 تنظیمات Advertised Listeners

متغیر KAFKA_ADVERTISED_LISTENERS به سایر نودها و کلاینت‌ها اعلام می‌کند که برای اتصال به این نود از چه آدرس و پورتی استفاده کنند.

برای مثال:

KAFKA_ADVERTISED_LISTENERS=EXTERNAL://localhost:9092

یعنی وقتی Producer یا Consumer بخواهد وصل شود، بداند آدرس این نود برای اتصال بیرونی localhost:9092 است. این تنظیم برای حالتی که قرار است روی سیستم خودمان به کافکای درون داکر متصل شویم مناسب است چون داکر دسکتاپ عملیات پورت فورواردینگ را برای ما انجام میدهد و زمانی که برنامه پایتون ما به localhost:9092 متصل میشود، این درخواست به کلاستر کافکا و کانتینر مربوطه ارسال خواهد اما در دنیای واقعی این آدرس باید آدرس یا یک IP باشد که برنامه ها به آن دسترسی داشته باشند.
اگر چند نود در شبکه داشتیم، معمولاً یک Listener داخلی (INTERNAL) هم تعریف می‌شود برای ارتباط بین خود نودها، جدا از اتصالات بیرونی.


۴. 🗳️ تنظیمات کنترلر و رأی‌دهنده‌ها

در حالت KRaft، هر کنترلر برای تصمیم‌گیری در اجماع رأی می‌دهد.
در حالت تک‌نودی، فقط یک رأی‌دهنده داریم:

KAFKA_CONTROLLER_QUORUM_VOTERS=1@localhost:9093

۵. 💾 تنظیمات مربوط به داده‌ها
  • KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: تعداد نسخه‌های کپی از تاپیک offset (در حالت تک‌نودی، عدد ۱ است).
  • KAFKA_LOG_DIRS: مسیر ذخیره داده‌ها داخل کانتینر.
  • volumes: تضمین می‌کند داده‌ها با توقف کانتینر از بین نرود.

🚀 نحوه استفاده

  1. اجرای کلاستر: docker compose up -d
  2. ورود به کانتینر: docker exec -it kafka-node sh cd /opt/kafka/bin
  3. ساخت یک تاپیک: ./kafka-topics.sh --bootstrap-server localhost:9092 --create --topic test-topic
  4. ارسال پیام (Producer): ./kafka-console-producer.sh --bootstrap-server localhost:9092 --topic test-topic
  5. دریافت پیام (Consumer): ./kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic test-topic --from-beginning
  6. توقف کلاستر: docker compose down

💡 نکات پایانی

  • در حالت تک‌نودی همه‌چیز در یک کانتینر انجام می‌شود (Controller + Broker).
  • در نسخه‌های چندنودی، معمولاً کنترلرها و بروکرها جدا هستند.
  • استفاده از volumes باعث می‌شود پیام‌ها بعد از ری‌استارت از بین نروند.
  • لیستنرها مهم‌ترین بخش در اتصال صحیح Producer و Consumer به کافکا هستند.
فروشگاه
جستجو
دوره ها

لطفا کلمات کلیدی را وارد کنید