Lançamento do eKuiper 1.10.0: regras de temporização e adaptação do EdgeX v3

Após dois meses de desenvolvimento, temos o prazer de anunciar que o eKuiper 1.10.0 foi lançado oficialmente!

Como uma versão de marco, o eKuiper 1.10.0 atualizou a versão das dependências básicas, como a versão da linguagem Go foi atualizada para 1.20, o EdgeX suporta a última versão principal Minnesota (v3), etc. Também continuamos a melhorar a expressividade, conectividade e facilidade de uso do produto, mantendo-o leve e compacto para implantação de ponta.

As novidades e melhorias da versão mais recente incluem principalmente os seguintes aspectos:

  • Gerenciamento de regras: o tempo de execução das regras pode ser planejado, o que permite uma certa autonomia das regras.
  • Ecologia de conexão: Adicionado/melhorado mais fontes e destinos de dados, incluindo EdgeX v3, Kafka Sink, file Sink, etc. Sink/Source suporta transformação de dados mais eficiente, como extração de dados, lotes e compactação. Para ajudar os usuários a conectar melhor várias fontes e destinos de dados e se adaptar a estruturas de dados mais complexas.
  • Expressividade: Adicionadas mais funções e sintaxe, como processamento de matriz e objeto, suporte a estado externo, sintaxe de subscrito dinâmico de matriz, etc., para ajudar os usuários a obter processamento de dados mais complexo.

Verifique o log de atualização para obter o conteúdo detalhado da atualização .

Execução regular de regras

Em alguns cenários, os dados do usuário podem ser periódicos. Para economizar recursos em execução, o usuário deseja interromper a regra quando não houver dados e habilitar a regra apenas durante o período de tempo especificado. Os usuários precisam que as regras sejam executadas automaticamente e periodicamente, como uma vez todas as manhãs, uma vez por semana e assim por diante. Os usuários podem usar a API do eKuiper para iniciar e parar regras manualmente, mas no caso de implantação em larga escala na borda, iniciar e parar manualmente não é viável e a autonomia da regra de borda é iminente. Portanto, adicionamos a função de execução agendada à nova versão das regras. Os usuários podem especificar o tempo de execução agendado das regras, e as regras iniciarão e pararão automaticamente dentro do período de tempo especificado sem intervenção manual.

A opção da regra adiciona dois parâmetros, ou seja, crone duration.

  • cronO parâmetro especifica o horário de execução agendado da regra e o formato segue o formato da expressão cron, como 0 0 0 * * *significa executar uma vez todos os dias às 0h00.
  • durationO parâmetro especifica o tempo de execução da regra, no formato string de duração, incluindo números e unidades de tempo, como 1mmeios para executar por 1 minuto.

Por exemplo, a seguinte regra é definida para ser executada a cada dois minutos através dos parâmetros nas opções, e cada execução é de 1 minuto.

{
  "id": "ruleSchedule",
  "sql": "SELECT * FROM demo;",
  "options": {
    "cron": "*/2 * * * *",
    "duration": "1m"
  },
  "actions": [{
    "mqtt":  {
      "server": "tcp://broker.emqx.io:1883",
      "topic": "result/rule"
    }
  }]
}

Observe que a duração não deve exceder o intervalo de tempo entre dois ciclos do cron, caso contrário, ocorrerá um comportamento inesperado.

A adição, exclusão, modificação e consulta de status de regras de tarefas agendadas são consistentes com regras comuns e podem ser operadas por meio de API ou CLI. Quando a tarefa agendada é executada, a regra está no Runningestado. Se o tempo de execução da tarefa agendada expirar, a regra deixará automaticamente de aguardar o próximo agendamento e o status mudará para Stopped: waiting for next schedule.. Parar uma tarefa agendada com o comando Parar interromperá imediatamente a regra e a removerá do agendador.

Adaptação flexível de fontes e destinos de dados

