如何在MarkLogic Data Hub中加快协调

时间:2018-08-02 06:43:15

标签: marklogic marklogic-dhf

我目前正在为数据的统一进行开发工作。 我注意到协调的完成很慢。
我对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. 有很多for循环调用(不嵌套),大约有20个调用。上面#2中的示例:

2 个答案:

答案 0 :(得分:2)

如果可能的话,我强烈建议您考虑与MarkLogic代表合作解决此问题。改善软件性能可能很复杂,最好与可以与您往返的人保持工作关系。

我经常问的第一个问题是:那么,您期望的SLA是多少?除非您对性能的期望有清晰的预期,否则我无法告诉您这是缓慢还是快速,或者您的期望是现实的还是不现实的。

根据我的经验,性能问题通常属于以下两类之一:软件或基础架构瓶颈。由于从20万条记录到100万条记录的时间推断似乎是线性的,所以我希望您的瓶颈不是严重的软件问题。

我要做的第一件事是检查MarkLogic监视历史记录,并确定您是否在充分利用基础架构。如果没有,请尝试增加协调工作负载的线程数和批处理大小,以便充分利用基础架构。

如果您充分利用基础架构,则可以升级基础架构,也可以开始着手改善软件。

根据您的代码,以下是一些您可以用来改进软件的建议:

  1. 尽可能不进行cts.search调用
  2. 在可能的情况下限制cts.search调用。我感觉到您可能要做的不仅仅是一项工作。
  3. 如果您只需要从文档中提取一个元素,请考虑使用cts.elementValues代替cts.search
  4. 对空格进行规范化,其他字符串函数可能会占用较大的文本字符串。如果您使用大型字符串,请考虑是否可以减少使用它们的时间。
  5. 我建议为您插入的每种类型的表在文档上实现唯一的XML名称空间,这样就不需要集合查询。

答案 1 :(得分:0)

除了Rob的建议外,您可能还想检查协调中的收集器步骤。看起来您正在将多个记录折叠到一个实体实例中,并且如果不迭代所有记录,效果最好。重复记录uris是默认的收集器实现。您可能要用正在创建的实体的某些唯一ID上的cts.values替换它。

如果您确实要遍历uri,则可能是您重新创建同一实体实例的次数与该实体实例所包含的记录一样多,这将浪费大量时间。您可以通过从干净的数据库中运行协调来查看您的最终数据库是否包含大量已删除的片段,从而进行检查。

HTH!