Эффективно выявлять изменения в большом наборе и работать над изменениями исключительно несколькими работниками? - PullRequest
0 голосов
/ 19 июня 2020

У меня есть набор размером ~ 1M. Случайные предметы в наборе часто трогаются до грязи (~ 10к / м, с дублированием). Демон домработника стремится снова очистить грязные предметы, выполняя тяжелую задачу очистки для каждого грязного элемента (например, 1 минуту на каждую задачу). Часто во время задачи очистки связанный элемент снова затрагивается (что не имеет значения). Из-за характера задачи одновременное выполнение одновременных задач для одного и того же элемента не допускается.

Как правильно решить эту проблему? Чтобы лучше объяснить это, вот приблизительное представление о том, как это можно решить:

Простое решение 1:

  1. «Грязный набор» отслеживает все затронутые элементы: элемент тронут, он добавлен в грязный набор. (например, на основе Redis, каждый элемент является ключом-значением в пространстве ha sh с именем «dirty-set»).

  2. Несколько экземпляров демона housekeeper запускаются одновременно (например, экземпляр микросервиса) . Каждый демон-экономка пытается получить работоспособные предметы:

2.1. Просматривать до N элементов (в зависимости от объема задачи, которую он может поддерживать) из грязного набора.

2.2. Для каждого просматриваемого элемента попробуйте заблокировать его так, чтобы другие узлы этого не сделали (объяснено позже в пункте 4).

2.3. Удалите успешно заблокированные предметы из грязного набора.

Для каждого полученного предмета демон домработницы отправляет задачу. работа над предметом. (например, блокировка на основе Redis: Redlock или блокировка на основе MongoDB: выделенная коллекция с уникальным индексом)

Наивное решение 2:

Подобно решению 1, но используйте таблица / коллекция базы данных для реализации как грязного набора, так и блокировки. Например, с MongoDB - это коллекция со схемой вроде {itemId: string, dirty: boolean, lock: timestamp}. Исходя из этого, «добавить в грязный набор» представляет собой простую запись без блокировки, которая обновляет грязное поле до значения «истина», «заглянуть, удалить из грязного и заблокировать» станет переходом БД (запрос N dirty = true и non -locked, обновить грязное поле до false и обновить блокировку).

Решение 2 кажется более интегрированным. Однако он имеет высокочастотную запись в БД (добавление грязного набора), чего следует избегать.

Какое решение этой проблемы может быть лучше?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...