Bancos de dados na plataforma IIoT: como o Mail.ru Cloud Solutions funciona com petabytes de dados de vários dispositivos


Olá, sou Andrey Sergeev, chefe do grupo de desenvolvimento de soluções de IoT do Mail.ru Cloud Solutions . Sabe-se que um banco de dados universal não existe. Especialmente quando você precisa criar uma plataforma de Internet das coisas capaz de processar milhões de eventos a partir de sensores por segundo no modo quase em tempo real.

Nosso produto Mail.ru IoT Platform começou com um protótipo baseado no Tarantool. Vou lhe dizer para onde foi, quais problemas encontramos e como resolvemos. E também mostra a arquitetura atual da plataforma moderna da Internet industrial das coisas. No artigo, falaremos:

  • sobre nossos requisitos de banco de dados, solução universal e teorema da CAP;
  • se o banco de dados + servidor de aplicativos em uma abordagem é uma bala de prata;
  • sobre a evolução da plataforma e os bancos de dados usados ​​nela;
  • , Tarantool’ .

, @Databases Meetup by Mail.ru Cloud Solutions. , :



Mail.ru IoT Platform


Nosso produto, Mail.ru IoT Platform, é uma plataforma escalável e independente de hardware para criar soluções para a Internet industrial das coisas. Ele permite que você colete dados de centenas de milhares de dispositivos simultaneamente e processe esse fluxo no modo quase em tempo real (ou seja, quase em tempo real), incluindo o uso de regras personalizadas - scripts em Python ou Lua.

A plataforma pode armazenar uma quantidade ilimitada de dados brutos das fontes, existe um conjunto de componentes prontos para visualização e análise de dados, ferramentas integradas para análise preditiva e criação de aplicativos com base na plataforma.


É a aparência do dispositivo Mail.ru IoT Platform.

No momento, a plataforma está disponível para instalação de acordo com o modelo local nas instalações do cliente; este ano, está planejado lançar a plataforma como um serviço na nuvem pública.

Protótipo do Tarantool: como tudo começou


Nossa plataforma começou como um projeto piloto - um protótipo com uma única instância Tarantool, cuja principal função era receber fluxo de dados de um servidor OPC, processar eventos recebidos usando scripts Lua em tempo real, monitorar indicadores-chave com base neles e gerar eventos e alertas em sistemas superiores.


Esquema do protótipo do Tarantool

Este protótipo até trabalhou em condições de combate por vários meses em um local de cluster, é uma plataforma para a produção de petróleo em alto mar, no Iraque, no Golfo Pérsico. Ele monitorou os principais indicadores e forneceu dados para o sistema de visualização e o log de eventos. O piloto foi reconhecido como bem-sucedido, mas como costuma ser o caso dos protótipos - ele não foi além do piloto e o protótipo ficou em espera por um longo tempo até cair em nossas mãos.

Nossos objetivos no desenvolvimento de uma plataforma IoT


Juntamente com o protótipo, recebemos a tarefa - criar uma plataforma IoT completa, escalável e tolerante a falhas, que mais tarde poderia ser lançada como um serviço em uma nuvem pública.

Precisávamos criar uma plataforma com o seguinte introdutório:

  1. Conecte centenas de milhares de dispositivos simultaneamente.
  2. Receba milhões de eventos por segundo.
  3. Processamento de fluxo no modo quase em tempo real.
  4. Armazenamento de dados brutos por vários anos.
  5. Ferramentas para análise de streaming e análise histórica.
  6. Suporte à implantação em vários datacenters para recuperação máxima de desastres.

Prós e contras do protótipo da plataforma


No momento do início do desenvolvimento ativo, o protótipo tinha a seguinte aparência:

  • Tarantool, usado como banco de dados + servidor de aplicativos (Application Server);
  • todos os dados são armazenados na memória do Tarantool;
  • um aplicativo em Lua no mesmo Tarantool, que executa as funções de recebimento de dados, processamento e chamada de scripts do usuário nos dados recebidos.