eKuiper é a implementação padrão do mecanismo de regras do EdgeX Foundry. O próximo EdgeX Minnesota (v3) é uma versão importante, e o eKuiper também é suportado e atualizado simultaneamente. Ao mesmo tempo, também adicionamos mais fontes e destinos de dados, como Kafka Sink, arquivo Sink, etc. O suporte dessas fontes e destinos de dados permite que o eKuiper conecte melhor várias fontes e destinos de dados e acesse várias infraestruturas de dados de maneira mais conveniente.

Suporte para EdgeX v3

EdgeX v3 é a próxima versão importante do EdgeX Foundry, a versão eKuiper 1.10.0 já suporta EdgeX v3. O EdgeX Source e Sink do eKuiper foram atualizados e adaptados, e as regras existentes dos usuários podem ser migradas perfeitamente para o EdgeX v3.

Ao mesmo tempo, em nosso teste, o eKuiper versão 1.10 ainda é compatível com o EdgeX v2, e os usuários podem escolher o EdgeX v2 ou o EdgeX v3 de acordo com suas necessidades.

Deve-se observar que, como o suporte ao barramento ZeroMQ foi removido no EdgeX, também removemos o suporte ao protocolo zmq do EdgeX Source/Sink no eKuiper. Os usuários que usam o barramento Redis padrão ou o barramento MQTT não são afetados.

Coletor de arquivos mais poderoso

O sistema de arquivos pertence ao kernel do sistema operacional e não requer nenhuma dependência de sistema externo, por isso tem alta aplicabilidade e pode ser aplicado em praticamente qualquer ambiente de implantação, principalmente em sistemas com recursos limitados. Usando o coletor de arquivos, podemos usá-lo como uma forma de persistir dados em lotes em um ambiente com altos requisitos de segurança ou sem rede e, em seguida, transferir os dados para outros sistemas por outros meios para obter a penetração do gateway de rede. Além disso, em um ambiente com baixa largura de banda, podemos gravar dados em arquivos em lotes antes de compactar e transmitir, para obter maior taxa de compactação e reduzir o consumo de largura de banda.

Continuando a otimização do conector de arquivo na versão anterior, na nova versão, o coletor de arquivo suporta mais tipos de arquivo, como csv, json e linhas. Ao mesmo tempo, o coletor de arquivos suporta mais transformações de dados, como extração de dados, agrupamento e compactação, o que é propício para a adaptação de mais aplicativos. Além disso, a gravação de arquivos oferece suporte a estratégias de segmentação personalizadas, suportando volumes de dados maiores e gerenciamento mais conveniente.

Os principais destaques da nova versão do File Sink são:

  • Vários formatos de arquivo são suportados e os arquivos gravados podem ser lidos pela fonte de arquivo para realizar a transmissão cíclica de dados.
  • Múltiplas estratégias de segmentação são suportadas:
    • Divida por tempo, suporte para definir o tempo de intervalo da divisão de arquivos
    • Divida pelo número de mensagens
    • Segmente o nome do arquivo para adicionar automaticamente um carimbo de data/hora para evitar a duplicação do nome do arquivo e defina o local onde o carimbo de data/hora é adicionado
  • Suporta a gravação de vários arquivos, ou seja, nomes de arquivos dinâmicos. De acordo com o conteúdo da mensagem, a mensagem pode ser gravada em diferentes arquivos para realizar o desvio de dados.
  • Otimização de desempenho de gravação, suporte a gravação em lote, melhore a eficiência de gravação. Quando vários arquivos são gravados, a gravação simultânea é suportada e os temporizadores são compartilhados para melhorar a eficiência da gravação.
  • Compressão de suporte, suporte gzip e ztsd dois métodos de compactação.

