Estou trabalhando em um projeto com conexão à Internet via satélite com apenas 130kB/dia (se usar mais fica muito caro).
Quero enviar o máximo possível de dados "úteis" todos os dias, mantendo-me abaixo de 130kB.
Eu li aqui (Como os nomes de arquivos são armazenados?) e aqui (Os metadados não ocupam tamanho?) que os metadados são armazenados em uma parte dedicada do sistema de arquivos, mas não está claro para mim quantos bytes isso "custará" para enviá-lo.
Se eu usar FTP, por exemplo, isso depende do sistema de arquivos de origem? No sistema de arquivos do servidor? Ou está relacionado ao protocolo FTP?
Falando em protocolo de transferência, qual é o mais econômico? Pesquisei um pouco no Google e parece que cada protocolo consome bits e bytes para handshake, verificações de integridade de dados, etc. mas não encontrei claramente qual é o mais econômico e quantos bytes são necessários para o gerenciamento do protocolo em si.
Eu li também sobre o tamanho do bloco. Este problema é relevante para transferência de dados ou é apenas para armazenamento de dados (neste último caso não é um problema)?
[EDITAR 08/11/2023 11:00]
Já estou trabalhando em seleção de dados, compactação de dados, tratamento de erros, etc. Estou mais familiarizado com esses assuntos, não os mencionei nesta pergunta porque não preciso de ajuda no momento, e se for o caso em no futuro farei uma pergunta separada.
Tenho 130kB/dia, digamos que 30kB são usados pelo próprio protocolo. Minha dúvida não é como formatar meus dados para que eu possa enviar o máximo de valores possível dentro de 100kB, minha dúvida é: são mesmo 30kB? Mais? Menos? Claro que depende. Mas depende de quê? Na minha pergunta original listei algumas idéias que acrescento, preciso da sua experiência para saber se perdi alguma coisa e/ou para me ajudar a restringir minha pesquisa em direção a soluções leves.
Elementos de contexto:
Destina-se a instrumentos autônomos implantados na Antártica. Nenhuma solução relacionada a Lora é possível aí.
Os dados a serem enviados são dados de status e medição dos instrumentos. Os dados são armazenados localmente e recuperados “fisicamente” uma vez por ano. Os dados são usados para verificar se algum parâmetro do instrumento deve ser modificado, para fazer alguma pré-análise e para preparar a manutenção anual.
Se um dia os dados forem perdidos ou não concluídos, não é muito problemático, não devem ser enviados no dia seguinte.
Ainda não posso comentar, então aqui estão minhas dicas:
130kb/dia é provavelmente muito limitado para muitas transferências baseadas em arquivos, mas pode ser usado de forma bastante eficiente de outras maneiras se você se restringir um pouco mais. A pesquisa sobre middleware e protocolos de baixo nível é provavelmente mais relevante para este caso do que a transferência genérica de arquivos. Outro domínio com esse tipo de problema são os dispositivos IoT remotos, LORA (ou LORAWAN) pode ser do seu interesse.
Outro ângulo para enfrentar esse problema seria apoiar-se no conhecimento compartilhado. Coisas como transferências diferenciais (ignorando entradas padrão) e tabelas de pesquisa para possíveis mensagens reduziriam a largura de banda real ao mínimo, mas exigirão um bom entendimento e codificação de sua comunicação. Buffers de protocolo são uma solução para esse tipo de problema.
Não se esqueça de contar na correção de erros. Aumentará o tamanho bruto, mas evitará a enorme latência de um reenvio com transportes menos confiáveis.
A maneira de obter o máximo de dados possível dos seus 130kB/dia é eliminar o máximo possível de camadas de protocolo. FTP fornece recursos como nomes de arquivos, permissões, estrutura de diretórios e autenticação. Você provavelmente não precisa desses recursos. A questão é: exatamente quanto podemos cortar antes de começarmos a ter problemas?
Um bom ponto de partida seria substituir o FTP por HTTP. Há alguma sobrecarga, mas é mínima. Por exemplo, tentei uma solicitação HTTP com curl e o HTTP adicionou uma sobrecarga de 771 bytes na forma de cabeçalhos. Você pode otimizar isso ainda mais, se desejar. Observe que, além da sobrecarga de 771 bytes do HTTP, há alguma sobrecarga do TCP, já que o HTTP é executado sobre o TCP.
Uma opção melhor seria apenas enviar o arquivo diretamente pelo TCP. O TCP tem alguma sobrecarga. Esta fonte estima cerca de 2,74% (incluindo cabeçalhos IPv4). Se você enviar o arquivo diretamente por TCP, nenhum metadado sobre o arquivo será transmitido. Você não saberá o nome do arquivo original. Provavelmente está tudo bem. Você pode simplesmente nomeá-lo com base na hora em que foi recebido.
Se quiser economizar um pouco mais, você pode usar o UDP. Isso daria trabalho, mas poderia ajudá-lo a diminuir um pouco esse número de 2,74%.
Se quiser economizar ainda mais, você pode usar soquetes IP brutos. Eles são funcionalmente idênticos ao UDP, exceto sem números de porta ou somas de verificação e com 8 bytes a menos de sobrecarga por pacote. A falta de números de porta, entretanto, significa que eles não podem atravessar o NAT. Isso exigiria que seu computador de medição remota tivesse um endereço IP público próprio, o que provavelmente não possui. Você pode fazer funcionar, mas não acho que valeria a pena o esforço versus o UDP.
Como outros apontaram, seu maior potencial de economia vem da mudança do envio de arquivos para o envio de dados . Em um comentário, você disse:
Supondo que você queira dizer floats de 32 bits, esse arquivo deve ser
[4 bytes per float]*[95 columns]*[86400 seconds in a day] = 31.31MiB
Talvez você esteja armazenando floats de 64 bits (você realmente precisa desse nível de precisão)?
[8 bytes per float]*[95 columns]*[86400 seconds in a day] = 62.62MiB
Pela maneira como você falou, suponho que esses valores normalmente não mudam rapidamente. Talvez você possa enviar valores de alta precisão para a primeira linha e, em seguida, enviar deltas menores para cada linha subsequente. Se você estiver disposto a postar um de seus arquivos de dados, eu estaria interessado em ver o quão pequeno eu poderia obtê-lo.
Os metadados do arquivo não são algo opaco que você obtém de um sistema de arquivos e "envia". É um conjunto de parâmetros individuais que você escolhe – diferentes protocolos enviam diferentes conjuntos de metadados e, se você criar seu próprio software para transferência de arquivos, poderá decidir quais campos deseja enviar e decidir quando e como enviar . envia-os.
O maior tipo de metadados – o layout que descreve como o arquivo é armazenado fisicamente no disco – não depende apenas do sistema de arquivos, mas também é completamente interno. Ou seja, embora você possa perguntar ao sistema de arquivos sobre a lista de extensões de arquivos, esse não é o tipo de metadados que você precisa transferir (ou mesmo olhar); você apenas lê o arquivo do início ao fim e o sistema de arquivos do receptor decide seu próprio layout de armazenamento.
A maioria dos outros campos são pequenos (como carimbos de data e hora) ou opcionais e não são necessários para transferência (como permissões de arquivo, que por exemplo, SMB ou NFS serão transferidos, mas HTTP não - e você certamente também não precisa).
Por fim, como se trata de vários campos e não apenas de um único bloco opaco de dados, o tamanho total também depende muito de como você escolhe organizar esses campos. Por exemplo, você envia a hora da modificação como uma data textual ou como um campo de nanossegundos de 64 bits ou como segundos decimais ou como um varint ou simplesmente não envia?
Ou seja, é difícil, senão impossível, fornecer uma resposta pronta para uso "qual protocolo é o melhor" neste estágio. Você precisa passar alguns momentos estudando projetos de protocolos de rede; no mínimo, você deve observar como alguns desses protocolos funcionam – suas especificações ou capturas de pacotes – para ter uma ideia aproximada de como funcionam os “metadados”.
O sistema de arquivos de origem ou destino geralmente não importa ao usar protocolos de transferência de arquivos em rede, pois todo o propósito de tais protocolos é abstrair as especificidades do armazenamento de arquivos subjacente e definir exatamente o que é enviado pela rede.
Quando um cliente está conversando com um servidor FTP, ele não sabe nada sobre o sistema de arquivos subjacente (e pode até não ser um sistema de arquivos real; o servidor FTP poderia muito bem apresentar uma visualização de tabela MySQL como "arquivos"...), tudo ele troca comandos FTP – e transfere apenas os campos de metadados definidos no FTP.
Ambos. Por exemplo, alguns protocolos de transferência aplicam uma soma de verificação a cada bloco (veja, por exemplo, XMODEM para um exemplo comumente usado); isso aumentará ligeiramente a quantidade total de dados se tudo correr bem, mas ao mesmo tempo reduzirá enormemente a quantidade de dados se a qualidade do link for ruim e alguns blocos precisarem ser retransmitidos (o que será mais barato do que reenviar o arquivo inteiro) . É uma compensação que você ajusta dependendo de suas necessidades específicas.
(Neste caso, geralmente você pode assumir que 'bloco' e 'pacote' são aproximadamente iguais. O tamanho do bloco é definido pelo protocolo de transferência usado e não tem nada a ver com o armazenamento.)
Para metadados, existem dois tipos: sistema de arquivos e embutido.
Os metadados do sistema de arquivos incluem a data de criação, o usuário proprietário e muito mais, mas geralmente permanecem no sistema de arquivos de origem e são criados novamente no sistema de arquivos de destino. Resumindo, normalmente não é transferido, apenas os dados do arquivo são transferidos. No entanto, se você transferir um arquivo, como Zip, os metadados serão incluídos no arquivo.
Os metadados integrados estão incluídos em alguns arquivos, como arquivos do Office, e podem incluir detalhes sobre o autor, os dados e muito mais. Esses dados são transmitidos com o próprio documento e são indivisíveis.
Se você deseja usar ao máximo a largura de banda, o protocolo em si é menos importante, podendo ser FTP, FTPS ou SFTP ou outro conforme necessário. É muito mais importante reduzir a quantidade de dados a serem transferidos.
Você pode fazer isso pelo método óbvio de limitar os dados a serem transferidos, mas também pode usar métodos de compactação para reduzir o tamanho dos dados. Zip é o método de compactação mais antigo, mas 7Zip é mais novo e mais eficiente na maioria dos casos.
Veja o post Quais as melhores opções para compactar arquivos com 7 Zip?
Minha resposta neste post mostra que os melhores parâmetros de compactação variam de acordo com o tipo de dados envolvidos. Para encontrar os parâmetros mais eficientes, usei o sintonizador fino 7-ZIP . Esta ferramenta busca os parâmetros ideais simplesmente repetindo a compactação com parâmetros variados procurando a combinação ideal. Você pode usá-lo em seus dados para encontrar os melhores parâmetros.
Observe que os dados que já estão compactados não podem ser compactados ainda mais. Não faz sentido compactar arquivos como arquivos Zip ou documentos do Office.
Sabendo um pouco sobre instrumentação, mas nada sobre seu instrumento, quase sempre há coisas que você pode fazer antes da compressão.
Por exemplo:
Já que você apresenta sua pergunta como absoluta ("a maioria"):
Um protocolo personalizado que transmite dados binários brutos compactados em sua menor forma aceitável (menos precisa) e omite quaisquer sobrecargas, como metadados de arquivo. Isso pode significar serializar dados em tipos de dados de comprimento variável. Você provavelmente teria que experimentar muitas abordagens diferentes usando um grande conjunto de dados representativos.
Você poderia usar UDP e lançar seu próprio algoritmo de verificação para pacotes ausentes, duplicados ou fora de sequência, mas talvez seja melhor começar com TCP.
Eu incluiria uma soma de verificação.
Obviamente, para um protocolo personalizado, você deve escrever software cliente e servidor e fazer sua própria avaliação das implicações para a segurança, etc.