Забираем большие маленькие данные по REST API

Забираем большие маленькие данные по REST API



При проведении различной ad-hoc аналитики или же создания интеграций между DS решением и внешними системами очень часто приходится использовать REST API для получения данных. Ситуация, когда все помещается в один запрос — идеальна, но редка как единорог. Как правило, приходится тянуть большие объемы, тянуть по частям и в режиме многоходовок, возможно, с использованием курсоров. Внешняя система может лечь при большой нагрузке или же там включатся механизмы пропуска запросов (троттлинг). Вопросы «почему у меня не работает» и «как мне сделать, чтобы работало» возникают с завидной регулярностью.


Ниже приведен блочный разбор типового скрипта для получению данных из внешней системы через REST API. Его можно рассматривать как первое приближение решения задачи подобного класса.


Является продолжением серии предыдущих публикаций.


Определяемся с требованиями


Чтобы обеспечить более или менее комфортную и предсказуемую работу по сбору данных с внешней системы определимся с минимальным набором функциональных требований. Изначально считаем, что исполнение может быть достаточно долгим, поскольку для коротких запросов все делается гораздо проще — перезапрос неудачной сессии дешевле обвязки.


  1. Необходимо обеспечить детальное логирование процесса сбора.
  2. Необходимо обеспечить многопоточный сбор данных.
  3. Необходимо обеспечить примерную количественную валидацию получаемых данных.
  4. Необходимо обеспечить локальное кэширование для иммитации инкрементального апдейта.


Разберем шаги на примере анализа данных для нужд маркетинга с сервиса (пусть это будет dashamail) по рассылке кампаний. Как минимум, есть иерархическая зависимость кампания — список рассылки. Т.е. сначала необходимо определиться со списком интересующих рекламных кампаний, а потом уже по каждой кампании определяться с ее списком рассылки. Скрипт минимально простой, исключительно для выполнения своих функций и не более. Желающие улучшить всегда могут это сделать самостоятельно.


Инициализация


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


Код инициализации


Запрашиваем список кампаний


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


Код сбора данных по списку проведенных кампаний


Сверка с локальным кэшем


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


Код сверки с локальным кэшем


Подготовка заданий для многопоточного опроса кампаний


Cформируем табличное описание заданий для генерации итератора. Учтем что кампания кампании рознь. Перемешаем случайным образом кампании, чтобы устранить потенциальную разбалансировку по нагрузке потоков.


Это мы все делаем в основном потоке.


Код подготовки заданий


Сбор данных по кампаниям в многопоточном режиме


Поскольку 99% времени потоки будут находиться в режиме ожидания ответа от внешней системы, количество потоков может быть больше числа доступных ядер и определяться лишь возможностями внешней системы. Тут же ведем проверку соответствия реально полученного объема данных с задекларированным по списку кампаний. Проверить полезно, но не всегда эти показатели могут совпадать. Не из-за проблем на канале связи, а из-за неконсистентности данных во внешней системе. Это тоже стоит учесть.


Детально про %dorng% можно почитать здесь.


Код сбора данных по кампаниям


Финализируем результат


Собираем все данные вместе, сохраняем, считаем время


Код финализации


Заключение


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



Report Page