Share via


Migrando o Time Series Insights (TSI) Gen2 para o Azure Data Explorer

Nota

O serviço Time Series Insights (TSI) deixará de ser suportado após março de 2025. Ponderar, o mais rapidamente possível, a migração dos ambientes ETI existentes para soluções alternativas. Para obter mais informações sobre a substituição e migração, visite nossa documentação.

Descrição geral

Recomendações de migração de alto nível.

Caraterística Estado Gen2 Migração recomendada
Ingerir JSON do Hub com achatamento e fuga Ingestão de ETI ADX - OneClick Ingest / Assistente
Abrir câmara frigorífica Conta de armazenamento do cliente Exportação contínua de dados para a tabela externa especificada pelo cliente no ADLS.
Conector PBI Pré-visualização Privada Use o conector ADX PBI. Reescreva o TSQ no KQL manualmente.
Apache Spark Connector Pré-visualização Privada. Consultar dados de telemetria. Dados do modelo de consulta. Migre dados para o ADX. Use o conector ADX Spark para dados de telemetria + exporte o modelo para JSON e carregue no Spark. Reescreva consultas no KQL.
Carregamento em Massa Pré-visualização Privada Use ADX OneClick Ingest e LightIngest. Opcionalmente, configure o particionamento no ADX.
Modelo de Série de Tempo Pode ser exportado como arquivo JSON. Pode ser importado para o ADX para realizar junções no KQL.
Explorador da ETI Alternando quente e frio Painéis ADX
Linguagem da consulta Consultas de séries temporais (TSQ) Reescreva consultas no KQL. Use SDKs Kusto em vez de TSI.

Migrando telemetria

Use PT=Time a pasta na conta de armazenamento para recuperar a cópia de toda a telemetria no ambiente. Para obter mais informações, consulte Armazenamento de dados.

Etapa de migração 1 – Obter estatísticas sobre dados de telemetria

Dados

  1. Visão geral do Env
    • ID do ambiente de registro da primeira parte do FQDN de acesso a dados (por exemplo, d390b0b0-1445-4c0c-8365-68d6382c1c2a de .env.crystal-dev.windows-int.net)
  2. Visão geral do Env -> Configuração de armazenamento -> Conta de armazenamento
  3. Use o Gerenciador de Armazenamento para obter estatísticas de pastas
    • Tamanho do registro e o número de blobs da PT=Time pasta. Para clientes em visualização privada da Importação em Massa, registre também PT=Import o tamanho e o número de blobs.

Etapa de migração 2 – Migrar telemetria para ADX

