Как свести к минимуму задержку, связанную с инфраструктурой обмена сообщениями kafka?
Сценарий. У меня тема с низким объемом (~ 150 мс/сек), для которой мы хотели бы иметь
низкая задержка распространения от производителя к потребителю.
Я добавил отметку времени от производителя и прочитал ее у потребителя, чтобы записать задержку распространения, с конфигурациями по умолчанию. msg (20 байт) показал задержку распространения от 1960 мс до 1230 мс. Задержка с сетью не связана с этим, я попробовал 1 производителя и 1 простой потребитель на той же машине.
Когда я попытался отрегулировать интервал смыва темы до 20 мс, он падает
до 1100 мс до 980 мс. Затем я попытался настроить потребителей "fetcher.backoff.ms"
на 10 мс, он упал до 1070 мс - 860 мс.
Проблема: для 20 байтов сообщения, я хотел бы иметь задержку распространения как можно ниже, а ~ 950 мс - это более высокая цифра.
Вопрос: что-то, что я упускаю из конфигурации?
Я приветствую комментарии, задержка, которую вы получили как минимум.
Предположение. Система Kafka включает в себя операции ввода-вывода диска, прежде чем потребитель получит сообщение от производителя, и это связано с RPM на жестком диске и т.д.
Обновление:
Пытался настроить
политику флеша журнала для долговечности и задержек.
Ниже приведена конфигурация:
# The number of messages to accept before forcing a flush of data to disk
log.flush.interval=10
# The maximum amount of time a message can sit in a log before we force a flush
log.default.flush.interval.ms=100
# The interval (in ms) at which logs are checked to see if they need to be
# flushed to disk.
log.default.flush.scheduler.interval.ms=100
Для тех же msg из 20 байтов задержка составляла 740 мс -880мс.
В самой конфигурации отображаются следующие утверждения.
Есть несколько важных компромиссов:
- Долговечность. Неубранные данные подвергаются большему риску потери в случае сбоя.
- Задержка: данные не становятся доступными для потребителей до тех пор, пока они не будут сброшены (что добавляет задержку).
- Пропускная способность: флеш обычно является самой дорогой операцией.
Итак, я считаю, что нет возможности спуститься до отметки 150 мс - 250 мс. (без обновления оборудования).
Ответы
Ответ 1
Я не пытаюсь уклониться от вопроса, но я думаю, что кафка - это плохой выбор для этого варианта использования. Хотя я думаю, что Кафка велик (я был огромным сторонником его использования на моем рабочем месте), его длина не является низкой латентностью. Его сильные стороны - высокая пропускная способность производства и поддержка как быстрых, так и медленных потребителей. Хотя он и обеспечивает долговечность и отказоустойчивость, так и другие системы общего назначения, такие как rabbitMQ. RabbitMQ также поддерживает множество разных клиентов, включая node.js. Когда кролик MQ падает по сравнению с kafka, это когда вы имеете дело с чрезвычайно большими объемами (скажем, 150K msg/s). В этот момент подход Кролика к долговечности начинает разваливаться, и Кафка действительно выделяется. Долговечность и отказоустойчивость кроликов более чем способны при 20K msg/s (по моему опыту).
Кроме того, для достижения такой высокой пропускной способности, Kafka имеет дело с сообщениями в партиях. Хотя партии небольшие и их размер настраивается, вы не можете сделать их слишком маленькими, не прибегая к большим накладным расходам. К несчастью, пакетное сообщение делает работу с низкой задержкой очень сложной. Хотя вы можете настраивать различные настройки в kafka, я бы не использовал Kafka для чего-то, где латентность должна была составлять менее 1-2 секунд.
Кроме того, kafka 0.7.2 не является хорошим выбором, если вы запускаете новое приложение. Все внимание сосредоточено на 0,8 сейчас, поэтому вы будете сами по себе, если столкнетесь с проблемами, и я определенно не ожидал новых функций.
Снова, я думаю, что Кафка отлично подходит для некоторых очень специфических, хотя и популярных, прецедентов. На моем рабочем месте мы используем как Кролика, так и Кафку. Хотя это может показаться щедрым, они действительно являются сложными.
Ответ 2
Я знаю, что прошло больше года с тех пор, как был задан этот вопрос, но я только что создал кластер Kafka для целей dev, и мы видим задержка в 1 мс от производителя к потребителю. Мой кластер состоит из трех узлов VM, работающих на службе облачной виртуальной машины (Skytap) с хранилищем SAN, поэтому это далеко не идеальное оборудование. Я использую Kafka 0.9.0.0, что является достаточно новым, и я уверен, что искатель использовал что-то более старое. У меня нет опыта работы с более старыми версиями, поэтому вы можете увеличить этот прирост просто от обновления.
Я измеряю задержку, запустив Java-продюсер и потребитель, которых я написал. Оба работают на одной машине, на четвертой виртуальной машине в той же среде Skytap (чтобы минимизировать задержку сети). Производитель записывает текущее время (System.nanoTime()
), использует это значение как полезную нагрузку в сообщении Avro и отправляет (acks = 1). Пользователь настроен на постоянный опрос с тайм-аутом 1 мс. Когда он получает пакет сообщений, он записывает текущее время (System.nanoTime()
снова), а затем вычитает время приема из времени отправки для вычисления задержки. Когда у него есть 100 сообщений, он вычисляет среднее значение всех 100 латентных значений и отпечатков на stdout. Обратите внимание, что важно запустить производителя и пользователя на том же компьютере, чтобы не возникала проблема синхронизации часов с вычислением задержки.
Я немного поиграл с объемом сообщений, созданных производителем. Существует определенно точка, в которой слишком много и латентность начинает увеличиваться, но она значительно выше 150/сек. Случайное сообщение занимает до 20 мс, но подавляющее большинство составляет от 0,5 мс до 1,5 мс.
Все это было выполнено с помощью конфигураций по умолчанию Kafka 0.9. Мне не нужно было настраивать. Я использовал пакетный размер = 1 для своих начальных тестов, но позже обнаружил, что он не повлиял на низкий объем и наложил значительное ограничение на максимальный объем до того, как латентности начали увеличиваться.
Важно отметить, что когда я запускаю своего продюсера и потребителя на своей локальной машине, то же самое сообщение о настройке сообщает о задержках сообщений в диапазоне 100 мс - о тех же самых записях, если я просто пингую своих брокеров Kafka.
Я отредактирую это сообщение позже с образцом кода от моего продюсера и потребителя вместе с другими подробностями, но я хотел опубликовать что-то, прежде чем забыть.
Ответ 3
Кафка может достигать миллисекундной задержки, используя синхронную передачу сообщений. При синхронной передаче сообщений производитель не собирает сообщения в патч перед отправкой.
bin/kafka-console-producer.sh --broker-list my_broker_host:9092 --topic test --sync
Следующий эффект имеет тот же эффект:
--batch-size 1
Ответ 4
Современные версии Kafka, похоже, имеют довольно минимальную задержку, так как результаты здесь показывают:
2 мс (медиана)
3 мс (99-й процентили)
14 мс (99,9-й процентиль)