Essa abordagem para criar aplicativos tem suas vantagens :

  1. O código e os dados estão em um único local, o que permite operar os dados diretamente na memória do aplicativo e remove os custos indiretos das visitas à rede típicas dos aplicativos tradicionais.
  2. O Tarantool usa o JIT (Just in Time Compiler) para Lua, que em tempo de compilação compila o código Lua no código da máquina, o que permite que scripts simples da Lua sejam executados a uma velocidade comparável ao código C (40.000 RPS de um núcleo - e esse não é o limite !).
  3. O Tarantool é baseado em multitarefa cooperativa, ou seja, cada chamada para o procedimento armazenado é iniciada em sua própria fibra, um análogo da corotina, que proporciona um aumento ainda maior no desempenho em tarefas com operações de E / S, por exemplo, visitas à rede.
  4. Uso eficiente de recursos - poucas ferramentas podem lidar com 40.000 solicitações por segundo a partir de um único núcleo de CPU.

Mas há desvantagens significativas :

  1. Precisamos armazenar dados brutos dos dispositivos por vários anos, mas não temos centenas de petabytes de memória para o Tarantool.
  2. Uma consequência direta da primeira vantagem: todo o código da nossa plataforma é armazenado nos procedimentos no banco de dados, o que significa que qualquer atualização na base de código da plataforma é uma atualização do banco de dados, o que é muito doloroso.
  3. , . , Tarantool 24-32 (Tarantool ) . — Tarantool, .
  4. . - , Tarantool Lua , - , LuaJIT .

Conclusão: O Tarantool é uma boa opção para criar MVP, mas para uma plataforma IoT completa, escalável, facilmente suportada e tolerante a falhas que pode receber, processar e armazenar dados de centenas de milhares de dispositivos, não é adequado.

As principais dores do protótipo que queríamos nos livrar


Antes de tudo, queríamos curar duas dores do nosso protótipo:

  1. Afaste-se do conceito de banco de dados + serviço de aplicativo. Queríamos atualizar o código do aplicativo, independentemente do armazenamento de dados.
  2. Simplifique o dimensionamento dinâmico sob carga. Eu queria obter uma escala horizontal independente e fácil de tantas funções quanto possível.

Para resolver esses problemas, escolhemos uma abordagem inovadora e ainda não testada: arquitetura de microsserviços e separação de serviços no banco de dados Stateless - aplicativos e Stateful -.

Para facilitar ainda mais a operação e o dimensionamento horizontal dos serviços Stateless, nós os contêineres e adotamos o Kubernetes.


Descobrimos os serviços sem estado, resta decidir o que fazer com os dados.

Requisitos básicos de banco de dados para a plataforma IoT


Inicialmente, não queríamos cercar o jardim e queríamos armazenar todos os dados da plataforma em um banco de dados universal. Após analisar as metas, chegamos à seguinte lista de requisitos para um banco de dados universal:

  1. ACID- — , .
  2. — .
  3. — , near real-time.
  4. — - .
  5. — , .
  6. — ( !), .
  7. — , ( !).
  8. SQL — .

CAP-


Antes de começar a classificar todos os bancos de dados disponíveis no mercado para conformidade com nossos requisitos, decidimos validar nossos requisitos de sanidade usando uma ferramenta bastante conhecida - os teoremas da PAC.

O teorema do CAP diz que um sistema distribuído pode ter no máximo duas das três propriedades a seguir:

  1. Consistência (consistência dos dados) - em todos os nós de computação em um determinado momento, os dados não se contradizem.
  2. Disponibilidade - qualquer solicitação para um sistema distribuído termina com uma resposta correta, mas sem garantia de que as respostas de todos os nós no sistema correspondam.
  3. Tolerância de partição - mesmo se não houver conexão entre nós, eles continuam a funcionar independentemente um do outro.


Por exemplo, o sistema CA clássico é um cluster Master-Slave do PostgreSQL com replicação síncrona, e o sistema AP clássico é o Cassandra.

Vamos retornar aos nossos requisitos e classificá-los usando o teorema da CAP:

  1. As transações de ACID e consistência estrita (ou pelo menos não consistência eventual) são C.
  2. A escala horizontal para escrita e leitura, além de alta disponibilidade, é A (multimestre).
  3. A tolerância a falhas é P; quando um data center cai, a plataforma não deve morrer.


Conclusão : o banco de dados universal de que precisamos deve ter todas as três propriedades do teorema da CAP, o que significa que não há banco de dados universal para todos os nossos requisitos.

