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

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

Вот некоторые факты:

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

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

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

  1. Для согласования 227826 записей потребовалось около 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. Основная сущность получает некоторые данные элемента от других сущностей (в приведенном ниже примере Table2 является другой сущностью)

<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. Существует множество вызовов циклов for (не вложенных), около 20 вызовов. Образец в № 2 выше:

person Ryan    schedule 02.08.2018    source источник
comment
Вы можете начать с определения медленных шагов в плагине, регистрируя время, прошедшее на разных шагах, с помощью xdmp.elapsedTime.   -  person Elijah Bernstein-Cooper    schedule 02.08.2018
comment
Спасибо за ответ! Когда я должен вызывать это, перед вызовом функции или после него?   -  person Ryan    schedule 02.08.2018
comment
Я регистрировал прошедшее время до и после вызова функции. Разница будет во времени выполнения функции.   -  person Elijah Bernstein-Cooper    schedule 02.08.2018


Ответы (2)


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

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

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

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

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

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

  1. Сделайте ваши вызовы cts.search нефильтрованными (если возможно)
  2. По возможности ограничивайте количество вызовов cts.search. У меня такое ощущение, что вы можете делать больше, чем по одному на каждую работу.
  3. Рассмотрите возможность использования cts.elementValues ​​вместо cts.search, если вам нужно извлечь только один элемент из документа.
  4. Нормализация пространства и другие строковые функции могут быть тяжелыми для больших строк текста. Если вы работаете с большими струнами, подумайте, сможете ли вы сократить их использование.
  5. Я предлагаю реализовать уникальное пространство имен XML в документе для каждого типа таблицы, которую вы втягиваете, чтобы вам не понадобились запросы на сбор.
person Rob S.    schedule 02.08.2018
comment
Спасибо, @Rob S! Эти предложения выше имеют смысл! - person Ryan; 06.08.2018

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

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

HTH!

person grtjn    schedule 09.08.2018