Многоуровневый дизайн очереди - PullRequest
2 голосов
/ 28 февраля 2009

Я разрабатываю систему для работы с внешним веб-сервисом. Сервис ограничивает количество запросов, которые могут быть сделаны в течение определенного периода времени (T). Система позволяет пакетировать определенное количество запросов (R). Служба поддерживает определенное количество операций (O).

Мой код будет обрабатывать неизвестное количество запросов от пользователей (на данный момент я понятия не имею, может ли это быть один запрос в день, может быть тысячи в секунду, хотя мне нужно построить его с предположением о тысячах в секунду, хотя ). Эти результаты будут храниться в базе данных в течение определенного периода времени. Если записи базы данных устарели, системе потребуется снова запросить данные у веб-службы.

Я могу получить доступ к веб-службе только через один IP-адрес с одной учетной записью (без мошенничества и получения учетной записи для каждого типа операции или одного компьютера для каждого типа операции). Система будет (надеюсь) работать на одном сервере.

То, что я пытаюсь сделать (думал об этом в течение нескольких недель без каких-либо результатов, которые мне нравятся), - это создать систему, в которой:

  • дублирующиеся запросы объединяются (дубликат означает, что они имеют одинаковые данные запроса)
  • запросы пользователей имеют приоритет над системными запросами
  • системный запрос может быть изменен на запрос пользователя (обновление базы данных находится в очереди, а пользователь запрашивает те же данные)
  • если нет запросов пользователя R для конкретной операции, то остаток берется из системных запросов
  • пользовательские запросы обрабатываются в том же порядке, в котором они поступают (за исключением того, что после обработки пользовательского запроса обрабатывается R запросов того же типа).

Так, например, T - 1 секунда, R - 3, а O - 2. В систему поступают следующие запросы:

Request 1,  user,   operation A, data 1
Request 2,  user,   operation A, data 2
Request 3,  user,   operation A, data 1 <- duplicate of request 1
Request 4,  system, operation B, data 3
Request 5,  system, operation A, data 1 <- duplicate of request 3
Request 6,  user,   operation B, data 3 <- duplicate of Request 4
Request 7,  system, operation A, data 4
Request 8,  user,   operation A, data 5
Request 9,  user,   operation A, data 6
Request 10, user,   operation A, data 7
Request 11, user,   operation B, data 8

Как только вы разберетесь с дубликатами, вы получите:

Request 1,  user,   operation A, data 1 
Request 2,  user,   operation A, data 2 
Request 4,  user,   operation B, data 3 <- promoted to user from system (msg 6)    
Request 7,  system, operation A, data 4 
Request 8,  user,   operation A, data 5 
Request 9,  user,   operation A, data 6 
Request 10, user,   operation A, data 7 
Request 11, user,   operation B, data 8

Запросы должны обрабатываться в следующем порядке:

T1 Request 1, Request 2, Request 8
T2 Request 4, Request 11
T3 Request 9, Request 10, Request 7

Я думаю, что будет 3-7 типов операций. Некоторые типы операций будут иметь больше запросов, чем другие. Системных запросов, вероятно, будет больше, чем пользовательских запросов.

Есть ли общий способ решения этой проблемы? Шаблон или технология? Не думаю ли я об этом (к сожалению, я не могу получить статистику использования до тех пор, пока она не заработает, я даже не могу догадаться, что это будет)?

Основные вещи, которые я стараюсь избегать:

  • обработка системных запросов над пользовательскими запросами (системный запрос может ждать несколько недель, пользовательский запрос должен обрабатываться как можно быстрее)
  • не делает один и тот же запрос дважды в период, когда данные кэшируются в базе данных

1 Ответ

1 голос
/ 28 февраля 2009

Я бы решил это, имея две очереди: одну для пользователя и одну для системных запросов. Разработайте каждую очередь как лексикографически упорядоченный набор, содержащий кортеж (тип операции, данные, время прибытия); это предполагает, что вы можете определить порядок своих частей данных. Упорядоченные наборы позволяют выполнять поиск по частичным ключам, что позволяет проверять наличие дублирующихся запросов в обеих очередях и позволяет продвигать систему по запросу пользователя. Хотя я не совсем понимаю роль переменной Т.

...