Criar cluster ADX

  1. Defina o tamanho do cluster com base no tamanho dos dados usando o ADX Cost Estimator.

    1. A partir das métricas dos Hubs de Eventos (ou Hub IoT), recupere a taxa de quantidade de dados ingeridos por dia. A partir da Conta de armazenamento conectada ao ambiente da ETI, recupere a quantidade de dados existente no contêiner de blob usado pela ETI. Essas informações serão usadas para calcular o tamanho ideal de um cluster ADX para seu ambiente.
    2. Abra o Estimador de Custos do Azure Data Explorer e preencha os campos existentes com as informações encontradas. Defina "Tipo de carga de trabalho" como "Armazenamento otimizado" e "Hot Data" com a quantidade total de dados consultados ativamente.
    3. Depois de fornecer todas as informações, o Estimador de Custos do Azure Data Explorer sugerirá um tamanho de VM e o número de instâncias para seu cluster. Analise se o tamanho dos dados consultados ativamente caberá no Hot Cache. Multiplique o número de instâncias sugerido pelo tamanho do cache do tamanho da VM, por exemplo:
      • Sugestão do estimador de custos: 9x DS14 + 4 TB (cache)
      • Total de Hot Cache sugerido: 36 TB = [9x (instâncias) x 4 TB (de Hot Cache por nó)]
    4. Mais fatores a considerar:
      • Crescimento do ambiente: ao planejar o tamanho do cluster ADX, considere o crescimento dos dados ao longo do tempo.
      • Hidratação e particionamento: ao definir o número de instâncias no ADX Cluster, considere nós extras (de 2 a 3x) para acelerar a hidratação e o particionamento.
      • Para obter mais informações sobre seleção de computação, consulte Selecionar a SKU de computação correta para seu cluster do Azure Data Explorer.
  2. Para monitorar melhor o cluster e a ingestão de dados, habilite as Configurações de diagnóstico e envie os dados para um espaço de trabalho do Log Analytics.

    1. Na folha Azure Data Explorer, vá para "Monitoramento | Configurações de diagnóstico" e clique em "Adicionar configuração de diagnóstico"

      Captura de ecrã da folha Monitorização da folha do Azure Data Explorer | Configurações de diagnóstico

    2. Preencha o seguinte

      1. Nome da configuração de diagnóstico: Nome de exibição para esta configuração
      2. Logs: No mínimo, selecione SucceededIngestion, FailedIngestion, IngestionBatching
      3. Selecione o espaço de trabalho do Log Analytics para o qual enviar os dados (se você não tiver um, precisará provisionar um antes desta etapa)

      Captura de ecrã da área de trabalho do Azure Data Explorer Log Analytics

  3. Particionamento de dados.

    1. Para a maioria dos conjuntos de dados, o particionamento ADX padrão é suficiente.
    2. O particionamento de dados é benéfico em um conjunto muito específico de cenários e não deve ser aplicado de outra forma:
      1. Melhorar a latência da consulta em conjuntos de big data em que a maioria das consultas filtra em uma coluna de cadeia de caracteres de cardinalidade alta, por exemplo, um ID de série temporal.
      2. Ao ingerir dados fora de ordem, por exemplo, quando eventos do passado podem ser ingeridos dias ou semanas após a sua geração na origem.
    3. Para obter mais informações, consulte Política de particionamento de dados ADX.

Prepare-se para a ingestão de dados

  1. Aceder a https://dataexplorer.azure.com.

    Captura de ecrã da página de destino do Azure Data Explorer

  2. Vá para a guia Dados e selecione 'Ingerir do contêiner de blob'

    Captura de tela da ingestão do Azure Data Explorer do contêiner de blob

  3. Selecione Cluster, Database e crie uma nova tabela com o nome escolhido para os dados da ETI

    Captura de ecrã da seleção de ingestão do Azure Data Explorer de cluster, base de dados e tabela

  4. Selecione Seguinte: Origem

  5. Na guia Origem, selecione:

    1. Dados históricos
    2. "Selecionar recipiente"
    3. Escolha a conta de Subscrição e Armazenamento para os seus dados da ETI
    4. Escolha o contêiner correlacionado ao seu ambiente de ETI

    Captura de tela da seleção de ingestão do contêiner do Azure Data Explorer

  6. Selecione em Configurações avançadas

    1. Padrão de tempo de criação: '/'yyyyMMddHHmmssfff'_'
    2. Padrão do nome do blob: *.parquet
    3. Selecione "Não espere a ingestão terminar"

    Captura de ecrã da seleção de ingestão do Azure Data Explorer de definições avançadas

  7. Em Filtros de Ficheiros, adicione o caminho da pasta V=1/PT=Time

    Captura de ecrã da seleção de ingestão do Azure Data Explorer do caminho da pasta

  8. Selecione Próximo: Esquema

    Nota

    A ETI aplica algum nivelamento e fuga ao persistir colunas em arquivos Parquet. Veja estes links para obter mais detalhes: regras de achatamento e fuga, atualizações de regras de ingestão.

  • Se o esquema for desconhecido ou estiver variando

    1. Remova todas as colunas que são consultadas com pouca frequência, deixando pelo menos o carimbo de data/hora e a(s) coluna(s) TSID.

      Captura de tela da seleção de esquema de ingestão do Azure Data Explorer

    2. Adicione uma nova coluna de tipo dinâmico e mapeie-a para todo o registro usando o caminho $.

      Captura de ecrã da ingestão do Azure Data Explorer para o tipo dinâmico

      Exemplo:

      Captura de ecrã da ingestão do Azure Data Explorer para exemplo de tipo dinâmico

  • Se o esquema for conhecido ou corrigido

    1. Confirme se os dados estão corretos. Corrija quaisquer tipos, se necessário.
    2. Selecione Próximo: Resumo

