Uma pergunta favorita sobre qualquer sistema distribuído de um especialista não técnico é "Quantos tps existem no seu blockchain?". No entanto, o número dado em resposta geralmente tem pouco em comum com o que o interlocutor gostaria de ouvir. Na verdade, ele queria perguntar "seu blockchain atenderá aos meus requisitos de negócios", e esses requisitos não são um número, mas muitas condições - aqui está a tolerância a falhas da rede, requisitos de finalidade, tamanho, natureza das transações e muitos outros parâmetros. Portanto, é improvável que a resposta à pergunta “quantas tps” seja simples e quase nunca será completa. Um sistema distribuído com dezenas e centenas de nós executando cálculos bastante complexos pode estar em um grande número de estados diferentes relacionados ao estado da rede, conteúdo de blockchain, falhas técnicas, problemas econômicos, ataques à rede e muitos outros motivos. Os estágios em que os problemas de desempenho são possíveis diferem dos serviços tradicionais, e o servidor de rede blockchain é um serviço de rede que combina a funcionalidade de um banco de dados, um servidor web e um cliente de torrent, o que torna extremamente difícil em termos de perfil de carga para todos os subsistemas : processador, memória, rede, armazenamento
Aconteceu que redes e blockchains descentralizados são um software bastante específico e incomum para desenvolvedores de software centralizado. Portanto, gostaria de destacar aspectos importantes do desempenho e sustentabilidade das redes descentralizadas, abordagens para medi-las e encontrar gargalos. Consideraremos vários problemas de desempenho que limitam a velocidade de prestação de um serviço aos usuários de blockchain e observamos os recursos específicos para esse tipo de software.
Estágios de Solicitação de Serviço ao Cliente Blockchain
Para falar honestamente sobre a qualidade de qualquer serviço mais ou menos complexo, é necessário levar em consideração não apenas os valores médios, mas também as máximas / mínimas, medianas, percentis. Teoricamente, podemos falar de 1000 tps em algumas blockchain, mas se 900 transações forem executadas a uma velocidade tremenda e 100 transações "desligarem" por vários segundos, o tempo médio coletado para todas as transações não será uma métrica honesta para um cliente que em alguns segundos não foi possível concluir a transação. “Pontuações” temporárias causadas pela falta de rodadas de consenso ou separação de rede podem arruinar muito um serviço que mostrou excelente desempenho nos bancos de teste.
Para identificar esse gargalo - e é necessário entender bem os estágios em que o blockchain real pode ter dificuldade em atender os usuários. Vamos descrever o ciclo de entrega e processamento de uma transação, bem como obter um novo estado de blockchain a partir do qual o cliente pode verificar se sua transação foi processada e levada em consideração.
- transação é formada no cliente
- transação é assinada no cliente
- o cliente seleciona um dos nós e envia sua transação para ele
- o cliente assina atualizações do banco de dados estadual de nós, aguardando o aparecimento dos resultados da execução de sua transação
- um nó propaga uma transação em uma rede p2p
- vários ou um BP (produtor de bloco) processará transações acumuladas, atualizando o banco de dados do estado
- A BP forma um novo bloco, processando o número necessário de transações
- BP distribui novo bloco na rede p2p
- o novo bloco é entregue no nó acessado pelo cliente
- o nó atualiza o banco de dados de estado
- o nó vê a atualização relacionada ao cliente e envia uma notificação de transação
Agora, vamos examinar mais de perto essas etapas e descrever possíveis problemas de desempenho em cada etapa. Ao contrário dos sistemas centralizados, também consideramos a execução de código nos clientes da rede. Frequentemente, ao medir tps, o tempo de processamento da transação é coletado dos nós e não do cliente - isso não é totalmente honesto. O cliente não se importa com a rapidez com que o nó processou sua transação, o mais importante para ele é o momento em que informações confiáveis sobre essa transação, incluídas na blockchain, ficam disponíveis para ele. É essa métrica que é essencialmente o tempo necessário para concluir uma transação. Isso significa que diferentes clientes, mesmo enviando a mesma transação, podem receber tempos completamente diferentes, que dependem do canal, carga e proximidade do nó, etc. Portanto, é absolutamente necessário medir esse tempo nos clientes, pois é esse parâmetro que precisa ser otimizado.
Preparação de transação no lado do cliente
Vamos começar com os dois primeiros pontos: a transação é formada e assinada pelo cliente. Curiosamente, esse também pode ser o gargalo do desempenho da blockchain do ponto de vista de um cliente. Isso é incomum para serviços centralizados, que executam todos os cálculos e operações de dados, e o cliente simplesmente prepara uma solicitação curta que pode solicitar uma grande quantidade de dados ou cálculos, obtendo um resultado final. Nas blockchains, o código do cliente está se tornando cada vez mais poderoso, e o núcleo da blockchain está se tornando cada vez mais leve, e é costume dar tarefas de computação em massa ao software do cliente. Existem clientes em blockchains que podem preparar uma única transação por um longo período de tempo (estou falando de várias provas de merkle, provas sucintas, assinaturas de limite e outras operações complexas no lado do cliente). Um bom exemplo de verificação fácil na cadeia e preparação difícil de uma transação em um cliente é a prova de pertencer a uma lista baseada na árvore Merkle, aqui está um artigo .
Além disso, não esqueça que o código do cliente não apenas envia transações para o blockchain, mas solicita primeiro o status do blockchain - e essa atividade pode afetar a carga da rede e os nós da blockchain. Portanto, ao fazer medições, será razoável emular o comportamento do código do cliente da maneira mais completa possível. Mesmo que seu blockchain tenha clientes light regulares que colocam uma assinatura digital simples na transação mais simples para transferir algum ativo, todos os anos ainda há cálculos mais massivos no cliente, os algoritmos criptográficos ficam mais fortes e essa parte do processamento pode se transformar em um gargalo pesado em o futuro. Portanto, tenha cuidado e não perca a situação quando em uma transação com duração de 3,5s, 2,5s é gasta na preparação e assinatura da transação e 1,0s- no envio à rede e aguardando uma resposta. Para avaliar os riscos desse gargalo, você precisa coletar métricas de máquinas clientes, e não apenas de nós blockchain.
Enviando uma transação e monitorando seu status
A próxima etapa é enviar a transação para o nó blockchain selecionado e receber o status de sua adoção no pool de transações. Esse estágio é semelhante a um acesso normal ao banco de dados, o nó deve gravar a transação no pool e começar a distribuir informações sobre ele pela rede p2p. A abordagem para avaliar o desempenho aqui é semelhante à avaliação do desempenho dos microsserviços tradicionais da API da Web, e as transações nas próprias cadeias de blocos podem ser atualizadas e alterar ativamente seu status. Em geral, a atualização das informações da transação em algumas cadeias de bloco pode ocorrer várias vezes, por exemplo, ao alternar entre os garfos de uma cadeia ou quando a BP informa sobre sua intenção de incluir uma transação em um bloco. Limitações no volume desse pool e no número de transações nele podem afetar o desempenho da blockchain. Se o pool de transações estiver entupido no tamanho máximo possível ou não couber na RAM, o desempenho da rede pode diminuir drasticamente. As blockchains não têm proteção centralizada contra o fluxo de mensagens indesejadas e, se a blockchain suportar transações de alto volume e taxas baixas, isso poderá levar a um estouro do pool de transações - esse é outro gargalo em potencial do desempenho.
Nas blockchains, o cliente encaminha a transação para qualquer nó da blockchain que ele gosta, o hash da transação geralmente é conhecido pelo cliente antes do envio, então tudo o que ele precisa fazer é obter uma conexão e, após a transferência, esperar até que a blockchain mude de estado, ativando sua transação. Observe que, medindo "tps", você pode obter resultados completamente diferentes para diferentes maneiras de conectar-se a um nó blockchain. Pode ser um HTTP RPC ou WebSocket comum, permitindo implementar o padrão de "inscrição". No segundo caso, o cliente receberá uma notificação anteriormente e o nó gastará menos recursos (principalmente memória e tráfego) em respostas sobre o status da transação. Portanto, ao medir "tps", é necessário considerar a maneira como os clientes se conectam aos nós. Portanto, para avaliar os riscos desse gargalo, a referência do blockchain deve ser capaz de emular clientes com solicitações WebSocket e HTTP RPC, em frações correspondentes a redes reais, bem como alterar a natureza das transações e seu tamanho.
Para avaliar os riscos desse gargalo, você também precisa coletar métricas de máquinas clientes, e não apenas de nós blockchain.
Transmissão de transações e blocos em uma rede p2p
Em blockchains, a rede ponto a ponto (p2p) é usada para transferir entre participantes da transação e blocos. As transações são distribuídas pela rede, começando com um dos nós, até atingirem pares de produtores que empacotam transações em blocos e, usando o mesmo p2p, distribuem novos blocos por todos os nós da rede. A base da maioria das redes p2p modernas são várias modificações do protocolo Kademlia. Aqui está uma boa visão geral deste protocolo e aqui está um artigo com várias medidas na rede BitTorrent, segundo o qual você pode entender que esse tipo de rede é mais complicado e menos previsível do que uma rede de serviços centralizada configurada com hardware. Além disso, aqui está um artigo sobre como medir várias métricas interessantes para nós do Ethereum.
Em resumo, cada par nessas redes mantém sua própria lista dinâmica de outros pares que solicitam blocos de informações endereçados pelo conteúdo. Após o recebimento da solicitação, o par fornece as informações necessárias ou transmite a solicitação para o próximo par pseudoaleatório da lista e, após receber a resposta, passa para o solicitante e o armazena em cache por um tempo, fornecendo esse bloco de informações na próxima vez. Assim, as informações populares aparecem em um grande número de caches em um grande número de pares e as informações impopulares são gradualmente excluídas. Os pares controlam quem transmitiu quanta informação a quem e a rede tenta estimular os distribuidores ativos, aumentando sua classificação e fornecendo a eles um nível de serviço mais alto, retirando automaticamente participantes inativos das listas de pares.
Portanto, a transação agora precisa ser distribuída pela rede para que os produtores do bloco possam vê-la e incluí-la no bloco. A Noda "distribui" ativamente uma nova transação para todos e escuta a rede, aguardando o bloco, no índice do qual a transação necessária aparecerá para notificar o cliente em espera. O tempo até a rede enviar informações entre si sobre novas transações e blocos nas redes p2p depende de um número muito grande de fatores: o número de nós honestos trabalhando nas proximidades (do ponto de vista da rede), o "aquecimento" dos caches desses nós, o tamanho dos blocos, transações e a natureza das alterações , geografia da rede, número de nós e muitos outros fatores. Medições abrangentes das métricas de desempenho nessas redes são uma questão complexa, é necessário avaliar simultaneamente o tempo de processamento de solicitações nos clientes e nos pares (nós blockchain). Problemas em qualquer mecanismo p2p, agrupamento e armazenamento de dados incorretos, gerenciamento ineficiente de listas de pares ativas e muitos outros fatores podem causar atrasos que afetam a eficiência de toda a rede como um todo, e esse gargalo é o mais difícil de analisar, testar e interpretação dos resultados.
Processamento da cadeia de blocos e atualização do banco de dados de estado
A parte mais importante do trabalho da blockchain é o algoritmo de consenso, sua aplicação a novos blocos recebidos da rede e o processamento de transações com o registro dos resultados no banco de dados estadual. Adicionar um novo bloco à cadeia e a seleção subsequente da cadeia principal deve funcionar o mais rápido possível. No entanto, na vida real, "deveria" não significa "funciona", e você pode, por exemplo, imaginar uma situação em que duas longas cadeias concorrentes alternam constantemente entre si, alterando os metadados de milhares de transações no pool em cada comutador e revertendo constantemente o estado do banco de dados estadual. Essa etapa, em termos de determinação de gargalo, é mais simples que a camada p2p da rede, porque a execução da transação e o algoritmo de consenso são estritamente determinados, e medir qualquer coisa aqui é mais fácil.
O principal é não confundir a degradação aleatória do desempenho desse estágio com problemas de rede - os nós fornecem blocos e informações sobre a cadeia principal mais lentamente e, para um cliente externo, pode parecer uma rede lenta, embora o problema esteja em um local completamente diferente.
Para otimizar o desempenho nesse estágio, é útil coletar e monitorar métricas dos próprios nós e incluir aquelas relacionadas às atualizações do banco de dados de estados: o número de blocos processados no nó, seu tamanho, número de transações, número de comutadores entre garfos em cadeia, número de blocos inválidos. , tempo de execução da máquina virtual, tempo de confirmação de dados etc. Isso não confundirá problemas de rede com erros nos algoritmos de processamento em cadeia.
Uma máquina virtual executando transações pode ser uma fonte útil de informações que pode otimizar a operação do blockchain. O número de alocações de memória, o número de instruções de leitura / gravação e outras métricas relacionadas à eficiência da execução do código do contrato podem fornecer muitas informações úteis aos desenvolvedores. Ao mesmo tempo, contratos inteligentes são programas, o que significa que, em teoria, eles podem consumir qualquer um dos recursos: CPU / memória / rede / armazenamento, portanto, o processamento de transações é uma etapa bastante incerta, que além disso muda bastante ao alternar entre versões e quando alteração do código dos contratos. Portanto, métricas sobre o processamento de transações também são necessárias para otimizar efetivamente o desempenho da blockchain.
Cliente recebendo notificação de inclusão de transação na blockchain
Este é o estágio final de recebimento de um serviço de blockchain por um cliente, em comparação com outros estágios, não há grande sobrecarga, mas ainda vale a pena considerar a possibilidade de um cliente receber uma resposta de volume de um nó (por exemplo, um contrato inteligente que retorna uma matriz de dados). De qualquer forma, esse momento é o mais importante para quem fez a pergunta “quantos tps existem na sua blockchain?”, Porque neste momento, o horário de recebimento do serviço é fixo.
Nesse local, há sempre o envio em tempo integral que o cliente teve que esperar por uma resposta do blockchain, é nesse momento que o usuário aguardará a confirmação em seu aplicativo e é a otimização dele que é a principal tarefa dos desenvolvedores.
Conclusão
Como resultado, é possível descrever os tipos de operações executadas em blockchains e dividi-las em várias categorias:
- transformações criptográficas, construção de evidências
- rede ponto a ponto, replicação de transações e blocos
- processamento de transações, execução de contratos inteligentes
- aplicando mudanças no blockchain ao banco de dados estadual, atualizando dados de transação e bloqueio
- solicitações somente leitura para indicar o banco de dados, API do nó blockchain, serviços de assinatura
Em geral, os requisitos técnicos para os nós das cadeias de blocos modernas são extremamente sérios - são CPUs rápidas para criptografia, uma grande quantidade de RAM para armazenar e acessar rapidamente o banco de dados de estado, interação de rede usando um grande número de conexões abertas simultaneamente e armazenamento volumoso. Esses altos requisitos e a abundância de vários tipos de operações levam inevitavelmente ao fato de que os recursos dos nós podem não ser suficientes e, em seguida, qualquer uma das etapas discutidas acima pode se tornar o próximo gargalo para o desempenho geral da rede.
Ao desenvolver e avaliar o desempenho de blockchains, você terá que considerar todos esses pontos. Para fazer isso, você precisa coletar e analisar métricas ao mesmo tempo dos clientes e nós da rede, procurar correlações entre elas, avaliar o tempo em que o serviço é prestado aos clientes, levar em conta todos os principais recursos: cpu / memory / network / storage, entender como eles são usados e se afetam. Tudo isso faz da comparação das velocidades de várias cadeias de blocos na forma de "quantos TPS" uma tarefa extremamente ingrata, pois há um grande número de configurações e condições diferentes. Em grandes sistemas centralizados, clusters de centenas de servidores, esses problemas também são complexos e também exigem a coleta de um grande número de métricas diferentes, mas em cadeias de bloco, devido a redes p2p, máquinas virtuais executando contratos, economia interna, o número de graus de liberdade é muito maior, o que torna o teste mesmo em vários servidores, ele não mostra e mostra apenas valores extremamente aproximados, que quase não têm conexão com a realidade.
Portanto, ao desenvolver uma blockchain no kernel, para avaliar o desempenho e responder à pergunta "ela melhorou em comparação com a última vez", usamos um software bastante complicado, orquestrando o lançamento da blockchain com dezenas de nós e iniciando automaticamente o benchmark e coletando métricas, sem essas informações, é extremamente difícil depurar Protocolos que funcionam com muitos participantes.
Então, depois de receber a pergunta "quantos TPS há no seu blockchain?", Ofereça à pessoa com quem está conversando com o chá e descubra se ele está pronto para se familiarizar com uma dúzia de gráficos e também ouça todas as três caixas de problemas de desempenho do blockchain e suas sugestões para resolvê-los ...