#java #apache-kafka #distributed-computing #software-design
#java #apache-kafka #распределенные вычисления #программное обеспечение-дизайн
Вопрос:
Я рассматриваю Kafka для использования в качестве распределенной рабочей очереди, из которой несколько работников могут извлекать задачи. Мой оригинальный дизайн выглядит так:
Work Producer ---> Kafka topic ------worker 1
|
|__worker 2
...
|__worker n
Проблемы с этим дизайном заключаются в следующем:
-
Если какой-либо работник берет задачу из темы и немедленно фиксирует смещение, то в случае сбоя задача может не быть обработана повторно.
-
Если какой-либо работник берет задачу из темы и фиксирует смещение только по завершении, тогда другие работники могут также выполнить эту задачу и обработать ее. Если задача выполняется довольно долго, то почти все работники будут выполнять одну и ту же задачу и обрабатывать ее, полностью препятствуя распределению.
Я ищу способ «пометить» задачу в очереди как «незавершенную», чтобы она не использовалась кем-либо еще, но смещение не зафиксировано (потому что оно может завершиться сбоем и нуждается в повторной обработке). Возможно ли это реализовать?
Ответ №1:
Если какой-либо работник берет задачу из темы и немедленно фиксирует смещение, то в случае сбоя задача может не быть обработана повторно.
В этом случае я рекомендую использовать ручные коммиты и отключить конфигурацию auto.commit.offset вашего потребителя.
Если какой-либо работник берет задачу из темы и фиксирует смещение только по завершении, тогда другие работники могут также выполнить эту задачу и обработать ее. Если задача выполняется довольно долго, то почти все работники будут выполнять одну и ту же задачу и обрабатывать ее, полностью препятствуя распределению.
Вы могли бы справиться с этим сценарием, создав свою тему с разделами, а ваших потребителей — с ConsumerGroup. В Kafka каждый раздел может быть прочитан только одним потоком-потребителем в группе потребителей.
Это означает, что до тех пор, пока все ваши потребители (или «работники») принадлежат к одной и той же группе потребителей, никогда не произойдет так, что два работника начнут читать и обрабатывать одно и то же сообщение.
Комментарии:
1. Хотя я бы не стал спорить ни с чем из этого, мне интересно, требуется ли сложность Kafka для того, что, в конце концов, является относительно простой задачей распространения сообщений, предположительно с небольшим объемом? Существует множество технологий распространения сообщений, которые могли бы сделать то же самое, без сложности Kafka. Конечно, если у вас уже есть Kafka, имеет смысл использовать его.
2. Да, я могу только поддержать то, что говорит @KevinBoone. Я предполагаю, что в конечном итоге это зависит от доступных альтернатив и объема задач / рабочих, о которых трудно судить по информации, приведенной в вопросе.
3. каждый раздел может быть прочитан только одним потоком-потребителем в группе потребителей , которые не совсем понимают это. Если в группе есть, скажем, 2 потребителя, только один может «получить» определенный раздел и прочитать из него? Другой никогда не будет читать?
4. Да, это правильно. Если у вас есть 2 потребителя в одной группе и тема только с одним разделом, один потребитель прочитает, другой будет простаивать все время и никогда не прочитает ни одного сообщения. (если не произойдет перебалансировка). Существует хорошее введение в потребителей Kafka.