Todos esses recursos são configuráveis ​​por meio de propriedades. Abaixo está um exemplo de uma regra usando um coletor de arquivo. Dentre eles, o caminho adota um nome de arquivo dinâmico, ou seja, a mensagem é escrita em diferentes arquivos de acordo com o conteúdo da mensagem. No exemplo a seguir, o tipo de arquivo é definido como csv, e rollingo atributo no início configura a estratégia de divisão do arquivo. compressão configura o método de compressão, usando compressão gzip. Para obter instruções de configuração detalhadas, consulte a documentação do produto.

{
  "id": "fileSinkRule",
  "sql": "SELECT * from demo ",
  "actions": [
     {
      "file": {
        "path": "{
   
   {.device}}_{
   
   {.ts}}.csv.gzip",
        "format": "delimited",
        "delimiter": ",",
        "hasHeader": true,
        "fileType": "csv",
        "rollingCount": 10,
        "rollingInterval": 0,
        "rollingNamePattern": "none",
        "compression":"gzip"
      }
    }
  ]
}

Pia Kafka

Kafka é um sistema de mensagens distribuídas com alto rendimento, alta disponibilidade, escalabilidade e durabilidade. A nova versão adiciona o Kafka Sink, que pode gravar dados do eKuiper no Kafka, realizando a conexão perfeita entre o eKuiper e o Kafka. Um exemplo de uso é o seguinte:

{
  "id": "kafka",
  "sql": "SELECT * from demo",
  "actions": [
    {
      "kafka":{
        "brokers": "127.0.0.1:9091",
        "topic": "sample_topic",
        "saslAuthType": "none"
      }
    }
  ]
}

Otimização de suporte de banco de dados

Algumas otimizações foram feitas no plug-in SQL source/sink na nova versão. incluem principalmente:

  1. Atualize o driver ClickHouse e teste o suporte do ClickHouse.
  2. Suporte ao banco de dados Dameng.
  3. Oferece suporte à configuração do pool de conexões para melhorar a eficiência das conexões do banco de dados.

Os usuários podem configurar a propriedade sql/maxConnections no arquivo de configuração etc/kuiper.yaml ou por meio de variáveis ​​de ambiente para especificar o número máximo de conexões no pool de conexões do banco de dados para evitar problemas de desempenho causados ​​por muitas conexões. Um exemplo se parece com isso:

  sql:
    # maxConnections indicates the max connections for the certain database instance group by driver and dsn sharing between the sources/sinks
    # 0 indicates unlimited
    maxConnections: 0

Transformação de dados do coletor

Os dados do usuário podem ter uma estrutura aninhada, por exemplo, os dados acessados ​​pelo Neuron geralmente contém alguns metadados, e o campo valores no payload são os dados que o usuário precisa. Além disso, quando instruções SQL complexas são usadas para processamento de dados, alguns resultados intermediários de cálculo podem ser definidos na cláusula SELECT e todos eles não precisam ser enviados para o Sink. Nesse caso, o lado Sink precisa transformar ou formatar os dados novamente. O modelo de dados é um método comumente usado, que é poderoso e oferece suporte a vários formatos. No entanto, requer que os usuários tenham uma certa capacidade de escrever modelos e, ao mesmo tempo, o desempenho de execução é ruim.

Na nova versão, o lado Sink suporta transformações de dados mais comumente usadas, incluindo extração de dados, atributos relacionados para envio em lote e estendido para a maioria dos tipos de Sink. Em algumas transformações de dados simples comumente usadas, os usuários podem configurar parâmetros, o que reduz a carga de trabalho dos usuários ao escrever modelos e melhora a eficiência operacional.

envio em lote

Por padrão, Sink produz um dado para cada evento. No entanto, se a taxa de transferência de dados for grande, haverá alguns problemas, como alta sobrecarga de IO; se compactado, a taxa de compactação é baixa; sobrecarga de rede para enviar para a nuvem é grande etc. Ao mesmo tempo, a taxa de envio rápida pode aumentar a pressão de processamento na nuvem. Para resolver esses problemas, a nova versão suporta a função de envio em lote no MQTT Sink.