Copie o comando LightIngest e armazene-o em algum lugar para que você possa usá-lo na próxima etapa.

Captura de ecrã da ingestão do Azure Data Explorer para o comando Lightingest

Ingestion de Dados

Antes de ingerir dados, você precisa instalar a ferramenta LightIngest. O comando gerado a partir da ferramenta One-Click inclui um token SAS. É melhor gerar um novo para que você tenha controle sobre o tempo de expiração. No portal, navegue até o contêiner de Blob para o ambiente TSI e selecione 'Token de acesso compartilhado'

Captura de ecrã da ingestão do Azure Data Explorer para token SAS

Nota

Também é recomendado aumentar a escala do cluster antes de iniciar uma grande ingestão. Por exemplo, D14 ou D32 com 8+ instâncias.

  1. Defina o seguinte

    1. Permissões: Ler e Listar
    2. Prazo de validade: defina para um período em que você se sinta confortável que a migração de dados será concluída

    Captura de ecrã da ingestão do Azure Data Explorer para expiração de permissões

  2. Selecione em 'Gerar token e URL SAS' e copie o 'URL SAS de Blob'

    Captura de ecrã da ingestão do Azure Data Explorer para URL de Blob SAS

  3. Vá para o comando LightIngest que você copiou anteriormente. Substitua o parâmetro -source no comando por este 'URL de Blob SAS'

  4. Opção 1: Ingerir todos os dados. Para ambientes menores, você pode ingerir todos os dados com um único comando.

    1. Abra um prompt de comando e mude para o diretório para o qual a ferramenta LightIngest foi extraída. Uma vez lá, cole o comando LightIngest e execute-o.

    Captura de ecrã da ingestão do Azure Data Explorer para a linha de comandos

  5. Opção 2: Ingerir dados por ano ou mês. Para ambientes maiores ou para testar em um conjunto de dados menor, você pode filtrar ainda mais o comando Lightingest.

    1. Por ano: altere o parâmetro -prefix

      • Antes: -prefix:"V=1/PT=Time"
      • Depois: -prefix:"V=1/PT=Time/Y=<Year>"
      • Exemplo: -prefix:"V=1/PT=Time/Y=2021"
    2. Por mês: altere o parâmetro -prefix

      • Antes: -prefix:"V=1/PT=Time"
      • Depois: -prefix:"V=1/PT=Time/Y=<Year>/M=<month #>"
      • Exemplo: -prefix:"V=1/PT=Time/Y=2021/M=03"

Depois de modificar o comando, execute-o como acima. Uma vez que a ingestão está completa (usando a opção de monitoramento abaixo) modifique o comando para o próximo ano e mês que você deseja ingerir.

Monitorização da ingestão

O comando LightIngest incluiu o sinalizador -dontWait para que o comando em si não espere a ingestão ser concluída. A melhor maneira de monitorar o progresso enquanto ele está acontecendo é utilizar a guia "Insights" dentro do portal. Abra a seção do cluster do Azure Data Explorer no portal e vá para 'Monitoramento | Perceções»

Captura de ecrã da ingestão do Azure Data Explorer para o Monitoring Insights

Você pode usar a seção 'Ingestão (visualização)' com as configurações abaixo para monitorar a ingestão enquanto ela está acontecendo

  • Intervalo de tempo: Últimos 30 minutos
  • Olhe para Bem Sucedido e por Tabela
  • Se você tiver alguma falha, olhe para Falha e por Tabela

