Тяжелая асинхронная обработка - PullRequest
5 голосов
/ 29 июня 2010

У меня есть приложение, в самом простом виде, оно считывает большое количество телефонных номеров из базы данных (около 15 миллионов) и отправляет каждое число по одной строке за раз в URL для обработки.Я разработал приложение следующим образом:

  1. массовый экспорт телефонных номеров из sql в текстовый файл с использованием служб SSIS.Это очень быстро и занимает 1 или 2 минуты.
  2. загружает числа в очередь сообщений (сейчас я использую MSMQ).
  3. Удалите сообщения из приложения командной строки и запустите запрос по http для некоторой службы, например, 3 звонка на номер телефона, и, наконец, войдите в базу данных.

Проблема заключается в следующем:Это все еще занимает много времени, чтобы закончить.MSMQ также имеет ограничение на размер сообщений, которые он может принимать, и теперь мне нужно создать несколько очередей сообщений.Мне нужно много отказоустойчивости, но я не осмелюсь сделать свою очередь сообщений транзакционной из-за производительности.Я подумываю о публикации очереди сообщений (в настоящее время частной очереди) в активном каталоге, чтобы процессы могли удалить ее из разных систем, чтобы она могла завершиться быстрее.Кроме того, мои процессоры достигли 100% во время выполнения, и я изменяю его, чтобы использовать пул потоков в это время.Я готов изучить JMS прямо сейчас, если она будет лучше обрабатывать очередь.На данный момент наиболее эффективной частью всей обработки является часть служб SSIS.

Мне бы хотелось услышать более качественный подход к проектированию, особенно если вы раньше обрабатывали такой тип тома.Я готов перейти на Unix или сделать LISP, если он лучше справится с такой ситуацией.

Спасибо.

Ответы [ 5 ]

2 голосов
/ 29 июня 2010

Вот простое супер прагматичное решение:

Сначала разбейте ваш текстовый файл на более мелкие файлы, возможно, с примерно 10 000 записей в каждом файле. Давайте назовем их numbers_x.queue.

Создайте приложение на основе пула потоков, в котором каждый поток обрабатывает файлы, выполняя следующие действия:

  1. Найдите файл с именем numbers_x.done, если он существует, найдите в нем последний полный номер.
  2. Если вы обнаружили, что файл .done сканирует файл numbers_x.queue, чтобы расположиться на месте номера после последнего в файле .done.
  3. Считывание числа из файла .queue
  4. Ваши веб-API звонки
  5. У вас логирование
  6. Добавить номер к файлу .done
  7. Если файл .queue еще не в конце, перейдите к 3
  8. Удалить файл очереди, затем готовый файл
  9. Получите еще один необработанный файл .queue и продолжайте с 1

Хотя это довольно грубый подход, он очень прост в реализации, довольно отказоустойчив, и вы можете легко разделить файлы .queue между несколькими серверами и заставить их работать параллельно.

0 голосов
/ 29 июня 2010

Какова цель использования 2 отдельных приложений + JMS - одно приложение для загрузки данных, а другое - для отправки их при использовании JMS для постановки номеров в очередь? Являются ли оба приложения автономными приложениями или одно приложение для чтения встроено в какой-либо сервер? И последний вопрос: отслеживаются ли цифры, что они были отосланы?

В конце концов, по моему мнению, нет никакой пользы от использования JMS. Это приносит только дополнительные накладные расходы.

Давайте подведем итоги: приложение, которое отправляет номера на некоторый веб-сервер для обработки. Я предполагаю, что принимающая сторона не может обрабатывать / получать больше номеров одновременно. Я предполагаю, что база данных, из которой вы загружаете данные, является неким «доступным только для чтения» хранилищем от клиента или около того. Я предполагаю, что вы хотите отслеживать отправленные номера.

Что бы я сделал:

  • объединить два приложения в одно
  • создать некоторую (возможно, встроенную) БД для отслеживания обработанных чисел (это лучше, чем поддерживать какой-либо файл вручную или хранить его в памяти - в случае сбоя вы начинаете с самого начала; у db есть отличные функции, чтобы предложить)
  • создать пул отправителей, которые берут, скажем, 10 цифр и отправляют его куда-нибудь
  • создать устройство чтения данных, которое считывает числа в пакетном режиме (я не вижу смысла в прочтении всего в начале, что задерживает начало отправки). Это также более прослеживаемо, поскольку вы поддерживаете небольшие наборы данных. Роль считывателя также заключается в том, чтобы отслеживать незанятых отправителей и снабжать их данными, которые считываются во время работы всех отправителей.
  • отправители обновляют внутреннюю базу данных уже обработанными номерами

Я бы сказал, что это вполне настраиваемо, так как вы можете изменять количество чисел, обрабатываемых отправителями, и изменять количество отправителей.

Если желаемая среда более распределена - у вас может быть больше компьютеров - тогда сделайте это следующим образом:

  • Сохранить JMS с одной (или более эквивалентной) очередью для подачи отправителей; создать очередь для уведомления части читателя о законченной работе (чтобы очереди подачи не были перегружены).
  • Сделать читатель частью, которая подает данные - наборы чисел - и читает очередь уведомлений.
  • Создать базу данных для отслеживания обработанных номеров - сделать ее доступной для отправителей или изолированной для читателя при отправке «отчетов об обработке» от отправителей. Читатель, чем обновления БД.
0 голосов
/ 29 июня 2010

Вы также можете предоставить доступ к телефонным номерам через веб-сервис. Вместо процесса чтения MSMQ он может запросить у веб-службы пакет телефонных номеров, которые можно пометить как заблокированные в SQL. Затем он может вызвать веб-службу с указанием успеха или неудачи, чтобы они могли быть помечены как завершенные или не помечены как заблокированные в SQL. Таким образом, вам не нужно массово выделять все строки и забивать систему, и вы получаете отказоустойчивость самого SQL.

В дополнение к этому вы можете затем выполнить некоторое обслуживание, чтобы разблокировать строки как заблокированные, если они не имели ответа в течение длительного времени, и затем игнорировать результаты, если исходный вызывающий объект наконец-то вернется к вам. Вы можете сделать это, помечая строки с помощью идентификатора вызывающей стороны.

Либо отключите веб-службу и подключитесь напрямую к базе данных. В любом случае он обеспечивает отказоустойчивость, прост в реализации, настолько быстр, насколько вы собираетесь, и может быть распределен по многим вычислительным компьютерам.

0 голосов
/ 29 июня 2010

Почему вы читаете всю партию из базы данных одновременно?Разве не было бы более эффективно читать номера телефонов в пакетном режиме, чтобы проблемы с очередями исчезли?

0 голосов
/ 29 июня 2010

У меня нет опыта работы с MSMQ, а только общий вопрос. Зачем читать весь список номеров в очереди при запуске? Почему бы не прочитать число из текстового файла, обработать его и затем прочитать дальше? Чтение всех чисел в объекте за один раз может превысить лимит ОЗУ, а разбиение на страницы приведет к задержке при переключении между объектами ОЗУ и файлом подкачки.

...