O princípio do envio em lote é que o Sink adotará uma determinada estratégia para armazenar os dados em cache e, em seguida, enviá-los para a nuvem de uma só vez. Os usuários podem controlar a quantidade de dados enviados em lotes e o intervalo de tempo configurando parâmetros batchSizee . lingerIntervalUm exemplo se parece com isso:

{
    "id": "batch",
    "sql": "select a,b from demo",
    "actions": [
       {
        "log": {
        },
        "mqtt": {
          "server": "tcp://broker.emqx.io:1883",
          "topic": "devices/messages",
          "lingerInterval": 10000,
          "batchSize": 3
        }
      }
    ]
}

Neste exemplo, quando a quantidade de dados atingir 3 ou acumular por 10 segundos, o Sink enviará os dados uma vez. Os usuários podem ajustar esses dois parâmetros de acordo com suas necessidades.

extração de dados

Ao usar dados intermediários ou o formato dos dados calculados for inconsistente com o formato dos dados gravados, precisamos extrair os dados necessários no lado do Sink. fieldsNa nova versão, dois parâmetros comuns e são adicionados a todos os Sinks dataField. Esses dois parâmetros foram suportados em coletores relacionados ao armazenamento de dados anteriores, incluindo SQL, Redis, InfluxDB, etc. Porque na gravação de dados, o banco de dados de destino geralmente possui definições de coluna rígidas, e a instrução SQL SELECT pode não corresponder necessariamente às colunas e geralmente possui campos selecionados redundantes. Em outros coletores, também haverá esses requisitos de extração de dados. Na nova versão, esses dois atributos são estendidos para coletores como MQTT, Kafka e File. Entre eles, dataFieldos parâmetros são usados ​​para especificar campos que representam dados para distingui-los de campos que representam outros dados, como metadados, por exemplo dataField: values, . fieldsOs parâmetros são usados ​​para especificar os campos que precisam ser gerados, para que possam corresponder exatamente aos requisitos do sistema de destino, por exemplo, fields: ["a","b"].

Exemplo 1: Extraia a saída da seção de valores dos dados do Neuron. Extraia dados aninhados configurando o atributo dataField da seguinte maneira:

{
  "id": "extract",
  "sql": "SELECT * FROM neuronStream",
  "actions": [
    {
      "mqtt": {
        "server": "tcp://broker.emqx.io:1883",
        "topic": "devices/messages",
        "dataField": "values"
      }
    }
  ]
}

Exemplo 2: Extraia os campos obrigatórios, ignorando a saída de alguns campos dos resultados do cálculo intermediário. Conforme mostrado abaixo, os campos especificados são extraídos configurando a propriedade fields:

{
  "id": "extract",
  "sql": "SELECT temperature, lag(temperature) as lt, humidity FROM demo WHERE lt > 10",
  "actions": [
    {
      "mqtt": {
        "server": "tcp://broker.emqx.io:1883",
        "topic": "devices/messages",
        "fields": ["temperature","humidity"]
      }
    }
  ]
}

Neste exemplo, a instrução SQL lag(temperature) as ltgerará um resultado de cálculo intermediário, o que é conveniente para filtrar no campo WHERE e simplifica a escrita SQL. Mas no lado Sink, precisamos apenas temperaturede humiditydois campos, portanto, fieldsespecifique os campos que precisam ser exibidos configurando a propriedade.

Esses dois atributos podem ser usados ​​ao mesmo tempo ou em conjunto com DataTemplate para concluir transformações de dados mais complexas. Após todas as três propriedades serem configuradas, o DataTemplate será executado primeiro, depois o dataField será executado e, finalmente, a extração de dados do dataField será executada.

Manipulação de arrays e objetos

