база с таблицей items в 300к строк, мне нужно в несколько потоков (worker pool) ходить в базу, брать, скажем, 100 строк, делать над ними работу (ходить к стороннему API, среднее время ответа 700мс) и класть обновленные данные в другую таблицу results. Меня в этом алгоритме беспокоит, что два воркера могут одновременно работать с одним массивом строк. Правильно ли использовать LIMIT и OFFSET для обеспечения уникального массива строк, контролируя это поведение на уровне приложения? Или есть в postgres более эффективные механизмы?
Я бы брал по остатку от деления первичного ключа. select * from items where id % (кол-во воркеров) = (номер воркера)
главное чтобы при этом использовался индекс
Классное решение! Спасибо большое! :)
Как-то раз я штук двадцать индексов по id%N сделал. Или даже тридцать :)
Я бы, вероятно, как-то боокировал эти строки в постгрессе на время обработки. Ну там, непосредственно в них записывал host.pid воркера или не в них, а рядом... С обеспечением атомарности записи.
Если я правильно понял, на чтение блокировки нет в постгресе?!
Никто не заставляет вас блокировать именно "на чтение".
Вообще, лично я бы делал select for update skip locked where id not in (select from worker_lock) , и потом писал в worker_lock.
А worker_lock так или иначе чистил периодически от зависшэго.
Выглядит сложновато
Тема параллелизма, атомарности и блокировок никогда не была простой. И да, это ещё всё достаточно примитивно.
Обсуждают сегодня