Migrieren von Time Series Insights (TSI) Gen2 zu Azure Data Explorer
Hinweis
Der TSI-Dienst (Time Series Insights) wird nach März 2025 nicht mehr unterstützt. Erwägen Sie, vorhandene TSI-Umgebungen so bald wie möglich zu alternativen Lösungen zu migrieren. Weitere Informationen zur Einstellung und Migration finden Sie in unserer Dokumentation.
Übersicht
Empfehlungen für die Migration auf hoher Ebene
Funktion | Gen2-Status | Migration empfohlen |
---|---|---|
Erfassen von JSON aus dem Hub mit Vereinfachung und Escapezeichen | TSI-Erfassung | ADX – OneClick-Erfassung/Assistent |
Öffnen von Cold Storage | Kundenspeicherkonto | Fortlaufender Datenexport in die kundenseitig angegebene externe Tabelle in ADLS. |
PBI-Connector | Private Vorschau | Verwenden des ADX-PBI-Connectors Manuelles erneutes Generieren von TSQ in KQL |
Spark-Connector | Private Vorschau Abfragen von Telemetriedaten Abfragemodelldaten | Migrieren von Daten zu ADX Verwenden des ADX Spark-Connectors für Telemetriedaten und Exportieren des Modells in JSON und Laden in Spark Erneutes Generieren von Abfragen in KQL |
Massenupload | Private Vorschau | Verwenden von ADX OneClick-Erfassung und LightIngest. Eine optional eingerichtete Partitionierung innerhalb von ADX |
Time Series-Modell | Kann als JSON-Datei exportiert werden Kann in ADX importiert werden, um Joins in KQL auszuführen | |
TSI-Explorer | Umschalten zwischen warm und kalt | ADX Dashboards |
Abfragesprache | Zeitreihenabfragen (Time Series Queries, TSQ) | Erneutes Generieren von Abfragen in KQL Verwenden von Kusto SDKs anstelle von TSI SDKs |
Migrieren von Telemetriedaten
Verwenden Sie den Ordner PT=Time
im Speicherkonto, um die Kopie aller Telemetriedaten in der Umgebung abzurufen. Weitere Informationen finden Sie unter Datenspeicher.
Migrationsschritt 1: Abrufen von Statistiken zu Telemetriedaten
Daten
- Übersicht über die Umgebung
- Aufzeichnen der Umgebungs-ID aus dem ersten Teil des FQDN für den Datenzugriff (z. B. d390b0b0-1445-4c0c-8365-68d6382c1c2a aus .env.crystal-dev.windows-int.net)
- Übersicht über die Umgebung -> Speicherkonfiguration -> Speicherkonto
- Verwenden von Storage-Explorer zum Abrufen von Ordnerstatistiken
- Aufzeichnen von Größe und Anzahl der Blobs im Ordner
PT=Time
Zeichnen Sie für Kunden in der privaten Vorschauversion des Massenimports auch diePT=Import
-Größe und die Anzahl von Blobs auf.
- Aufzeichnen von Größe und Anzahl der Blobs im Ordner
Migrationsschritt 2: Migrieren von Telemetriedaten zu ADX
Erstellen eines ADX-Clusters
Definieren Sie die Clustergröße basierend auf der Datengröße mithilfe der ADX-Kostenschätzung.
- Rufen Sie aus Event Hubs-Metriken (oder IoT Hub-Metriken) die Rate der täglich erfassten Daten ab. Rufen Sie aus dem Speicherkonto, das mit der TSI-Umgebung verbunden ist, den Umfang der Daten ab, die sich im Blobcontainer befinden, der von TSI verwendet wird. Diese Informationen werden verwendet, um die ideale Größe eines ADX-Clusters für Ihre Umgebung zu berechnen.
- Öffnen Sie die Azure Data Explorer-Kostenschätzung, und füllen Sie die vorhandenen Felder mit den gefundenen Informationen. Legen Sie „Workloadtyp“ auf „Datenspeicheroptimiert“ und „Heiße Daten“ mit der Gesamtmenge der aktiv abgefragten Daten fest.
- Nachdem Sie alle Informationen angegeben haben, schlägt die Azure Data Explorer-Kostenschätzung eine VM-Größe und die Anzahl der Instanzen für Ihren Cluster vor. Analysieren Sie, ob die Größe der aktiv abgefragten Daten in den Cache für heiße Daten passt. Multiplizieren Sie die Anzahl der vorgeschlagenen Instanzen mit der Cachegröße der VM-Größe. Beispiel:
- Kostenschätzungsvorschlag: 9x DS14 + 4 TB (Cache)
- Vorgeschlagener Cache für heiße Daten gesamt: 36 TB = [9x (Instanzen) x 4 TB (von Cache für heiße Daten pro Knoten)]
- Weitere zu beachtende Faktoren:
- Umgebungswachstum: Berücksichtigen Sie bei der Planung der ADX-Clustergröße das Datenwachstum im Laufe der Zeit.
- Hydration und Partitionierung: Wenn Sie die Anzahl der Instanzen im ADX-Cluster definieren, sollten Sie zusätzliche Knoten (ungefähr die 2- bis 3-fache Anzahl) in Betracht ziehen, um die Hydration und Partitionierung zu beschleunigen.
- Weitere Informationen zur Computeauswahl finden Sie unter Auswählen der passenden Compute-SKU für Ihren Azure Data Explorer-Cluster.
Um Ihren Cluster und die Datenerfassung optimal zu überwachen, sollten Sie Diagnoseeinstellungen aktivieren und die Daten an einen Log Analytics-Arbeitsbereich senden.
Wechseln Sie auf dem Blatt „Azure Data Explorer“ zu „Überwachung | Diagnoseeinstellungen“, und klicken Sie auf „Diagnoseeinstellung hinzufügen“.
Geben Sie Folgendes ein:
- Name der Diagnoseeinstellung: Anzeigename für diese Konfiguration
- Protokolle: Wählen Sie mindestens SucceededIngestion, FailedIngestion, IngestionBatching aus
- Wählen Sie den Log Analytics-Arbeitsbereich aus, an den die Daten gesendet werden sollen (wenn Sie noch keinen besitzen, müssen Sie vor diesem Schritt einen bereitstellen).
Datenpartitionierung
- Für die meisten Datasets ist die ADX-Standardpartitionierung ausreichend.
- Die Datenpartitionierung ist in einer sehr spezifischen Gruppe von Szenarien nützlich und sollte andernfalls nicht angewendet werden:
- Verbesserung der Abfragelatenz in großen Datasets, bei denen die meisten Abfragen nach einer Zeichenfolgenspalte mit hoher Kardinalität filtern, z. B. einer Zeitreihen-ID.
- Beim Erfassen von Daten in ungeordneter Reihenfolge, wenn z. B. Ereignisse aus der Vergangenheit möglicherweise erst Tage oder Wochen nach ihrer Entstehung im Ursprung erfasst werden.
- Weitere Informationen finden Sie unter Partitionierungsrichtlinie.
Vorbereiten auf die Datenerfassung
Gehe zu https://dataexplorer.azure.com.
Wechseln Sie zur Registerkarte „Daten“, und wählen Sie „Daten aus Blobcontainer erfassen“ aus.
Wählen Sie „Cluster“, „Datenbank“ aus, und erstellen Sie eine neue Tabelle mit dem Namen, den Sie für die TSI-Daten auswählen.
Wählen Sie Weiter: Quelle aus.
Wählen Sie auf der Registerkarte „Quelle“ Folgendes aus:
- Verlaufsdaten
- Wählen Sie „Container“ aus.
- Wählen Sie das Abonnement und Speicherkonto für Ihre TSI-Daten aus.
- Wählen Sie den Container aus, der mit Ihrer TSI-Umgebung korreliert.
Wählen Sie „Erweiterte Einstellungen“ aus.
- Muster der Erstellungszeit: '/'jjjjMMttHHmmssfff'_'
- Muster für Blobname: *.parquet
- Aktivieren Sie die Option „Warten Sie nicht, bis die Erfassung abgeschlossen ist“.
Fügen Sie unter „Dateifilter“ den Ordnerpfad
V=1/PT=Time
hinzu.Wählen Sie die Option „Weiter: Schema“ aus.
Hinweis
TSI wendet beim Beibehalten von Spalten in Parquet-Dateien eine gewisse Vereinfachung und Escapezeichen an. Weitere Informationen finden Sie unter diesen Links: Vereinfachungs- und -Escaperegeln, Aktualisierungen von Erfassungsregeln.
Wenn das Schema unbekannt ist oder variiert:
Wenn das Schema bekannt oder festgelegt ist:
- Vergewissern Sie sich, dass die Daten richtig aussehen. Korrigieren Sie bei Bedarf beliebige Typen.
- Wählen Sie „Weiter: Zusammenfassung“ aus.
Kopieren Sie den LightIngest-Befehl, und speichern Sie ihn an einer anderen Stelle, damit Sie ihn im nächsten Schritt verwenden können.
Datenerfassung
Vor dem Erfassen von Daten müssen Sie das LightIngest-Tool installieren. Der vom OneClick-Tool generierte Befehl enthält ein SAS-Token. Es empfiehlt sich, einen neuen zu generieren, damit Sie die Ablaufzeit steuern können. Navigieren Sie im Portal zum Blobcontainer für die TSI-Umgebung, und wählen Sie „SAS-Token“ aus.
Hinweis
Es wird auch empfohlen, Ihren Cluster hochzuskalieren, bevor Sie eine umfassende Erfassung starten. Beispiel: D14 oder D32 mit mehr als 8 Instanzen.
Legen Sie Folgendes fest:
- Berechtigungen: Lesen und Auflisten
- Ablauf: Legen Sie einen Zeitraum fest, bei dem Sie sicher sind, dass die Migration der Daten abgeschlossen ist.
Wählen Sie „SAS-Token und -URL generieren“ aus, und kopieren Sie die „Blob-SAS-URL“.
Wechseln Sie zum LightIngest-Befehl, den Sie zuvor kopiert haben. Ersetzen Sie den Parameter „-source“ im Befehl durch diese SAS-Blob-URL.
Option 1: Alle Daten erfassen. Für kleinere Umgebungen können Sie alle Daten mit einem einzigen Befehl erfassen.
- Öffnen Sie eine Eingabeaufforderung, und wechseln Sie in das Verzeichnis, in das das LightIngest-Tool extrahiert wurde. Fügen Sie dort den LightIngest-Befehl ein, und führen Sie ihn aus.
Option 2: Daten nach Jahr oder Monat erfassen. Für größere Umgebungen oder zum Testen mit einem kleineren Dataset können Sie den Lightingest-Befehl weiter filtern.
Nach Jahr: Ändern Sie den Parameter „-prefix“.
- Vorher:
-prefix:"V=1/PT=Time"
- Nachher:
-prefix:"V=1/PT=Time/Y=<Year>"
- Beispiel:
-prefix:"V=1/PT=Time/Y=2021"
- Vorher:
Nach Monat: Ändern Sie den Parameter „-prefix“.
- Vorher:
-prefix:"V=1/PT=Time"
- Nachher:
-prefix:"V=1/PT=Time/Y=<Year>/M=<month #>"
- Beispiel:
-prefix:"V=1/PT=Time/Y=2021/M=03"
- Vorher:
Nachdem Sie den Befehl geändert haben, führen Sie ihn wie oben beschrieben aus. Wenn die Erfassung abgeschlossen ist (mithilfe der unten angegebenen Überwachungsoption), ändern Sie den Befehl für das nächste Jahr und den Monat, den Sie erfassen möchten.
Überwachen der Erfassung
Der LightIngest-Befehl hat das Flag „-dontWait“ enthalten, sodass der Befehl selbst nicht auf den Abschluss der Erfassung wartet. Die beste Möglichkeit, den Fortschritt während des Vorgangs zu überwachen, ist die Verwendung der Registerkarte „Insights“ (Erkenntnisse) im Portal. Öffnen Sie im Portal den Abschnitt des Azure Data Explorer-Clusters, und wechseln Sie zu „Monitoring | Insights“ (Überwachung | Erkenntnisse).
Sie können den Abschnitt „Erfassung (Vorschau)“ mit den folgenden Einstellungen verwenden, um die Erfassung zu überwachen, während sie durchgeführt wird.
- Zeitbereich: Letzte 30 Minuten
- Sehen Sie sich „Erfolgreich“ und „Nach Tabelle“ an.
- Wenn Fehler aufgetreten sind, sehen Sie sich „Fehler“ und „Nach Tabelle“ an.
Sie wissen, dass die Erfassung abgeschlossen ist, sobald Sie sehen, dass die Metriken für Ihre Tabelle auf 0 zurückgeht. Wenn Sie weitere Details anzeigen möchten, können Sie Log Analytics verwenden. Wählen Sie im Abschnitt des Azure Data Explorer-Clusters auf der Registerkarte „Protokoll“ die folgende Option aus:
Nützliche Abfragen
Grundlegendes zum Schema, wenn ein dynamisches Schema verwendet wird
| project p=treepath(fullrecord)
| mv-expand p
| summarize by tostring(p)
Zugreifen auf Werte im Array
| where id_string == "a"
| summarize avg(todouble(fullrecord.['nestedArray_v_double'])) by bin(timestamp, 1s)
| render timechart
Migrieren des Zeitreihenmodells (Time Series Model, TSM) zu Azure Data Explorer
Das Modell kann im JSON-Format über die TSI-Explorer-Benutzeroberfläche oder die TSM-Batch-API aus der TSI-Umgebung heruntergeladen werden. Anschließend kann das Modell in ein anderes System wie Azure Data Explorer importiert werden.
Laden Sie TSM von der TSI-Benutzeroberfläche herunter.
Löschen Sie die ersten drei Zeilen mit VSCode oder einem anderen Editor.
Suchen Sie mit VSCode oder einem anderen Editor, und ersetzen Sie den regulären Ausdruck
\},\n \{
durch}{
.Erfassung als JSON in ADX als separate Tabelle mithilfe der Funktion „Aus Datei hochladen“.
Übersetzen von Zeitreihenabfragen (TSQ) in KQL
GetEvents
{
"getEvents": {
"timeSeriesId": [
"assest1",
"siteId1",
"dataId1"
],
"searchSpan": {
"from": "2021-11-01T00:00:0.0000000Z",
"to": "2021-11-05T00:00:00.000000Z"
},
"inlineVariables": {},
}
}
events
| where timestamp >= datetime(2021-11-01T00:00:0.0000000Z) and timestamp < datetime(2021-11-05T00:00:00.000000Z)
| where assetId_string == "assest1" and siteId_string == "siteId1" and dataid_string == "dataId1"
| take 10000
GetEvents mit Filter
{
"getEvents": {
"timeSeriesId": [
"deviceId1",
"siteId1",
"dataId1"
],
"searchSpan": {
"from": "2021-11-01T00:00:0.0000000Z",
"to": "2021-11-05T00:00:00.000000Z"
},
"filter": {
"tsx": "$event.sensors.sensor.String = 'status' AND $event.sensors.unit.String = 'ONLINE"
}
}
}
events
| where timestamp >= datetime(2021-11-01T00:00:0.0000000Z) and timestamp < datetime(2021-11-05T00:00:00.000000Z)
| where deviceId_string== "deviceId1" and siteId_string == "siteId1" and dataId_string == "dataId1"
| where ['sensors.sensor_string'] == "status" and ['sensors.unit_string'] == "ONLINE"
| take 10000
GetEvents mit projizierter Variable
{
"getEvents": {
"timeSeriesId": [
"deviceId1",
"siteId1",
"dataId1"
],
"searchSpan": {
"from": "2021-11-01T00:00:0.0000000Z",
"to": "2021-11-05T00:00:00.000000Z"
},
"inlineVariables": {},
"projectedVariables": [],
"projectedProperties": [
{
"name": "sensors.value",
"type": "String"
},
{
"name": "sensors.value",
"type": "bool"
},
{
"name": "sensors.value",
"type": "Double"
}
]
}
}
events
| where timestamp >= datetime(2021-11-01T00:00:0.0000000Z) and timestamp < datetime(2021-11-05T00:00:00.000000Z)
| where deviceId_string== "deviceId1" and siteId_string == "siteId1" and dataId_string == "dataId1"
| take 10000
| project timestamp, sensorStringValue= ['sensors.value_string'], sensorBoolValue= ['sensors.value_bool'], sensorDoublelValue= ['sensors.value_double']
AggregateSeries
{
"aggregateSeries": {
"timeSeriesId": [
"deviceId1"
],
"searchSpan": {
"from": "2021-11-01T00:00:00.0000000Z",
"to": "2021-11-05T00:00:00.0000000Z"
},
"interval": "PT1M",
"inlineVariables": {
"sensor": {
"kind": "numeric",
"value": {
"tsx": "coalesce($event.sensors.value.Double, todouble($event.sensors.value.Long))"
},
"aggregation": {
"tsx": "avg($value)"
}
}
},
"projectedVariables": [
"sensor"
]
}
events
| where timestamp >= datetime(2021-11-01T00:00:00.0000000Z) and timestamp < datetime(2021-11-05T00:00:00.0000000Z)
| where deviceId_string == "deviceId1"
| summarize avgSensorValue= avg(coalesce(['sensors.value_double'], todouble(['sensors.value_long']))) by bin(IntervalTs = timestamp, 1m)
| project IntervalTs, avgSensorValue
AggregateSeries mit Filter
{
"aggregateSeries": {
"timeSeriesId": [
"deviceId1"
],
"searchSpan": {
"from": "2021-11-01T00:00:00.0000000Z",
"to": "2021-11-05T00:00:00.0000000Z"
},
"filter": {
"tsx": "$event.sensors.sensor.String = 'heater' AND $event.sensors.location.String = 'floor1room12'"
},
"interval": "PT1M",
"inlineVariables": {
"sensor": {
"kind": "numeric",
"value": {
"tsx": "coalesce($event.sensors.value.Double, todouble($event.sensors.value.Long))"
},
"aggregation": {
"tsx": "avg($value)"
}
}
},
"projectedVariables": [
"sensor"
]
}
}
events
| where timestamp >= datetime(2021-11-01T00:00:00.0000000Z) and timestamp < datetime(2021-11-05T00:00:00.0000000Z)
| where deviceId_string == "deviceId1"
| where ['sensors.sensor_string'] == "heater" and ['sensors.location_string'] == "floor1room12"
| summarize avgSensorValue= avg(coalesce(['sensors.value_double'], todouble(['sensors.value_long']))) by bin(IntervalTs = timestamp, 1m)
| project IntervalTs, avgSensorValue
Migration von TSI Power BI-Connector zu ADX Power BI-Connector
Die bei dieser Migration erforderlichen manuellen Schritte sind:
- Konvertieren der Power BI-Abfrage in TSQ
- Konvertieren von TSQ in KQL Power BI-Abfrage in TSQ: Die aus dem TSI-UX-Explorer kopierte Power BI-Abfrage sieht wie unten dargestellt aus.
Für Rohdaten (GetEvents-API)
{"storeType":"ColdStore","isSearchSpanRelative":false,"clientDataType":"RDX_20200713_Q","environmentFqdn":"6988946f-2b5c-4f84-9921-530501fbab45.env.timeseries.azure.com", "queries":[{"getEvents":{"searchSpan":{"from":"2019-10-31T23:59:39.590Z","to":"2019-11-01T05:22:18.926Z"},"timeSeriesId":["Arctic Ocean",null],"take":250000}}]}
- Für die Konvertierung in TSQ erstellen Sie einen JSON-Code aus den obigen Nutzdaten. Die Dokumentation zur GetEvents-API enthält auch Beispiele, um sie besser zu verstehen. Abfrage – Ausführen – REST-API (Azure Time Series Insights) | Microsoft-Dokumentation
- Die konvertierte TSQ sieht wie unten dargestellt aus. Dies sind die JSON-Nutzdaten in „Abfragen“.
{
"getEvents": {
"timeSeriesId": [
"Arctic Ocean",
"null"
],
"searchSpan": {
"from": "2019-10-31T23:59:39.590Z",
"to": "2019-11-01T05:22:18.926Z"
},
"take": 250000
}
}
Für „Daten aggregieren“ (API für „Reihe aggregieren“)
- Bei einer einzelnen Inlinevariablen sieht die PowerBI-Abfrage im TSI-UX-Explorer wie folgt aus:
{"storeType":"ColdStore","isSearchSpanRelative":false,"clientDataType":"RDX_20200713_Q","environmentFqdn":"6988946f-2b5c-4f84-9921-530501fbab45.env.timeseries.azure.com", "queries":[{"aggregateSeries":{"searchSpan":{"from":"2019-10-31T23:59:39.590Z","to":"2019-11-01T05:22:18.926Z"},"timeSeriesId":["Arctic Ocean",null],"interval":"PT1M", "inlineVariables":{"EventCount":{"kind":"aggregate","aggregation":{"tsx":"count()"}}},"projectedVariables":["EventCount"]}}]}
- Für die Konvertierung in TSQ erstellen Sie einen JSON-Code aus den obigen Nutzdaten. Die Dokumentation zur AggregateSeries-API enthält auch Beispiele, um sie besser zu verstehen. Abfrage – Ausführen – REST-API (Azure Time Series Insights) | Microsoft-Dokumentation
- Die konvertierte TSQ sieht wie unten dargestellt aus. Dies sind die JSON-Nutzdaten in „Abfragen“.
{
"aggregateSeries": {
"timeSeriesId": [
"Arctic Ocean",
"null"
],
"searchSpan": {
"from": "2019-10-31T23:59:39.590Z",
"to": "2019-11-01T05:22:18.926Z"
},
"interval": "PT1M",
"inlineVariables": {
"EventCount": {
"kind": "aggregate",
"aggregation": {
"tsx": "count()"
}
}
},
"projectedVariables": [
"EventCount",
]
}
}
- Fügen Sie für mehrere Inlinevariablen den JSON-Code an „inlineVariables“ an, wie im folgenden Beispiel gezeigt. Die Power BI-Abfrage für mehrere Inlinevariablen sieht wie folgt aus:
{"storeType":"ColdStore","isSearchSpanRelative":false,"clientDataType":"RDX_20200713_Q","environmentFqdn":"6988946f-2b5c-4f84-9921-530501fbab45.env.timeseries.azure.com","queries":[{"aggregateSeries":{"searchSpan":{"from":"2019-10-31T23:59:39.590Z","to":"2019-11-01T05:22:18.926Z"},"timeSeriesId":["Arctic Ocean",null],"interval":"PT1M", "inlineVariables":{"EventCount":{"kind":"aggregate","aggregation":{"tsx":"count()"}}},"projectedVariables":["EventCount"]}}, {"aggregateSeries":{"searchSpan":{"from":"2019-10-31T23:59:39.590Z","to":"2019-11-01T05:22:18.926Z"},"timeSeriesId":["Arctic Ocean",null],"interval":"PT1M", "inlineVariables":{"Magnitude":{"kind":"numeric","value":{"tsx":"$event['mag'].Double"},"aggregation":{"tsx":"max($value)"}}},"projectedVariables":["Magnitude"]}}]}
{
"aggregateSeries": {
"timeSeriesId": [
"Arctic Ocean",
"null"
],
"searchSpan": {
"from": "2019-10-31T23:59:39.590Z",
"to": "2019-11-01T05:22:18.926Z"
},
"interval": "PT1M",
"inlineVariables": {
"EventCount": {
"kind": "aggregate",
"aggregation": {
"tsx": "count()"
}
},
"Magnitude": {
"kind": "numeric",
"value": {
"tsx": "$event['mag'].Double"
},
"aggregation": {
"tsx": "max($value)"
}
}
},
"projectedVariables": [
"EventCount",
"Magnitude",
]
}
}
- Wenn Sie die neuesten Daten abfragen möchten („isSearchSpanRelative“: true), berechnen Sie „searchSpan“ manuell, wie unten erwähnt.
- Ermitteln Sie den Unterschied zwischen „from“ (von) und „to“ (bis) von den Power BI-Nutzdaten. Wir nennen diesen Unterschied „D“, wobei „D“ = „from“ - „to“.
- Nehmen Sie den aktuellen Zeitstempel („T“), und subtrahieren Sie den Unterschied, der im ersten Schritt ermittelt wurde. Es wird ein neues „from“ (F) von „searchSpan“ sein, wobei „F“ = „T“ - „D“.
- Jetzt ist das neue „from“ das in Schritt 2 erhaltene „F“ und das neue „to“ das „T“ (aktueller Zeitstempel).