A sintaxe SQL foi originalmente projetada para bancos de dados relacionais e há menos tipos de dados compostos no banco de dados, portanto, tem recursos de processamento limitados para arrays e objetos. Em cenários de IoT, o formato de dados acessado é principalmente JSON e os tipos de dados compostos aninhados são cidadãos de primeira classe. O eKuiper SQL incorporou a capacidade de acessar dados aninhados desde o início. No entanto, ainda há muitas necessidades não atendidas para transformações de dados mais profundas. Na nova versão, aprimoramos os recursos de processamento de arrays e objetos, incluindo a conversão de dados de array em várias linhas, funções de processamento de array e objeto, etc.

Carga útil de matriz compatível com fontes de dados

Quando a fonte de dados usa o formato JSON, a versão anterior suportava apenas a carga do objeto JSON, mas a nova versão suporta a carga da matriz JSON. Além disso, o usuário não precisa configurar e o sistema identificará automaticamente o tipo de carga útil.

Por exemplo, os dados do tipo array podem ser acessados ​​na nova versão do MQTT Source:

[
    {"temperature":23},
    {"temperature":24},
    {"temperature":25}
]

Quando os dados da matriz são recebidos, os dados serão divididos em várias partes de dados para processamento e cada parte dos dados contém um elemento de matriz. Por exemplo, os dados acima serão divididos em três partes de dados. A partir daí, o processamento é igual ao dos dados normais do objeto JSON.

Array dados em várias linhas

Algumas fontes de dados passam em lotes de dados, mas existem alguns metadados comuns, portanto, o formato geral ainda é um objeto JSON, como os dados a seguir. Esse formato de dados é especialmente comum nos valores de retorno dos serviços HTTP.

{
    "device_id": "device1",
    "data": [
        {"temperature":23},
        {"temperature":24},
        {"temperature":25}
    ]
}

Esses dados são processados ​​como uma única linha de dados no eKuiper . Logicamente, o que o usuário precisa é de várias linhas de dados. Na nova versão, adicionamos um novo tipo de função: função de várias linhas, que é usada para converter dados de uma única linha em processamento de várias linhas. Além disso, adicionamos a única função multilinha: unnest. Usado para expandir as colunas da matriz em várias linhas.

unnest | unnest(array) | A coluna do parâmetro deve ser um objeto array. Essa função expande a matriz de parâmetros em várias linhas e retorna o resultado. Se cada subitem no objeto de matriz for um objeto map[string]interface{}, o subitem será listado como uma coluna na linha retornada.

Os dados aninhados podem ser processados ​​como várias linhas, resultando em vários resultados de saída. Por exemplo, os dados acima podem obter três resultados de saída.

exemplo de uso

Crie uma demonstração de fluxo e forneça a seguinte entrada.

{"a": [1,2], "b": 3} 

Regras para obter resultados de desaninhamento:

SQL: SELECT unnest(a) FROM demo
___________________________________________________
{"unnest":1}
{"unnest":2}

Regras para obter resultados de desaninhamento com outras colunas:

SQL: SELECT unnest(a), b FROM demo
___________________________________________________
{"unnest":1, "b":3}
{"unnest":2, "b":3}

Crie uma demonstração de fluxo e forneça a seguinte entrada.

{"x": [{"a": 1,"b": 2}, {"a": 3,"b": 4}], "c": 5} 

Regras para obter resultados de desaninhamento com outras colunas:

SQL: SELECT unnest(x), b FROM demo
___________________________________________________
{"a":1, "b":2, "c": 5}
{"a":3, "b":4, "c": 5}

Funções de manipulação de arrays e objetos

Na nova versão, melhoramos a capacidade de lidar com arrays e objetos na forma de funções. Por exemplo, uma função para obter o maior valor de uma lista array_max, uma função para obter o menor valor de uma lista array_min, uma função para obter o número de elementos de uma lista array_length, uma função para obter os elementos de uma lista array_element, uma função para obter os elementos em um objeto object_element. Para as funções suportadas atualmente, verifique a documentação da função .

Na próxima versão, continuaremos aprimorando a capacidade de lidar com arrays e objetos.

Açúcar sintático para acesso à estrutura aninhada

