Параллельное чтение из таблицы SQL
Существует таблица с событиями, которые должны пушиться в Kafka or Rabbit. Также существует около трех и более бэкграунд-воркеров, которые проверяют таблицу на новые ивенты и отправляет их в Kafka or Rabbit. Событий в таблице может быть несколько миллионов.
Как воркерам параллельно считать ивенты из таблицы без локов и без повторений? (Что я имею ввиду под повторениями: чтобы первый воркер взял порцию, например, из 100 ивентов, а другой воркер не взял их же и не запушил события повторно) Ключевой момент - без локов.
Ответы (1 шт):
Берете воркер, один, читаете базу, кидаете записи из таблицы в очередь кролику (или кафке, пфённой само собой), назовем его "мастер". Настолько быстро кидаете, насколько не хотите уронить кролика, например контроллируя длину очереди. Берете 100500 рабочих воркеров и заставляете их эту очередь разгребать. Кролик гарантирует, что одно событие не будет получено двумя воркерами.
Далее можно поднять очередь ответов и устроить систему транзакций, где рабочие будут обратно через кролика сообщать, какие данные были обработаны. Это позволит растащить их по кластеру, включать и выключать, ломать и чинить, масштабировать. Но это уже насколько фантазии хватит.
Никаких локов не требуется, так как мастер один и он сам внутри себя синхронизирует транзакции чтения-записи БД. Эти все велосипеды давно придуманы и много где разжеваны. Мастер должен быть настолько легковесным, чтобы узкое место было именно в БД.
Не нагружайте БД лишней работой, например логами или чтением состояния для админских задач, поднимите для таких штук реплику. Даже если реплика в пиковые часы немного будет отставать, в спокойные часы она догонит. Зато можно будет на реплике гонять сколько угодно тяжелых запросов чтения, и это не скажется на производительности ядра кластера. Плюс реплика - живой бэкап.
У нас 1ккк RPS на такой архитектуре тянет, в несколько слоёв мемкешей правда и с in-memory табличками, но что поделать, рабочих нод около сотни, а вам сколько надо, 3 или немного более? Тогда откуда вообще этот вопрос? Вам и кролик то наверное не нужен тогда, если нагрузку вытащит одна физическая нода. Кролик нужен тогда, когда база, мастер и AMQP очередь - 3 разные физические ноды, а рабочие - еще N физических нод.