Escolhendo um banco de dados para os dados com os quais a plataforma IoT trabalha


Se você não pode escolher um banco de dados universal, decidimos selecionar os tipos de dados com os quais a plataforma trabalhará e selecionar um banco de dados para cada tipo.

Numa primeira aproximação, dividimos os dados em dois tipos:

  1. Meta - informação é um modelo do mundo, dispositivos, configurações, regras, quase todos os dados, exceto aqueles que transmitem dispositivos finais.
  2. Dados brutos dos dispositivos - leituras de sensores, telemetria e informações de serviço dos dispositivos. De fato, são séries temporais, em que cada mensagem individual contém um valor e um carimbo de data / hora.

Escolhendo um banco de dados para metadados


Requisitos de banco de dados para metadados . Os metadados são inerentemente relacionais. Eles são caracterizados por uma pequena quantidade, raramente são modificados, mas são dados importantes, não podem ser perdidos; portanto, a consistência é importante mesmo dentro da estrutura da replicação assíncrona, além de transações ACID e escala de leitura horizontal.

Há relativamente poucos dados e eles são alterados com pouca frequência; portanto, você pode sacrificar a escala horizontal para a gravação, bem como a possível inacessibilidade do banco de dados de gravação em caso de acidente. Ou seja, em termos do teorema da PAC, precisamos de um sistema de CA.

O que é adequado no caso usual . Com essa declaração do problema, qualquer banco de dados relacional clássico com suporte para clusters com replicação assíncrona como PostgreSQL ou MySQL seria bastante adequado para nós.

Recursos da nossa plataforma . Também precisávamos de suporte para árvores com requisitos específicos. Como parte do protótipo, havia um recurso dos sistemas da classe BDVV (bancos de dados em tempo real) - modelando o mundo usando uma árvore de tags. Eles permitem combinar todos os dispositivos clientes em uma estrutura em árvore, o que facilita o gerenciamento de um grande número de dispositivos e sua exibição.


É assim que é a exibição dos dispositivos na forma de uma estrutura em árvore.

Essa árvore permite vincular dispositivos finais ao ambiente, por exemplo, você pode colocar dispositivos localizados fisicamente em uma sala em uma subárvore, o que facilita muito o trabalho com eles no futuro. Essa é uma função conveniente, além disso, queríamos trabalhar ainda mais no nicho do sistema de detonador aéreo, e ali a presença de tal funcionalidade é realmente o padrão da indústria.

Para a implementação completa de árvores de tags, um banco de dados em potencial deve atender aos seguintes requisitos:

  1. Suporte para árvores com largura e profundidade arbitrárias.
  2. Modificação de elementos da árvore em transações ACID.
  3. Alto desempenho ao atravessar uma árvore.

Os bancos de dados relacionais clássicos podem lidar com árvores pequenas muito bem, mas não com árvores arbitrárias.

Solução possível. Use dois bancos de dados - um banco de dados gráfico para armazenar uma árvore e um banco de dados relacional para armazenar o restante das metainformações.

Essa abordagem tem várias grandes desvantagens ao mesmo tempo:

  1. Para garantir a consistência entre dois bancos de dados, você precisa adicionar um coordenador de transações externas.
  2. Esse design é difícil de manter e não é muito confiável.
  3. Na saída, temos dois bancos de dados em vez de um, enquanto o banco de dados gráfico é necessário apenas para suportar funcionalidades limitadas.


Uma solução possível, mas não muito boa, com dois bancos de dados


Nossa solução para armazenar metadados . Também pensamos e lembramos que, inicialmente, essa funcionalidade foi implementada em um protótipo baseado no Tarantool e resultou muito bem.

Antes de continuar, gostaria de fornecer uma definição não padrão de Tarantool: Tarantool não é um banco de dados, mas um conjunto de primitivas para criar um banco de dados para o seu caso específico.

Primitivas disponíveis prontas para uso:

  • Espaço - um análogo das tabelas no banco de dados para armazenar dados.
  • Transações ACID completas.
  • A replicação é assíncrona usando logs WAL.
  • Uma ferramenta de sharding que suporta compartilhamento automático de novo.
  • Superfast LuaJIT para procedimentos armazenados.
  • Grande biblioteca padrão.
  • Gerenciador de pacotes LuaRocks com ainda mais pacotes.

