🦾 IT-Качалка Давида Шекунца 💪
2023-09-25 07:22
Ivan Zhuravlev
Увы, но ты ошибаешься на счёт своих утверждений.Во-первых, протокол Кафка из коробки поддерживает FIFO на партицию (никто не мешает создать одну при необходимой архитектуре). Exactly-once через транзакции.История сообщений из коробки, в redpanda есть ещё разделение на горячее и холодное хранилище.С метриками и даже трассировкой из коробки нет проблем.Состояние джоб тоже не проблема, если паттерн состояний, пример:task.pendingtask.in-progresstask.successtask.failedВ каждом стриме задачи с нужным состоянием.Найти задачу по id или времени можно по маске task.*.Во-вторых, да, можно построить на CDC это всё, ещё на pg есть через pub/sub разные очереди.Но, если мы говорим за highload и масштабирование, то все эти решения на БД резко проигрывают.У меня есть статья, которую я так и не опубликовал, там мы прорабатывали алгоритм регулярных (ну и обычных тоже) очередей с максимальными возможными гарантиями и скоростью работы на протоколе Kafka. Было бы интересно дать тебе почитать и послушать твоё мнение)
Оооо я ждал тебя 😍У нас было 2 задачи, в которых я разочаровался при использовании очередей:- Джобы, которые запускаются раз в месяц и должны (1) посчитать сколько использовали компании ресурсов, (2) рассчитать сколько снять денег с баланса с учетом скидок и подобного, (3) снять деньги с баланса системы а за остатком сходить в сторонюю систему, (4) выставить счета и акты, (4) подписать и отправить на почту- Есть контроллеры (порядка 10-50к) каждый отправляет сообщения, которые обязательно нужно процессить посследовательно в рамках 1 контроллера, но параллельно в рамках множества (потому что присылают они с разной частатой и процессинг некоторых может занимать секунды из-за ожидания сторонних провайдеров)Сразу скажу: в обоих случаях скорость на четвертом месте, самое важное (1) надежность исполнения, (2) удобство добавления новых фич (этот функционал активно расширяется), (3) дебагинг и возможность быстрого перезапуска в случае проблем (а проблем с ними обычно куча потому что мы завязаны на кучу сторонних сисем)В первом случае БД дает преимущества, потому что (1) мы вывели все джобы с состояниями тех поддержке и они могут посмотреть что и как по каждой джобе, а также что и как было выставлено, (2) также прямо в UI могут выбрать "с какого этапа повторить", на джобе храняться все id созданных сущностей и мы удаляем все созданныеы сущности до нужного этапа и продолжаем взятие в работу, (3) преимущество из пункта нижеВо втором случае самая большая проблема "последовательно в рамках 1 контроллера и параллельно во всех", где контроллеров >10 000, партиции слишком жирно создавать на каждый отдельный контроллер, а если создавать топики, то надо будет вертеть систему привязки N топиков к M сервисов (и вот эта вся распределенщина)А мы все масштабирование решили в 1 строчку: UPDATE job SET status='in-progress' WHERE id = (SELECT id FROM job WHERE status = 'pending' AND controller_id NOT IN ( SELECT controller_id FROM job WHERE status = 'in-progress') ORDER BY created_at ASC LIMIT 1) RETURNING * – теперь каждый отдельный инстанс из одной кучи конкурентно выхватывает какую-то задачу учитывая последовательность в рамках 1 и параллельность в рамках множестваДа, несомненно, скоростью тут и не пахнет (хотя и проблем со скоростью у нас нет)Ну и соответственно все остальные плюсы из текста постаЯ это к чему: да, несомненно, все это можно сделать более крутым в каждом аспекте на очередях, НО я достигаю всех нужных показателей для средних проектов, еще и удобной разработки, еще и распределенности просто парой INSERT, SELECT, UPDATE, используя уже используемую в проекте БД, от которой мне нужно только наличие атомарного UPDATE и все, и это очень радуетP.S.Статью с огромным удовольствием почитаю)