Как ускорить гармонизацию в MarkLogic Data Hub

В настоящее время я занимаюсь разработкой для согласования наших данных. Я заметил, что завершение согласования идет медленно.
Я относительно новичок в разработке NoSQL / MarkLogic и не уверен в лучших практиках, которым нужно следовать для более плавной и быстрой гармонизации.

Вот несколько фактов:

Загрузка данных:

  1. Данные, загруженные в стадии подготовки, поступили из системы ERP с использованием реляционной базы данных. Данные извлекаются в CSV и загружаются в Mark Logic
  2. Все данные реляционной таблицы извлекаются в файл CSV. Каждая таблица представлена ​​в отдельном объекте.

Пост гармонизации:

  1. 227 826 записей заняли около 66 минут, чтобы завершить согласование
  2. 1074151 записей заняло около 4 часов и 19 минут, чтобы завершить согласование

Фрагменты кода гармонизации:

  1. Есть многочисленные логики вычисления даты (образец ниже)

function getScheduleWindowEnd(businessUnit,targetDateString,schEndDateString)
   {
    var scheduleWindowEnd = new String();
    var preferredDate = new Date(); 
    var startDayOfWeek = getBUStartDayOfWeek(businessUnit);
    
    if (fn.empty(targetDateString) || targetDateString == null || targetDateString == "" || 
       fn.empty(schEndDateString) || schEndDateString == null || schEndDateString == "")
    {
     tempScheduleWindowEnd = "";
     return "";
    }
    else
    {
      targetDateString = fn.replace(targetDateString, "/", "-") ;
      schEndDateString = fn.replace(schEndDateString,"/","-");

      var targetDate = xs.date(targetDateString);
      var schEndDate = xs.date(schEndDateString);
    
      // Get preferred date
      if (fn.empty(schEndDate)) 
      {
        preferredDate = targetDate;
      }
      else
      {
       preferredDate = schEndDate;
      }
      
      //get target day of week
      var scheduledDayOfWeek = xdmp.weekdayFromDate(preferredDate);
    
      if (scheduledDayOfWeek < startDayOfWeek)
      {
      scheduleWindowEnd = fn.string(addDays(preferredDate,(startDayOfWeek-scheduledDayOfWeek)));  
      }
      else
      {
      scheduleWindowEnd = fn.string(addDays(preferredDate,(startDayOfWeek-scheduledDayOfWeek+7)));
      }
      
      scheduleWindowEnd = fn.replace(fn.substring(scheduleWindowEnd, 1, 10), "-", "/");
      tempScheduleWindowEnd = scheduleWindowEnd;
    }
     
     return scheduleWindowEnd
   }

  1. Основной объект получает некоторые данные элемента от других объектов (в приведенном ниже примере таблица 2 является другим объектом)

<StatusDescription>${fn.normalizeSpace(getUDCDescription("00", "SS", fn.normalizeSpace(hl.elementText(source, "WASRST", true))))}</StatusDescription>

function getUDCDescription(drsy,drrt,drky) {
     let udcRecord =  cts.search(cts.andQuery([
       cts.collectionQuery("ERPSystemSource"),
       cts.collectionQuery("Table2"),
       cts.elementWordQuery(xs.QName("DRSY"), drsy),
       cts.elementWordQuery(xs.QName("DRRT"), drrt),
       cts.elementWordQuery(xs.QName("DRKY"), drky)
     ]))
     
     let docXML = new String();
     for (const item of udcRecord) {
       docXML += hl.encodeXml(fn.normalizeSpace(hl.elementText(item, "DRDL01", true)))
     }
     return docXML;
   }

  1. Некоторые из согласованных данных являются однозначными (прямая выборка). Смотрите образец ниже:

        <Element1>${hl.elementText(source, "WADOCO", true)}</Element1>
        <Element2>${fn.normalizeSpace(hl.elementText(source, "WAMCU", true))}</Element2>

  1. Существует множество циклов вызовов (не вложенных), около 20 вызовов. Пример № 2 выше:

2 ответа

Решение

Я настоятельно рекомендую, если это возможно, рассмотреть вопрос о сотрудничестве с представителем MarkLogic по этой проблеме. Повышение производительности программного обеспечения может быть сложным, и лучше всего иметь рабочие отношения с кем-то, кто может идти с вами туда-сюда.

Первый вопрос, который я всегда задаю: "Каков ваш ожидаемый SLA? Пока у вас нет четкого набора ожиданий того, как, по вашему мнению, должна выглядеть производительность, я не могу сказать вам, что это медленно или быстро, или если ваши ожидания реалистичны или нереалистичны.

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

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

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

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

  1. Сделайте ваши звонки cts.search нефильтрованными (когда это возможно)
  2. Ограничьте вызовы cts.search там, где это возможно. Я чувствую, что вы можете делать больше, чем один на работу.
  3. Попробуйте использовать cts.elementValues ​​вместо cts.search, если вам нужно извлечь только один элемент из документа
  4. Нормализация пространства и другие строковые функции могут быть тяжелыми для больших строк текста. Если вы работаете с большими строками, подумайте, сможете ли вы сократить количество раз их использования.
  5. Я предлагаю реализовать уникальное пространство имен XML в документе для каждого типа таблицы, которую вы извлекаете, чтобы вам не требовались запросы к коллекции.

В дополнение к предложениям Роба, вы также можете проверить шаг коллектора в гармонизации. Похоже, вы сворачиваете несколько записей в один экземпляр сущности, и это работает лучше всего, если вы не выполняете итерацию всех записей. Итерация записи Uris является реализацией коллектора по умолчанию. Возможно, вы захотите заменить это, например, cts.values ​​на некоторый уникальный идентификатор для сущностей, которые вы создаете.

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

НТН!

Другие вопросы по тегам