Nossa solução CA foi um banco de dados relacional + gráfico baseado no Tarantool. Reunimos o repositório de meta informações dos sonhos com base nas primitivas do Tarantool:

  • Espaço para armazenamento de dados.
  • Transações ACID - estavam disponíveis.
  • Replicação assíncrona - estava disponível.
  • Relações - feitas em procedimentos armazenados.
  • Árvores - também feitas em procedimentos armazenados.

A instalação do cluster que temos é clássica para esses sistemas - um Master para gravação e vários Slive com replicação assíncrona para dimensionamento para leitura.

O resultado: um híbrido rápido e escalável de um banco de dados relacional e gráfico. Uma única instância do Tarantool é capaz de lidar com milhares de solicitações de leitura, incluindo aquelas com passagem de árvore ativa.

Escolhendo um banco de dados para dados de dispositivos


Requisitos de banco de dados para dados de dispositivos . Esses dados são caracterizados por gravação frequente e uma grande quantidade de dados: milhões de dispositivos, vários anos de armazenamento, petabytes de informações de mensagens recebidas e dados armazenados. Sua alta disponibilidade é importante, pois são as leituras dos sensores que operam principalmente nas regras do usuário e em nossos serviços internos.

Para um banco de dados, o dimensionamento horizontal para leitura e gravação, disponibilidade e tolerância a falhas, bem como a disponibilidade de ferramentas analíticas prontas para trabalhar com esse conjunto de dados, de preferência com base em SQL, são importantes. Ao mesmo tempo, podemos sacrificar a consistência e as transações ACID.

Ou seja, no quadro do teorema da PAC, precisamos de um sistema AP.

Requisitos adicionais. Tínhamos alguns requisitos adicionais para decidir onde as quantidades gigantescas de dados seriam armazenadas:

  1. Séries temporais - os dados dos sensores são séries temporais, eu queria obter uma base especializada.
  2. Código aberto - as vantagens do código aberto não precisam de comentários.
  3. Um cluster livre é um flagelo comum entre bancos de dados novos.
  4. Boa compactação - dada a quantidade de dados e, em geral, sua uniformidade, eu queria compactar com eficiência os dados armazenados.
  5. Operação bem-sucedida - queríamos começar em um banco de dados que alguém já esteja explorando ativamente próximo de nossas cargas, a fim de minimizar os riscos.

Nossa decisão . O ClickHouse atendeu exclusivamente aos nossos requisitos - um banco de dados baseado em colunas de séries temporais com replicação, multimaster, sharding, suporte a SQL e um cluster gratuito. Além disso, o Mail.ru tem muitos anos de experiência bem-sucedida na operação de um dos maiores clusters ClickHouse em volume de armazenamento.

Mas não importa o quão bom o ClickHouse seja, e temos problemas com ele.

Problemas de banco de dados para esses dispositivos e suas soluções


O problema com o desempenho de gravação. Imediatamente houve um problema com o desempenho de gravação de um grande fluxo de dados. Eles precisam ser levados ao banco de dados analítico o mais rápido possível, para que as regras que analisam o fluxo de eventos em tempo real possam analisar o histórico de um dispositivo específico e decidir se devem ou não gerar um alerta.

Solução para o problema . O ClickHouse não tolera várias inserções únicas (inserções), mas funciona bem com grandes pacotes (lotes) de dados - ele pode lidar facilmente com a gravação de lotes em milhões de linhas. Decidimos armazenar em buffer o fluxo de dados recebidos e colá-los em lotes.


Por isso, lidamos com o desempenho ruim da gravação.O

problema da gravação foi resolvido, mas nos custou um atraso significativo de vários segundos entre os dados que entram no sistema e a aparência deles em nosso banco de dados.

E isso é crítico para vários algoritmos que respondem aos dados dos sensores em tempo real.

Leia o problema de desempenho. A análise de fluxo para processamento de dados em tempo real precisa constantemente de informações do banco de dados - são dezenas de milhares de pequenas consultas. Em média, um nó ClickHouse realiza cerca de cem consultas analíticas ao mesmo tempo; ele foi criado para consultas analíticas pesadas e pouco frequentes para processar grandes quantidades de dados. Obviamente, isso não é adequado para calcular tendências no fluxo de dados de centenas de milhares de sensores.


