自定义提取器上的OutOfMemory

时间:2017-10-30 13:00:14

标签: azure-data-lake u-sql extractor

我已经将许多小的XML文件拼接到一个文件中,然后创建了一个自定义提取器来返回具有与每个文件对应的一个字节数组的行。

  1. 在远程/主控上运行
    • 运行一个文件(gzipped,11Mb),它运行正常。
    • 为多个文件运行它,我得到一个System.OutOfMemoryException。
  2. 在local / master上运行
    • 运行一个或多个文件(gzip 500+ Mbs),工作正常。
  3. Extractor看起来像这样:

    public override IEnumerable<IRow> Extract(IUnstructuredReader input, IUpdatableRow output)
        {
    
            using (var stream = new StreamReader(input.BaseStream))
            {
                var xml = stream.ReadToEnd();
    
                // Clean stiched XML
                xml = UtilsXml.CleanXml(xml);
    
                // Get nodes - one for each stiched file
                var d = new XmlDocument();
                d.LoadXml(xml);
                var root = d.FirstChild;
    
                for (int i = 0; i < root.ChildNodes.Count; i++)
                {
                    output.Set<object>(1, Encoding.ASCII.GetBytes(root.ChildNodes[i].OuterXml.ToString()));
                    yield return output.AsReadOnly();
                }
    
                yield break;
            }
        }
    

    并且错误消息如下所示:

    ==== Caught exception System.OutOfMemoryException
    
    at System.Xml.XmlDocument.CreateTextNode(String text)
    at System.Xml.XmlLoader.LoadAttributeNode()
    at System.Xml.XmlLoader.LoadNode(Boolean skipOverWhitespace)
    at System.Xml.XmlLoader.LoadDocSequence(XmlDocument parentDoc)
    at System.Xml.XmlDocument.Load(XmlReader reader)
    at System.Xml.XmlDocument.LoadXml(String xml)
    at Microsoft.Analytics.Tools.Formats.Text.XmlByteArrayRowExtractor.<Extract>d__0.MoveNext()
    at ScopeEngine.SqlIpExtractor<ScopeEngine::GZipInput,Extract_0_Data0>.GetNextRow(SqlIpExtractor<ScopeEngine::GZipInput\,Extract_0_Data0>* , Extract_0_Data0* output) in d:\data\ccs\jobs\bc367467-ef86-43d2-a937-46ba2d4cc524_v0\sqlmanaged.h:line 1924
    

    那么我做错了什么?我该如何在远程调试?

    谢谢!

1 个答案:

答案 0 :(得分:1)

不幸的是,本地运行不会强制执行内存分配,因此您必须自己检查本地顶点调试中的内存。

查看上面的代码,我看到您正在将XML文档加载到DOM中。请注意,XML DOM可以将字符串表示中的数据大小分解为10或更多(我作为常驻SQL XML专家在我的时代已经看过2到12)。

今天的每个UDO只能获得1/2 GB的RAM。所以我假设您的XML DOM文档开始超越它。

建议通常是您使用XMLReader接口(http://usql.io上的示例中还有一个读取器提取器)并扫描文档以查找您要查找的信息。

如果您的文档总是足够小(例如,<20MB),您可能需要确保释放其他文档的内存并一次操作一个文档。

我们计划允许您根据内存需求注释您的UDO,但这仍然有点过时。