Captura de ecrã da ingestão do Azure Data Explorer para resultados de Monitorização

Você saberá que a ingestão está completa quando ver as métricas irem para 0 para sua tabela. Se quiser ver mais detalhes, você pode usar o Log Analytics. Na seção cluster do Azure Data Explorer, selecione na guia 'Log':

Captura de tela da ingestão do Azure Data Explorer para logs de monitoramento

Consultas Úteis

Compreender o esquema se o esquema dinâmico for usado

| project p=treepath(fullrecord)
| mv-expand p 
| summarize by tostring(p)

Acessando valores na matriz

| where id_string == "a"
| summarize avg(todouble(fullrecord.['nestedArray_v_double'])) by bin(timestamp, 1s)  
| render timechart 

Migrando o Modelo de Série Temporal (TSM) para o Azure Data Explorer

O modelo pode ser baixado em formato JSON do Ambiente TSI usando o TSI Explorer UX ou TSM Batch API. Em seguida, o modelo pode ser importado para outro sistema, como o Azure Data Explorer.

  1. Faça o download do TSM da TSI UX.

  2. Exclua as três primeiras linhas usando o VSCode ou outro editor.

    Captura de ecrã da migração do TSM para o Azure Data Explorer - Eliminar as 3 primeiras linhas

  3. Usando o VSCode ou outro editor, pesquise e substitua como regex \},\n \{ por }{

    Captura de ecrã da migração do TSM para o Azure Data Explorer - procurar e substituir

  4. Ingerir como JSON no ADX como uma tabela separada usando a funcionalidade Upload from file.

    Captura de ecrã da migração do TSM para o Azure Data Explorer - Ingest as JSON

Traduzir Consultas de Série Temporal (TSQ) para 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 com filtro

{
  "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 com variável projetada

{
  "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']

Série Agregada

{
  "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 com filtro

{
  "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

Migração do TSI Power BI Connector para o ADX Power BI Connector

As etapas manuais envolvidas nessa migração são:

  1. Converter consulta do Power BI em TSQ
  2. Converter TSQ para KQL Consulta do Power BI para TSQ: A consulta do Power BI copiada do TSI UX Explorer tem a aparência mostrada abaixo

Para dados brutos (API GetEvents)

{"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}}]}
  • Para convertê-lo em TSQ, crie um JSON a partir da carga útil acima. A documentação da API GetEvents também tem exemplos para entendê-la melhor. Consulta - Executar - API REST (Azure Time Series Insights) | Documentos Microsoft
  • O TSQ convertido parece como mostrado abaixo. É a carga JSON dentro de "consultas"
{
  "getEvents": {
    "timeSeriesId": [
      "Arctic Ocean",
      "null"
    ],
    "searchSpan": {
      "from": "2019-10-31T23:59:39.590Z",
      "to": "2019-11-01T05:22:18.926Z"
    },
    "take": 250000
  }
}

Para dados Aggradate (API da série agregada)

  • Para uma única variável embutida, a consulta do PowerBI do TSI UX Explorer tem a aparência mostrada abaixo:
{"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": {
    "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",
    ]
  }
}
  • Para mais de uma variável embutida, acrescente o json em "inlineVariables", conforme mostrado no exemplo abaixo. A consulta do Power BI para mais de uma variável embutida tem a seguinte aparência:
{"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",
    ]
  }
}
  • Se você quiser consultar os dados mais recentes("isSearchSpanRelative": true), calcule manualmente o searchSpan como mencionado abaixo
    • Encontre a diferença entre "de" e "para" da carga útil do Power BI. Vamos chamar essa diferença de "D", onde "D" = "de" - "para"
    • Pegue o carimbo de data/hora atual ("T") e subtraia a diferença obtida na primeira etapa. Será novo "from"(F) de searchSpan onde "F" = "T" - "D"
    • Agora, o novo "de" é "F" obtido na etapa 2 e o novo "para" é "T" (carimbo de data/hora atual)