Provavelmente a pergunta mais comum feita por usuários novos no eKuiper é como acessar dados em estruturas aninhadas. Não existe tal sintaxe definida no SQL padrão. Em linguagens de programação, geralmente usamos ponto (.) para acessar dados aninhados. No entanto, no SQL, um ponto representa um nome de tabela. Portanto, estendemos a sintaxe SQL para usar a notação de seta (->) para acessar estruturas incorporadas. Mas essa sintaxe não é intuitiva e há um custo de aprendizado para iniciantes.

Na nova versão, adicionamos açúcar sintático de acesso à estrutura aninhada para simplificar o acesso a estruturas aninhadas. Onde não há ambiguidade, os usuários podem usar a notação de ponto para acessar estruturas aninhadas. Por exemplo, para os seguintes dados:

{
    "a": {
        "b": {
            "c": 1
        }
    }
}

Pode ser usado diretamente na instrução a.b.cpara acessar estruturas aninhadas. A notação de seta original também é suportada de forma compatível, por exemplo a->b->c, .

Suporte de estado externo

O eKuiper é um mecanismo de processamento de fluxo com estado. O estado é usado principalmente internamente, incluindo o estado da janela, o estado da função de análise, etc. Em versões anteriores, damos suporte ao acesso mais granular (baseado em linha) ao estado externo por meio de tabelas. Na nova versão, adicionamos recursos de acesso e armazenamento de estado externo baseado em chave (coluna). Por meio do acesso de estado externo, mais funções podem ser realizadas, como limite dinâmico e estado de comutação dinâmico. Os usuários podem facilmente compartilhar o status com aplicativos de terceiros para obter um trabalho colaborativo.

O armazenamento de estado externo pode coexistir com o armazenamento de estado interno do sistema ou pode ser usado independentemente. Armazenamentos de estado externos também oferecem suporte a SQLite ou Redis. O Redis baseado em KV é mais adequado para armazenar estados externos. No arquivo de configuração etc/kuiper.yaml, podemos configurar o tipo de armazenamento de estado externo.

store:
  #Type of store that will be used for keeping state of the application
  extStateType: redis
  • Acesso de estado: suponha que um aplicativo de terceiros tenha gravado dados em cache $device1$temperatureL: "20". No SQL, podemos get_keyed_stateacessar o estado externo por meio de funções. Por exemplo, get_keyed_state(\"$device1$temperatureL\", \"bigint\", 0) as temperatureLpermitindo assim que o estado externo participe dos cálculos.
  • Escrita de estado: suponha que precisamos gravar o resultado do cálculo no estado externo do Redis, podemos usar o Redis Sink. Na nova versão, o Redis Sink oferece suporte à gravação de vários pares chave-valor por vez. No exemplo a seguir, configurando keyTypecomo multiple, podemos escrever vários pares chave-valor de uma só vez. fieldO nome do campo a ser escrito também pode ser especificado através do item de configuração.
{
  "id": "ruleUpdateState",
  "sql":"SELECT status as `$device1$status`,temperatureH as `$device1$temperatureH`,temperatureL as `$device1$temperatureL` FROM stateStream",
  "actions":[
    {
      "redis": {
        "addr": "{
   
   {localhost}}:6379",
        "dataType": "string",
        "keyType": "multiple",
        "sendSingle": true
      }
    }
  ]
}

atualizações de sintaxe SQL

Além de algumas atualizações de sintaxe SQL mencionadas anteriormente, a nova versão também inclui as seguintes atualizações de sintaxe SQL:

obter regras atuais

A função foi adicionada rule_id()para obter o ID da regra atual, o que é conveniente para os usuários rastrearem as regras geradas pelos dados.

Subscrito dinâmico de matriz

Na nova versão, as expressões podem ser usadas para subscritos de matriz para realizar a indexação dinâmica. Por exemplo, SELECT a[start] FROM stream, onde startpode ser um campo cujo valor é uma variável; o subscrito pode usar qualquer expressão.