Com um grande número de solicitações, o ClickHouse não funciona bem.Resolvendo

o problema . Decidimos colocar um cache na frente do ClickHouse, que conterá os dados mais solicitados nas últimas 24 horas.

Os dados das últimas 24 horas não são de um ano, mas também de uma quantidade bastante significativa de dados; portanto, também precisamos de um sistema AP com escala horizontal para leitura e gravação, mas com foco no desempenho, tanto para gravar eventos únicos quanto para múltiplos lendo. Também requer alta disponibilidade, análise de séries temporais, persistência e TTL embutido.

No final, precisávamos de um ClickHouse rápido, que pode até armazenar tudo na memória para maior velocidade. Como não encontramos nenhuma solução adequada no mercado, decidimos construí-la com base nos primitivos do Tarantool:

  1. Persistência - é (WAL-logs + snapshots).
  2. Desempenho - existem todos os dados na memória.
  3. Dimensionamento - há replicação + sharding.
  4. Alta disponibilidade - existe.
  5. Ferramentas de análise de séries temporais (agrupamento, agregação etc.) - feitas em procedimentos armazenados.
  6. TTL - realizado em procedimentos armazenados com uma fibra de fundo (corotina).

Acabou sendo uma solução conveniente e produtiva - uma instância contém 10.000 RPCs para leitura, incluindo consultas analíticas de até dezenas de milhares de consultas.

Aqui está a arquitetura resultante:


Arquitetura final: ClickHouse como banco de dados analítico e cache Tarantool que armazena dados em 24 horas

Novo tipo de dados - estado e seu armazenamento


Selecionamos bancos de dados especializados para todos os dados, mas a plataforma se desenvolveu e um novo tipo de dados apareceu - state. O estado contém o estado atual de dispositivos e sensores, bem como várias variáveis ​​globais para regras de análise de fluxo.

Por exemplo, há uma lâmpada na sala. Ele pode ser ativado e desativado e você sempre deve ter acesso ao seu estado atual, inclusive nas regras. Outro exemplo é uma variável nas regras de fluxo, por exemplo, algum tipo de contador. Esse tipo de dado é caracterizado pela necessidade de gravação frequente e acesso rápido, mas, ao mesmo tempo, os dados ocupam uma quantidade relativamente pequena.

O repositório de meta-informações é pouco adequado para esses tipos de dados, pois o estado pode mudar com frequência e, no nosso caso, o limite de gravação é limitado a um mestre. Os armazenamentos operacionais e de longo prazo também são inadequados, pois nosso estado mudou pela última vez há três anos e é importante que tenhamos acesso rápido à leitura.

Ou seja, para o banco de dados no qual o estado está armazenado, é importante o dimensionamento horizontal para leitura e gravação, alta disponibilidade e tolerância a falhas, enquanto é necessária consistência no nível de valores / documentos. Você pode usar a consistência geral e as transações ACID.

Uma solução adequada pode ser qualquer Valor-chave ou um banco de dados de documentos: um cluster Redis sombreado, MongoDB ou Tarantool novamente.

Prós Tarantool:

  1. Esta é a maneira mais popular de usar Tarantool.
  2. Escala horizontal - há replicação assíncrona + sharding.
  3. Consistência no nível do documento - é.

Como resultado, agora temos três Tarantools, que usamos para casos completamente diferentes: armazenamento de meta-informações, um cache para ler rapidamente dados de dispositivos e armazenar dados de status.

Como escolher um banco de dados para a plataforma IoT


  1. Um banco de dados universal não existe.
  2. Cada tipo de dado possui seu próprio banco de dados, mais adequado para ele.
  3. Às vezes, o banco de dados que você precisa pode não estar disponível no mercado.
  4. O Tarantool é adequado como base para um banco de dados especializado.

Esta palestra foi feita pela primeira vez no @Databases Meetup pelo Mail.ru Cloud Solutions. Assista a um vídeo de outras apresentações e inscreva-se nos anúncios de eventos do Telegram Around Kubernetes no Mail.ru Group .


O que mais se pode ler :

  1. Qual banco de dados escolher para o projeto, para não escolher novamente .
  2. More than Ceph: bloqueie o armazenamento na nuvem MCS .


All Articles