Azure Data Factory: Cannot write more bytes to the buffer than the configured maximum buffer size: 2147483647

Bij een poging om ExactOnlineREST.Incremental.SalesInvoiceLinesIncremental@eol te laden via Azure Data Factory krijg ik constant deze foutmelding:

ErrorCode=SchemaMappingFailedInHierarchicalToTabularStage
Type=Microsoft.DataTransfer.Common.Shared.HybridDeliveryException
Message=Failed to process hierarchical to tabular stage
error message: Cannot write more bytes to the buffer than the configured maximum buffer size: 2147483647.
Source=Microsoft.DataTransfer.ClientLibrary
Type=System.Net.Http.HttpRequestException
Message=Cannot write more bytes to the buffer than the configured maximum buffer size: 2147483647.
Source=System.Net.Http,’

Deze foutmelding komt direct zodra het laden begint. (dus direct na het cachen bij Invantive).

Samen met mij collega alles afgezocht maar we kunnen niets vinden qua oplossing. Het gekke is, als je een top 1.000.000 (ExactOnlineREST.Incremental.SalesInvoiceLinesIncremental@eol?$top=1000000) en daaronder doet, gaat het wel goed. Maar alles daarboven lijkt te mislukken. Ergens lijkt 1 miljoen de max te zijn. Komt dat bekend voor misschien?

Op dezelfde manier halen we SalesInvoicesBulk en SalesInvoiceLinesBulk, dat gaat wel goed. Ook AccountsIncremental gaat goed. En TransactionLinesIncremental gaat goed, wel met een filter op FinancialYear = 2021, maar dit zijn meer dan 1 miljoen regels op dit moment. Alles via dezelfde pipeline.

Hoogst waarschijnlijk is dit een beperking van Azure Data Factory, maar het kan ook een bug genoemd worden omdat andere Microsoft-producten dit wel ondersteunen.

De getoonde maximumwaarde van de buffer is bijna 2 GB, oftewel 2^31 - 1 (2147483648 - 1), als de maximum waarde van een 32-bits integer met teken.

Het lijkt er op dat de stap van “hierarchical” naar “tabular stage” (wat dat ook mag zijn) een lengtelimiet kent en batchmatig werkt. Zonder al te diepe kennis van Azure Data Factory zal ik proberen uit te leggen wat de mechanismen zijn die waarschijnlijk een rol spelen en het achterliggende probleem.

Samenvattend advies is om een van de volgende opties te proberen:

  • Beperk het datavolume van een individuele download naar ADF door horizontaal (minder kolommen) of verticaal (minder rijen) te filteren. Het zou best kunnen dat een vrij lang tekstveld gebruikt wordt in de Exact Online verkoopfacturen en dat dat leidt tot significant veel onnodig datagebruik.
  • Controleer het gedefinieerde ADF-proces op de afwezigheid van operaties die eerst alle data moeten verzamelen om gegevens op te kunnen leveren zoals groeperen of sorteren (de groepsoperatoren).
  • Mocht vorige stap niks opleveren, meld dan een bug bij Microsoft over deze stap. Motiveer dat het een bug is door de beperkte overdraagbaarheid (compatibiliteit) van een data stroom met enerzijds Power BI Service en Power BI Desktop en anderzijds ADF te benoemen. Juist ADF zou het beter moeten doen qua schaalbaarheid, zeker als men schermt met het begrip “pipes” uit de flow manufacturing.

Streamen van data

Invantive Bridge Online retourneert de waardes als een stream van data, waarbij de gegevens al teruggegeven worden in OData4-formaat over HTTP in een reeks van niet-overlappende brokken.

Deze manier van werken biedt een aantal voordelen:

  • Het inlezen in Power BI of Azure Data Factory kan al beginnen voordat alle gegevens verzameld zijn, zodat er dakpansgewijs gewerkt wordt en de doorlooptijd korter blijft.
  • Een ander voordeel dat er vrijwel geen beperkingen zijn aan de omvang van de download.
  • Ook beperkt het streamen van data enorm het gebruik van de resources op de Invantive-servers; er hoeft vele malen minder werkgeheugen gereserveerd te worden per download omdat idealiter alleen een klein voorraadje aan nog te verwerken data nodig is.
  • Tenslotte heeft de software by design weinig last van harde limieten zoals we die van vroeger kennen met allerhande maximale buffermaten. Als voorbeeld: op SCO Unix was je een tijdje zoet met het goed begrijpen en instellen van de kernelbuffers om er Oracle op werkend te krijgen.

Streaming kan ook nadelen hebben. Een voorbeeld van een lastiger te begrijpen op Exact Online zelf is te vinden in Itgenclr078: Newtonsoft.Json.JsonReaderException / zorgen stabiliteit Exact Online. Het vergelijkbare probleem op Invantive Bridge Online staat beschreven in https://forums.invantive.com/t/datasource-error-odata-invalid-json-a-comma-character-was-expected-in-scope-array-every-two-elements-in-an-array-and-properties-of-an-object-must-be-separated-by-commas/1125: als er een serieuze fout optreedt als de stream eenmaal goed gestart is, dan biedt de HTTP-standaard in combinatie met Power BI weinig mogelijkheden om de foutmelding netjes te melden. In plaats daarvan wordt alleen gemeld dat de OData-gegevens niet geldig zijn (want er staat ergens op het einde een foutmelding).

Batchmatig

Het tegenovergestelde van streaming met telkens losse brokken verwerken is batchmatig werken. Waar streaming lijkt op continuous-flow manufacturing zoals van frisdranken of folies, lijkt batchmatig werken meer op batch production van kleine of grote losse producten.

De software haalt eerst alle gegevens op en stopt die in een buffer. Vervolgens wordt die buffer doorgegeven aan de volgende stap en in zijn geheel verwerkt.

Het is normaal als delen van het gegevensverwerkende proces deels streaming en deels batchmatig zijn. Bij de frisdrankproductie zal er bijvoorbeeld op enig moment ook overgegaan worden op het afvullen in PET-flessen, die daarna individueel verder verwerkt worden.

Azure Data Factory

ADF geeft blijkbaar bij een stap de foutmelding “Cannot write more bytes to the buffer than the configured maximum buffer size: 2147483647”. Er wordt een buffer gebruikt met een maximum omvang. Deze maximum omvang is blijkbaar precies gelijk aan 2^31-1, wat ook de maximale omvang is van een aantal soorten objecten in Microsoft .NET.

Waarschijnlijk is deze specifieke functionaliteit in ADF niet ontworpen met het oog op echt grote volumes data. Dit zou ook kunnen verklaren waarom ADF incidenteel crasht, maar dan pas lang nadat een download uit Invantive Bridge Online is afgerond.

Compressie

Als een terzijde, merk op dat de in Invantive Bridge Online Monitoring getoonde omvang de omvang na compressie is. De werkelijke gegevensomvang voor de verwerking door bijvoorbeeld ADF zal dan waarschijnlijk pakweg het 10-voudige tot 15-voudige zijn.

Bedankt.

Een eerste test wijst uit dat met een OData-filter

ExactOnlineREST.Incremental.SalesInvoiceLinesIncremental@eol?$filter = InvoiceDate ge 2019-01-01T00:00:00.00Z

het inderdaad wel goed gaat; zo kunnen we in delen de data laden in Azure Data Factory.