Как Kafka записывает сообщения и как их отдаёт
Комментарии (2)
Ответ сгенерирован нейросетью и может содержать ошибки
Как Kafka записывает сообщения
Kafka записывает сообщения (запись производителя) в партиции (разделы) топиков (тематических каналов). Это происходит через механизм append-only log, где сообщения добавляются только в конец. Каждый топик разделен на партиции для обеспечения параллельности и масштабируемости.
Процесс записи Producer:
- Producer отправляет сообщение в конкретный топик Kafka.
- Сообщение может быть направлено в определенную партицию с использованием ключа (key) или стратегии балансировки (round-robin, если ключ отсутствует).
- Kafka записывает сообщение в файл лога партиции. Каждая партиция — это физический файл на диске, где данные хранятся последовательно.
- Сообщения сохраняются в формате батчей (batch) для оптимизации производительности, уменьшая количество операций I/O.
- Kafka гарантирует сохранность данных через механизм acks (acknowledgments):
- **acks=0**: Producer не ожидает подтверждения — возможна потеря данных.
- **acks=1**: подтверждение от лидера партиции — баланс между производительностью и надежностью.
- **acks=all**: подтверждение от лидера и всех синхронных реплик — максимальная надежность.
// Пример конфигурации Producer в Java
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("acks", "all"); // Гарантирует запись на все реплики
Producer<String, String> producer = new KafkaProducer<>(props);
producer.send(new ProducerRecord<>("my-topic", "key", "value"));
producer.close();
Как Kafka отдаёт сообщения (Consumer)
Kafka отдаёт сообщения потребителям через механизм pull-based модель, где Consumer активно запрашивает данные из партиций.
Процесс чтения Consumer:
- Consumer (или Consumer Group) подключается к топику и читает сообщения из партиций.
- Каждая партиция в группе потребителей назначается конкретному потребителю для предотвращения конфликтов (через механизм rebalance).
- Consumer читает сообщения последовательно, используя offset (номер позиции сообщения в партиции). Offset хранится либо в Kafka (внутренний топик
__consumer_offsets), либо внешне. - Consumer управляет своим прогрессом, подтверждая обработку сообщений через commit offset, что позволяет продолжить чтение с последней позиции.
# Пример Consumer в Python (kafka-python)
from kafka import KafkaConsumer
consumer = KafkaConsumer(
'my-topic',
bootstrap_servers=['localhost:9092'],
group_id='my-group',
auto_offset_reset='earliest', # Начать с начала если нет сохраненного offset
enable_auto_commit=True, # Автоматически коммитить offset
)
for message in consumer:
print(f"Received: {message.value}")
# Обработка сообщения
Ключевые механизмы для отдачи сообщений:
- Распределение партиций: В Consumer Group каждый consumer получает уникальный набор партиций для чтения, обеспечивая горизонтальную масштабируемость.
- Управление offset: Consumer может читать с любого offset, поддерживая как ат-итичный (от последнего коммита), так и интерактивный (по запросу) режимы.
- Репликация и отказоустойчивость: Если лидер партиции недоступен, consumer автоматически переключается на реплику, обеспечивая непрерывность чтения.
# Пример проверки offset через kafka-consumer-groups
kafka-consumer-groups --bootstrap-server localhost:9092 --describe --group my-group
# Вывод покажет текущие offset, lag и распределение партиций
Важно отметить, что Kafka хранит сообщения долго (на основе настроек retention), поэтому потребители могут читать исторические данные. Эта комбинация надежной записи и гибкого чтения делает Kafka мощным инструментом для потоковой обработки данных и построения событийно-ориентированных архитектур.