A dinamização permite operações de array muito flexíveis que eram difíceis de alcançar nas versões anteriores. Por exemplo, há vários sensores no pipeline cujos dados são coletados como uma matriz. Depois que o objeto entra na linha de montagem, a posição do objeto na linha de montagem pode ser calculada de acordo com a linha de montagem e a velocidade, de modo a determinar os dados do sensor do objeto. Esse processo de cálculo pode ser realizado por meio do cálculo dinâmico de subscritos de matriz.

função de execução atrasada

Na nova versão, adicionamos uma função de execução atrasada. Quando essas funções são executadas, haverá um atraso por um período de tempo. Por exemplo, delayuma função retorna o valor de uma entrada após um atraso.

Se a finalidade dos dados tiver restrições de tráfego, use esta função para realizar o efeito de eliminação de pico e preenchimento de vale.

Aprimoramentos da Graph API

Na nova versão, adicionamos suporte para Graph API para acessar fluxos definidos e tabelas de consulta. Além disso, JoinOp oferece suporte a fluxos e tabelas de pesquisa. Também melhoramos as mensagens de validação da Graph API para facilitar a localização de erros pelos usuários. A Graph API e até mesmo o editor visual baseado nela podem realizar mais recursos de processamento de dados.

Os usuários precisam definir fluxos e tabelas de consulta por meio Create Streamde e . Create TableNas regras da Graph API, você pode sourceNameapontar para fluxos definidos e tabelas de pesquisa por meio da propriedade. Por exemplo, nas regras a seguir, demoe alertTableaponte para o fluxo definido e a tabela de consulta, respectivamente.

{
  "id": "ruleAlert",
  "graph": {
    "nodes": {
      "demo": {
        "type": "source",
        "nodeType": "mqtt",
        "props": {
          "sourceType": "stream",
          "sourceName": "demo"
        }
      },
      "alertTable": {
        "type": "source",
        "nodeType": "memory",
        "props": {
          "sourceType": "table",
          "sourceName": "alertTable"
        }
      },
      "joinop": {
        "type": "operator",
        "nodeType": "join",
        "props": {
          "from": "demo",
          "joins": [
            {
              "name": "alertTable",
              "type": "inner",
              "on": "demo.deviceKind = alertTable.id"
            }
          ]
        }
      },
      "log": {
        "type": "sink",
        "nodeType": "log",
        "props": {}
      }
    },
    "topo": {
      "sources": ["demo", "alertTable"],
      "edges": {
        "demo": ["joinop"],
        "alertTable": ["joinop"],
        "joinop": ["log"]
      }
    }
  }
}

atualização de dependência

Além das dependências relacionadas ao EdgeX, o eKuiper também atualizou as seguintes dependências:

  • Versão do idioma Go atualizada para 1.20
  • A dependência do SQLite mudou para a versão Go pura
  • Redis depende do GitHub - redis/go-redis: cliente Redis Go atualizado para v9
  • Remova a dependência zeroMQ padrão
  • Atualizar outras bibliotecas dependentes

Agradecimentos especiais

O desenvolvimento da versão 1.10 do eKuiper recebeu forte apoio da comunidade.

Agradecimentos especiais aos seguintes colaboradores:

  • @carlclone: ​​​​Contribuiu com a implementação do coletor Kafka e a implementação de vários algoritmos de compactação/descompactação.
  • @wangxye: Contribuiu com várias funções de array/objeto.

Obrigado à equipe de desenvolvimento e a todos os colaboradores por seu trabalho árduo e dedicação! Divirta-se com eKuiper!

Declaração de direitos autorais: Este artigo é original da EMQ, indique a fonte para reimpressão.
Link original: https://www.emqx.com/zh/blog/ekuiper-v-1-10-0-release-notes

Acho que você gosta

Origin blog.csdn.net/emqx_broker/article/details/131682436
Recomendado
Clasificación