Go: Kafka

11 вопросов

1 Что такое Apache Kafka?

Kafka - распределенная потоковая платформа: хранит сообщения в топиках разбитых на партиции, обеспечивает персистентность, масштабирование и повторное чтение. Производители пишут в топики, потребители читают из партиций (consumer groups). Используют для логов, событий, стриминга, очередей. В Go популярны библиотеки: confluent-kafka-go, segmentio/kafka-go, sarama.

conn, _ := kafka.DialLeader(ctx, "tcp", "localhost:9092", "topic", 0)
conn.WriteMessages(kafka.Message{Value: []byte("hello")})
Открыть отдельно →
2 Топики и партиции в Kafka. Как это влияет на Go-клиент?

Топик разбит на партиции; сообщения с одним ключом попадают в одну партицию (партиционирование по ключу). Параллелизм потребления ограничен числом партиций. В Go при создании топика или при продюсинге указывают число партиций; consumer подключается к партициям (в группе партиции распределяются между участниками). Увеличение партиций после создания возможно, но меняет распределение ключей.

msg := kafka.Message{Key: []byte(userID), Value: data}
w.WriteMessages(ctx, msg)
Открыть отдельно →
3 Что такое consumer group в Kafka?

Consumer group - набор потребителей с общим group.id. Каждая партиция топика назначается одному потребителю в группе; при добавлении/уходе потребителей происходит rebalance - перераспределение партиций. В Go подключаются к Kafka с group ID; библиотека участвует в rebalance. Обработка сообщений идемпотентна или с учетом дублей при повторной доставке.

r := kafka.NewReader(kafka.ReaderConfig{
    Brokers: []string{"localhost:9092"},
    Topic:   "events",
    GroupID: "processor",
})
Открыть отдельно →
4 Управление offset в Kafka. Commit в Go.

Offset - позиция потребителя в партиции. После обработки сообщения consumer коммитит offset (в Kafka или в группе). При перезапуске чтение продолжается с закоммиченного offset. В Go: автоматический коммит по таймауту или ручной после успешной обработки (CommitMessages). At-least-once: коммит после обработки; при сбое после обработки но до коммита - повторная доставка. Идемпотентность обработки важна.

for {
    msg, _ := r.FetchMessage(ctx)
    process(msg)
    r.CommitMessages(ctx, msg)
}
Открыть отдельно →
5 Гарантии доставки продюсера (acks, idempotence).

acks=0 - не ждать подтверждения. acks=1 - лидер партиции подтвердил. acks=all - лидер и реплики подтвердили. Идемпотентный продюсер (enable.idempotence=true) избегает дублей при ретраях. В Go настраивают при создании продюсера; для критичных сообщений acks=all и идемпотентность. Транзакции (транзакционный продюсер + read_committed на consumer) дают exactly-once семантику в рамках Kafka.

w := &kafka.Writer{
    RequiredAcks: kafka.RequireAll,
    Async:        false,
}
Открыть отдельно →
6 Семантики потребления: at-most-once, at-least-once, exactly-once.

At-most-once: коммит до обработки; при падении после коммита сообщение теряется. At-least-once: коммит после обработки; при падении после обработки но до коммита - повторная доставка (идемпотентность обработки). Exactly-once: транзакции продюсера + read_committed и идемпотентный consumer, или семантика в приложении (дедупликация по ключу). В Go чаще реализуют at-least-once с идемпотентной обработкой.

Открыть отдельно →
7 Kafka и RabbitMQ. Когда что выбирать?

Kafka: большие объемы, ретроспектива (хранение, повторное чтение), потоковая обработка, несколько потребителей одного потока, партиционирование по ключу. RabbitMQ: классические очереди, гибкая маршрутизация (exchanges), приоритеты, TTL, меньше латентность для простых сценариев. В Go для событийной шины и логов чаще Kafka; для задач воркерам и простых очередей - RabbitMQ или облачные очереди (SQS).

Открыть отдельно →
8 Exactly-once в Kafka. Транзакции и идемпотентность.

Exactly-once в Kafka: транзакционный продюсер (отправка в транзакции), consumer с read_committed (читает только закоммиченные транзакции), идемпотентность на стороне приложения (дедупликация по ключу сообщения или по бизнес-ключу). В Go поддержка зависит от библиотеки; confluent-kafka и kafka-go поддерживают транзакции. Альтернатива - at-least-once + дедупликация в БД (уникальный ключ + INSERT ... ON CONFLICT).

Открыть отдельно →
9 Как Kafka обеспечивает отказоустойчивость и сохранность данных?

Kafka реплицирует каждую партицию на несколько брокеров (replication.factor). Один брокер - лидер, остальные - реплики (ISR, In-Sync Replicas). При падении лидера контроллер автоматически выбирает нового из ISR. Продюсер с acks=all получает подтверждение только после записи во все ISR-реплики. Параметр min.insync.replicas задает минимум синхронных реплик для записи. Типичная конфигурация (RF=3, min.insync=2, acks=all) выдерживает потерю одного брокера без остановки и потери данных. Consumer при перезапуске продолжает с закоммиченного offset, не теряя позицию.

Открыть отдельно →
10 Что такое Kafka Connect?

Kafka Connect - фреймворк для потоковой передачи данных между Kafka и внешними системами (БД, S3, Elasticsearch). Connectors - источник (source) или приемник (sink). В Go приложении обычно не используют Connect напрямую; пишут продюсеры и консьюмеры на Go. Connect полезен для готовых пайплайнов (например, Debezium для CDC в Kafka).

Открыть отдельно →
11 Schema Registry в Kafka. Зачем в Go?

Schema Registry хранит схемы сообщений (Avro, JSON Schema, Protobuf); версионирование и совместимость. Продюсер и консьюмер получают/проверяют схему по id в заголовке сообщения. В Go используют клиент Schema Registry (confluentinc/confluent-kafka-go с schema_registry) для сериализации/десериализации. Удобно при эволюции формата и нескольких сервисах на разных языках.

sr, _ := schemaregistry.NewClient(schemaregistry.NewConfig("http://localhost:8081"))
encoder, _ := avro.NewGenericAvroSerializer(sr, ...)
payload, _ := encoder.Serialize("topic", msg)
Открыть отдельно →
🧠Квиз 🏆Лидеры 🎯Собесед. 📖Вопросы 📚База зн.