Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Veel cloudtoepassingen gebruiken asynchrone berichten om informatie uit te wisselen tussen onderdelen van het systeem. Een belangrijk aspect van berichten is het formaat dat wordt gebruikt om de payloadgegevens te coderen. Nadat u een berichttechnologiehebt gekozen, is de volgende stap het definiëren van hoe de berichten worden gecodeerd. Er zijn veel opties beschikbaar, maar de juiste keuze is afhankelijk van uw use-case.
In dit artikel worden enkele overwegingen beschreven.
Berichtuitwisselingsbehoeften
Een berichtuitwisseling tussen een producent en een consument heeft nodig:
- Een vorm of structuur die de nettolading van het bericht definieert.
- Een codeerformaat om de informatielading weer te geven.
- Serialisatiebibliotheken voor het lezen en schrijven van de gecodeerde payload.
De producent van het bericht definieert de berichtvorm op basis van de bedrijfslogica en de informatie die het naar de consumenten wil verzenden. Als u de vorm wilt structuren, verdeelt u de informatie in afzonderlijke of gerelateerde onderwerpen (of velden). Bepaal de kenmerken van de waarden voor deze velden. Houd rekening met de volgende vragen.
- Wat is het meest efficiënte gegevenstype?
- Heeft de payload altijd specifieke velden?
- Heeft de payload één record of een herhaalde set waarden?
Kies vervolgens een coderingsindeling, afhankelijk van uw behoeften. Specifieke factoren omvatten de mogelijkheid om zeer gestructureerde gegevens te maken als u deze nodig hebt, de tijd die nodig is om het bericht te coderen en over te dragen, en de mogelijkheid om de nettolading te parseren. Kies vervolgens een coderingsindeling die aan uw behoeften voldoet.
De consument moet deze beslissingen begrijpen om binnenkomende berichten correct te lezen.
Om de berichten over te dragen, serialiseert de producent het bericht naar een coderingsindeling. Aan de ontvangende kant deserialiseert de consument de payload om de gegevens te benaderen. Dit proces zorgt ervoor dat beide entiteiten hetzelfde model delen. Zolang de vorm ongewijzigd blijft, kan berichten zonder problemen worden voortgezet. Wanneer het contract wordt gewijzigd, moet de coderingsindeling in staat zijn om de wijziging te verwerken zonder de consument te verstoren.
Sommige coderingsindelingen, zoals JSON, beschrijven zelf, wat betekent dat ze kunnen worden geparseerd zonder naar een schema te verwijzen. Deze indelingen produceren echter vaak grotere berichten. Andere indelingen parseren mogelijk niet zo eenvoudig gegevens, maar resulteren in compactere berichten. In dit artikel vindt u een overzicht van de belangrijkste factoren om u te helpen de juiste indeling te kiezen.
Overwegingen voor coderingsformaat
De coderingsindeling definieert hoe een set gestructureerde gegevens wordt weergegeven als bytes. Het type bericht kan van invloed zijn op de keuze van de indeling. Berichten met betrekking tot zakelijke transacties bevatten hoogstwaarschijnlijk zeer gestructureerde gegevens. U kunt ook de gestructureerde gegevens later ophalen voor controledoeleinden. Voor een stroom gebeurtenissen wilt u mogelijk zo snel mogelijk een reeks records lezen en opslaan voor statistische analyse.
Houd rekening met de volgende factoren wanneer u een coderingsindeling kiest.
Menselijke leesbaarheid
Berichtcodering kan breed worden onderverdeeld in op tekst gebaseerde en binaire indelingen.
Met tekstgebaseerde codering is de belading van het bericht in platte tekst, zodat een persoon deze kan inspecteren zonder codebibliotheken te gebruiken. Deze aanpak maakt het gemakkelijker om gegevens te lezen en te begrijpen. Leesbare indelingen zijn geschikt voor archiveringsgegevens. Omdat een mens de nettolading kan lezen, zijn tekstindelingen eenvoudiger om fouten op te sporen en naar logboeken te verzenden voor het oplossen van fouten.
Het nadeel van op tekst gebaseerde codering is dat de nettolading meestal groter is. De payloadgrootte kan vaak worden verminderd door middel van een minificatieproces, zolang deze kan worden omgekeerd voor menselijke leesbaarheid wanneer dat nodig is. Veelgebruikte indelingen op basis van tekst zijn JSON en YAML.
Versleuteling
Als er gevoelige gegevens in de berichten staan, moet u overwegen of deze berichten volledig moeten worden versleuteld. Als er alleen specifieke velden moeten worden versleuteld en u de cloudkosten wilt verlagen, kunt u overwegen om een bibliotheek zoals NServiceBus te gebruiken.
Coderingsgrootte
De berichtgrootte is van invloed op de netwerkinvoer-/uitvoerprestaties op de kabel. Binaire indelingen zijn compacter dan op tekst gebaseerde indelingen. Binaire indelingen vereisen serialisatie- en deserialisatiebibliotheken. De payload kan alleen maar worden gelezen wanneer deze wordt gedecodeerd.
Gebruik een binaire indeling als u het netwerkverkeer wilt verminderen en berichten sneller wilt versturen. Deze indelingscategorie wordt aanbevolen in scenario's waarin opslag of netwerkbandbreedte een probleem is. Opties voor binaire indelingen zijn Apache Avro, Google Protocol Buffers (protobuf), MessagePack en Beknopte binaire objectweergave (CBOR). De voor- en nadelen van deze indelingen worden verderop beschreven in Choices voor coderingsindelingen.
Het nadeel van binaire indeling is dat de nettolading niet door mensen kan worden gelezen. De meeste binaire indelingen maken gebruik van complexe systemen die kostbaar kunnen worden onderhouden. Ze hebben ook speciale bibliotheken nodig om te decoderen, wat mogelijk niet wordt ondersteund als u archiveringsgegevens wilt ophalen.
Voor niet-binaire indelingen verwijdert een minificatieproces overbodige spaties en tekens, terwijl de naleving van de specificatie van de indeling behouden blijft. Deze aanpak helpt de coderingsgrootte te verminderen zonder de structuur te wijzigen. Evalueer de mogelijkheden van uw encoder om de standaardwaarde te minificeren. Bijvoorbeeld, JsonSerializerOptions.WriteIndented
van .NET's System.Text.Json.JsonSerializer
bepaalt de automatische minificatie bij het maken van JSON-tekst.
Inzicht in de belading
Een nettolading van een bericht arriveert als een reeks bytes. Om deze volgorde te parseren, moet de consument toegang hebben tot metagegevens die de gegevensvelden binnen de payload beschrijven. De twee belangrijkste methoden voor het opslaan en distribueren van metagegevens zijn:
Getagde metagegevens. In sommige coderingsindelingen, met name JSON, worden velden gelabeld met het gegevenstype en de id, binnen de hoofdtekst van het bericht. Deze indelingen zijn zelfbeschrijvend omdat ze kunnen worden geparseerd in een woordenboek met waarden zonder naar een schema te verwijzen. Een manier om de consument inzicht te geven in de velden is door een query uit te voeren op verwachte waarden. De producer verzendt bijvoorbeeld een payload in JSON. De gebruiker parseert de JSON in een woordenboek en controleert het bestaan van velden om de payload te begrijpen. Een andere manier is dat de consument een gegevensmodel toepast dat de producent deelt. Als u bijvoorbeeld een statisch getypte taal gebruikt, kunnen veel JSON-serialisatiebibliotheken een JSON-tekenreeks parseren in een getypte klasse.
Schema. Een schema definieert formeel de structuur- en gegevensvelden van een bericht. In dit model hebben de producent en consument een contract via een goed gedefinieerd schema. Het schema kan de gegevenstypen, vereiste of optionele velden, versiegegevens en de structuur van de nettolading definiëren. De producent verzendt de ladingsbestand volgens het schrijfschema. De consument ontvangt de payload door een leesschema toe te passen. Het bericht wordt geserialiseerd en gedeserialiseerd met behulp van de coderingsspecifieke bibliotheken. Schema's kunnen op twee manieren worden gedistribueerd:
Sla het schema op als een preambule of koptekst in het bericht, maar los van de nettolading.
Sla het schema extern op.
Sommige coderingsindelingen definiëren het schema en maken gebruik van hulpprogramma's die klassen genereren op basis van het schema. De producent en consument gebruiken deze klassen en bibliotheken om de last te serialiseren en deserialiseren. De bibliotheken bieden ook compatibiliteitscontroles tussen het schrijver- en lezerschema. Zowel protobuf als Apache Avro volgen die benadering. Het belangrijkste verschil is dat protobuf een taalagnostische schemadefinitie heeft en Avro compacte JSON gebruikt. Een ander verschil is de manier waarop beide indelingen compatibiliteitscontroles bieden tussen lezer- en schrijfschema's.
Een andere manier om het schema extern op te slaan, bevindt zich in een schemaregister. Het bericht bevat een verwijzing naar het schema en de payload. De producent verzendt de schema-id in het bericht. De consument haalt het schema op door deze identificatie te specificeren uit een externe opslag. Beide partijen gebruiken een indelingsspecifieke bibliotheek om berichten te lezen en te schrijven. Naast het opslaan van het schema kan een register compatibiliteitscontroles bieden om ervoor te zorgen dat het contract tussen de producent en consument niet wordt verbroken naarmate het schema zich ontwikkelt.
Voordat u een benadering kiest, moet u bepalen of de grootte van de overdrachtsgegevens of de mogelijkheid om de gearchiveerde gegevens later te parseren belangrijker is.
Het opslaan van het schema samen met de nettolading produceert een grotere coderingsgrootte en is ideaal voor onregelmatige berichten. Kies deze methode als het overdragen van kleinere segmenten van bytes cruciaal is of als u een reeks records verwacht. De kosten voor het onderhouden van een extern schemaarchief kunnen hoog zijn.
Als on-demand decodering van de payload echter belangrijker is dan de grootte, zorgt het opnemen van het schema met de payload of de benadering van getagde metadata ervoor dat decodering achteraf gegarandeerd is. Er kan een aanzienlijke toename van de berichtgrootte zijn die van invloed is op de opslagkosten.
Schemaversiebeheer
Naarmate de bedrijfsvereisten veranderen, wordt verwacht dat de shape verandert en zal het schema zich ontwikkelen. Met versiebeheer kan de producent schema-updates aangeven die mogelijk nieuwe functies bevatten. Versiebeheer heeft twee belangrijke aspecten:
De consument moet de wijzigingen bijhouden en begrijpen.
Een manier is dat de consument alle velden controleert om te bepalen of het schema is gewijzigd. Een andere manier is dat de producent een schemaversienummer met het bericht publiceert. Wanneer het schema zich ontwikkelt, wordt de versie verhoogd door de producent.
Wijzigingen mogen de bedrijfslogica van consumenten niet beïnvloeden of verbreken.
Stel dat een veld wordt toegevoegd aan een bestaand schema. Als consumenten die de nieuwe versie gebruiken een payload volgens de oude versie ontvangen, kan hun logica instorten als ze het ontbreken van het nieuwe veld niet kunnen negeren. Overweeg nu het tegenovergestelde scenario. Als een veld wordt verwijderd in het nieuwe schema, kunnen gebruikers die het oude schema gebruiken mogelijk de gegevens niet lezen.
Coderingsindelingen zoals Avro bieden de mogelijkheid om standaardwaarden te definiëren. Als in het voorgaande voorbeeld het veld wordt toegevoegd met een standaardwaarde, wordt het ontbrekende veld gevuld met de standaardwaarde. Andere indelingen, zoals protobuf, bieden vergelijkbare functionaliteit via vereiste en optionele velden.
Payloadstructuur
Overweeg of de gegevens in de nettolading zijn gestructureerd als een reeks records of als één afzonderlijke nettolading. De ladingstructuur kan worden gecategoriseerd in een van de volgende modellen.
Matrix/woordenlijst/waarde: Definieert vermeldingen die waarden bevatten in een of multidimensionale matrices. Inzendingen hebben unieke sleutel-/waardeparen. Het model kan worden uitgebreid om complexe structuren weer te geven. Enkele voorbeelden zijn JSON, Apache Avro en MessagePack.
Deze indeling is geschikt als berichten afzonderlijk worden gecodeerd met verschillende schema's. Als u meerdere records hebt, kan de gegevenslast overbodig worden. Deze redundantie kan de payload doen opzwellen.
Tabelgegevens: Informatie is onderverdeeld in rijen en kolommen. Elke kolom geeft een veld of het onderwerp van de informatie aan en elke rij bevat waarden voor deze velden. Deze indeling is efficiënt voor een herhalende set gegevens, zoals tijdreeksgegevens.
Comma-Separated Waarden (CSV) is een van de eenvoudigste tekstformaten. Het presenteert gegevens als een reeks records met een gemeenschappelijke header. Voor binaire codering heeft Apache Avro een preambule die vergelijkbaar is met een CSV-header, maar die een compactere coderingsgrootte genereert.
Bibliotheekondersteuning
U moet bekende indelingen gebruiken in plaats van een eigen model. Bekende indelingen worden ondersteund door bibliotheken die de gemeenschap algemeen ondersteunt. Met gespecialiseerde indelingen hebt u specifieke bibliotheken nodig. Uw bedrijfslogica moet mogelijk een aantal van de API-ontwerpopties van de bibliotheken omzeilen.
Kies voor een indeling op basis van een schema een coderingsbibliotheek die compatibiliteitscontroles tussen de lezer en het schrijfschema maakt. Specifieke coderingsbibliotheken, zoals Apache Avro, verwachten dat de consument zowel de schrijver als het lezerschema opgeeft voordat het bericht wordt gedeserialiseerd. Deze controle zorgt ervoor dat de consument op de hoogte is van de schemaversies.
Interoperabiliteit
Uw keuze aan indelingen kan afhankelijk zijn van de specifieke workload of het technologie-ecosysteem.
Bijvoorbeeld:
Azure Stream Analytics biedt systeemeigen ondersteuning voor JSON, CSV en Avro. Wanneer uw workload Gebruikmaakt van Stream Analytics, is het zinvol om een van deze indelingen te kiezen.
JSON is een standaardindeling voor HTTP REST API's. Als uw toepassing JSON-nettoladingen van clients ontvangt en deze vervolgens in een berichtenwachtrij plaatst voor asynchrone verwerking, kan het zinvol zijn om JSON te gebruiken voor de berichten in plaats van opnieuw te coderen in een andere indeling.
Dit zijn slechts twee voorbeelden van interoperabiliteitsoverwegingen. Gestandaardiseerde indelingen zijn over het algemeen meer interoperabel dan aangepaste indelingen. In tekstopties is JSON een van de meest interoperabele opties.
Opties voor coderingsindelingen
De volgende populaire coderingsindelingen worden gebruikt voor gegevensweergave en -overdracht. Houd rekening met de overwegingen voordat u een formaat kiest.
JSON
JSON is een open standaard, met de indeling die is gedefinieerd door de Internet Engineering Task Force (IETF) in RFC 8259. JSON is een op tekst gebaseerde indeling die het matrix-/woordenlijst-/waardemodel volgt.
JSON kan worden gebruikt voor het taggen van metagegevens en u kunt de nettolading parseren zonder een schema. JSON biedt ondersteuning voor de optie om optionele velden op te geven, wat helpt bij zowel voorwaartse als achterwaartse compatibiliteit.
Het grootste voordeel is dat het universeel beschikbaar is. JSON is de meest interoperabele coderingsindeling en de standaardindeling voor veel berichtenservices.
Omdat JSON een op tekst gebaseerde indeling is, is het niet efficiënt via de kabel en niet ideaal wanneer opslag een probleem is. Gebruik indien mogelijk minificatietechnieken. Als u items die in de cache zijn opgeslagen rechtstreeks via HTTP naar een client retourneert, kan het opslaan in JSON mogelijk de kosten van het deserialiseren vanuit een ander formaat en daarna serialiseren naar JSON besparen.
Gebruik JSON voor berichten met één record of voor een reeks berichten waarin elk bericht een ander schema heeft. Vermijd het gebruik van JSON voor een reeks records, zoals voor tijdreeksgegevens.
Er zijn andere variaties van JSON, zoals
CSV-bestand
CSV is een tabelindeling op basis van tekst. De koptekst van de tabel geeft de velden aan. CSV is geschikt voor berichten die een set records bevatten.
Het nadeel van CSV is een gebrek aan standaardisatie. Er zijn meerdere manieren om scheidingstekens, kopteksten en lege velden uit te drukken.
Protocolbuffers
ProtocolBuffers (of protobuf) is een serialisatie-indeling die gebruikmaakt van sterk getypte definitiebestanden om schema's in sleutel-/waardeparen te definiëren. Deze definitiebestanden worden vervolgens gecompileerd naar taalspecifieke klassen die worden gebruikt voor het serialiseren en deserialiseren van berichten.
Het bericht bevat een kleine, gecomprimeerde binaire nettolading, wat resulteert in een snellere gegevensoverdracht. Het nadeel is dat de nettolading niet door mensen kan worden gelezen. Omdat het schema extern wordt opgeslagen, is deze indeling niet ideaal voor scenario's waarvoor u gearchiveerde gegevens moet ophalen.
Apache Avro
Apache Avro is een binaire serialisatie-indeling die gebruikmaakt van een definitiebestand dat vergelijkbaar is met protobuf, maar zonder een compilatiestap. In plaats daarvan bevatten geserialiseerde gegevens altijd een schema-preambule.
De preambule kan de header of een schema-id bevatten. Vanwege de kleinere coderingsgrootte wordt Avro aanbevolen voor streaminggegevens. Omdat het een header heeft die van toepassing is op een set records, is deze ook geschikt voor tabellaire gegevens.
Apache Parquet
Apache Parquet- is een kolomopslagbestandsindeling die doorgaans is gekoppeld aan Apache Hadoop en gerelateerde frameworks voor gegevensverwerking.
Apache Parquet ondersteunt gegevenscompressie en biedt beperkte mogelijkheden voor de ontwikkeling van schema's. Deze indeling wordt doorgaans gebruikt wanneer andere big data-technologieën in uw workload dit vereisen voor het maken of verbruik van gegevens.
MessagePack
MessagePack is een binaire serialisatie-indeling die is ontworpen om compact te zijn voor verzending via de kabel. MessagePack heeft geen schemadefinitie en typecontrole. Deze indeling wordt niet aanbevolen voor bulkopslag.
CBOR
CBOR (Specificatie) is een binaire indeling die een kleine coderingsgrootte biedt. Het voordeel van het gebruik van CBOR via MessagePack is de naleving van IETF in RFC7049.