IBM Cloud Docs
IBM Cloudant na prática

IBM Cloudant na prática

O IBM Cloudant no documento de prática é o terceiro documento de melhor prática na série. Ela mostra as melhores práticas a seguir:

  • Como evitar conflitos.
  • Como a exclusão de documentos funciona
  • O que deve ser cuidado com as atualizações.
  • Como trabalhar num ambiente eventualmente consistente.
  • Como configurar replicação.
  • Como usar a API em massa.
  • Por que você não deve alterar Q, R e N.
  • Como os limites de taxa funcionam
  • O que a criação de log rastreia
  • Como compactar o seu tráfego HTTP

Para mais informações, consulte Modelagem de dados ou Indexação e consulta.

O conteúdo neste documento foi originalmente escrito por Stefan Kruger como um post do blog Melhores e piores práticas em 21 de novembro de 2019.

Evitar conflitos

O IBM Cloudant é projetado para tratar os conflitos como um estado natural de dados em um sistema distribuído. Esse recurso é um recurso poderoso que ajuda um cluster IBM Cloudant a sempre manter a alta disponibilidade. No entanto, a suposição é de que os conflitos ainda são razoavelmente raros. O rastreamento de conflitos no núcleo do IBM Cloudant tem um custo significativo que está associado a ele.

É perfeitamente possível (mas uma má ideia!) ignorar os conflitos. O banco de dados continuará operando tranquilamente escolhendo uma revisão aleatória, mas determinista, de documentos conflitantes. No entanto, à medida que o número de conflitos não resolvidos cresce, o desempenho do banco de dados diminui drasticamente, especialmente durante a replicação.

Como desenvolvedor, é de sua responsabilidade verificar, e resolver, conflitos, ou ainda melhor, empregar modelos de dados que inviabilizem os conflitos.

Se você cria conflitos rotineiramente, deverá realmente considerar as mudanças de modelo: mesmo que você resolva seus conflitos diligentemente, as ramificações de conflito na árvore de revisão permanecerão sem uma maneira fácil de arrumar isso. Para obter mais informações, consulte os websites a seguir:

  • Guia do IBM Cloudant para conflitos
  • Guia do IBM Cloudant para versões e MVCC
  • Série do blog de três partes sobre conflitos

A exclusão de documentos não os exclui

A exclusão de um documento de um banco de dados IBM Cloudant não os limpa. A exclusão é implementada por meio da escrita de uma nova revisão do documento sob exclusão, com um campo _deleted: true incluído. Esta revisão especial é chamada de tombstone. Os tombstones ainda ocupam espaço e também são passados pelo replicador.

Os modelos que contam com exclusões frequentes de documentos não são adequados para o IBM Cloudant. Para obter mais informações, consulte os documentos do tombstone IBM Cloudant.

Tenha cuidado com as atualizações

No final das contas, é mais caro alterar os documentos existentes do que criar novos. IBM Cloudant sempre precisa manter a estrutura de árvore do documento. Essa regra se aplicará mesmo se nós internos na árvore forem separados de suas cargas úteis. Se você achar que cria árvores de revisão longas, seu desempenho de replicação sofrerá. Além disso, se a sua frequência de atualização for maior do que, digamos, uma ou duas vezes a cada poucos segundos, você estará mais propenso a produzir conflitos de atualização.

Prefira modelos que são imutáveis.

Ao ler as seções a seguir, A exclusão de documentos não os exclui e Cuidado com as atualizações, elas provocam uma pergunta óbvia: Que é: o conjunto de dados crescerá sem limites se o meu modelo for imutável? Se você aceitar que as exclusões não limpam completamente os dados excluídos e que as atualizações não estão atualizando em termos de crescimento do volume de dados, não existirá muita diferença. O gerenciamento do volume de dados ao longo do tempo requer diferentes técnicas.

A única maneira de recuperar espaço verdadeiramente é excluir bancos de dados, em vez de documentos. É possível replicar apenas as revisões vencedoras para um novo banco de dados e excluir o antigo para se livrar de exclusões e conflitos remanescentes. Ou talvez você possa construí-los em seu modelo para iniciar regularmente novos bancos de dados (digamos 'dados anuais') e arquivar (ou remover) dados desatualizados, se o seu caso de uso permitir.

A consistência eventual é um mestre severo (também conhecido como "não leia suas gravações")

A consistência eventual é uma ótima ideia no papel, e um contribuidor fundamental para a capacidade do IBM Cloudant de escalar na prática. No entanto, é justo dizer que a mentalidade necessária para desenvolver um armazenamento de dados eventualmente consistente não parece natural para a maioria das pessoas.

Muitas vezes você é prejudicado quando escreve testes semelhantes aos seguintes:

  1. Criar um banco de dados.
  2. Preencha o banco de dados com alguns dados de teste.
  3. Consulte o banco de dados para algum subconjunto desses dados de teste.
  4. Verifique se os dados que você obteve de volta são os dados que você esperava obter.

Nada de errado com esse teste? Isso funciona em todos os outros bancos de dados que você já usou, correto?

Não no IBM Cloudant.

Ou melhor, funciona 99 vezes de 100.

O motivo dessa diferença é uma janela de inconsistência (geralmente) pequena entre a gravação de dados no banco de dados e a disponibilização desses dados em todos os nós do cluster. Como todos os nós em um cluster são iguais em estatura, não há garantia de que uma gravação e uma leitura subsequente sejam atendidas pelo mesmo nó. Portanto, em algumas circunstâncias, a leitura pode atingir um nó antes que os dados gravados o atinjam.

Então, por que você não coloca um pequeno atraso em seu teste entre a gravação e a leitura? Esse atraso torna o teste menos propenso a falhar, mas o problema ainda está lá.

O IBM Cloudant não tem garantias transacionais. Enquanto as gravações de documentos são atômicas (você tem a garantia de que um documento pode ser lido em sua totalidade, ou não pode ser lido de nenhum jeito), não há maneira para fechar a janela de inconsistência. Ela está lá por design.

Uma preocupação séria que todo desenvolvedor deve considerar é que não é possível assumir com segurança que os dados que você grava estão disponíveis para qualquer outra pessoa em um momento específico. Se você vem de um tipo diferente de tradição de banco de dados, levará algum tempo para se acostumar com esse estado.

Dica de teste: o que você pode fazer para evitar a janela de inconsistência nos testes é testar em uma instância de nó único do IBM Cloudant ou do CouchDB em execução, digamos, no Docker(informações do docker). Um único nó remove o eventual problema de consistência, mas esteja ciente de que você está testando em um ambiente que se comporta de forma diferente do que você almeja na produção. Advertência.

Replicação não é mágica

“So let’s set up three clusters across the world, Dallas, London, Sydney, with bi-directional synchronization between them to provide real-time collaboration between our 100,000 clients.”

Nº Apenas... Nº O IBM Cloudant é bom na replicação. Pode parecer mágico, mas note que não dá garantias de latência. Na verdade, todo o sistema é projetado com uma eventual consistência em mente. Tratar a replicação do IBM Cloudant como um sistema de mensagens em tempo real não termina bem. Para esse caso de uso, coloque um sistema intermediário que foi projetado para esta finalidade, como Apache Kafka.

É difícil colocar um número no rendimento de replicação. A resposta é sempre: "Depende". As coisas que impactam o desempenho da replicação incluem, mas não são limitadas a:

  1. Mude a frequência
  2. Tamanho do documento
  3. Número de tarefas de replicação simultânea no cluster como um todo
  4. Árvores de documentos amplos (em conflito)
  5. Suas configurações de capacidade de rendimento reservadas

Para obter mais informações, consulte os websites a seguir:

Use a API em massa

IBM Cloudant tem bons pontos de extremidade de API para carregar (e ler) em massa muitos documentos em uma única solicitação. Ler muitos documentos em uma única solicitação pode ser muito mais eficiente do que ler e gravar muitos documentos um de cada vez. O terminal de gravação é mostrado no exemplo a seguir:

${database}/_bulk_docs

Seu principal objetivo é ser uma parte central no algoritmo do replicador, mas também está disponível para seu uso e isso é incrível.

Com _bulk_docs, além de criar PouchDB, implemente criar, atualizar e excluir mesmo para documentos únicos para menos caminhos de código.

O exemplo a seguir cria um novo documento, atualiza um segundo existente, e exclui um terceiro documento:

curl -XPOST 'https://ACCT.cloudant.com/DB/_bulk_docs' \
     -H "Content-Type: application/json" \
     -d '{"docs":[{"baz":"boo"}, \
         {"_id":"463bd...","foo":"bar"}, \
         {"_id":"ae52d...","_rev":"1-8147...","_deleted": true}]}'

Também é possível buscar muitos documentos em uma única solicitação emitindo um POST para ' _all_docs (também existe um ponto de extremidade relativamente novo chamado ' _bulk_get, mas esse ponto de extremidade provavelmente não é o que você deseja. Ele está lá para um propósito interno específico).

Para buscar um conjunto fixo de docs usando _all_docs, POST com um corpo keys, execute o seguinte comando:

curl -XPOST 'https://ACCT.cloudant.com/DB/_all_docs' \
     -H "Content-Type: application/json" \
     -d '{"keys":["ab234....","87addef...","76ccad..."]}'

O IBM Cloudant (no momento da gravação) impõe um tamanho de solicitação máximo de 11 MB. Solicitações _bulk_docs que excedam este tamanho são rejeitadas com um 413: Payload Too Large error.

Para obter mais informações, consulte os websites a seguir:

Não mexa com Q, R e N a menos que você realmente saiba o que está fazendo

Não altere Q, R e N a menos que realmente saiba o que está fazendo. os parâmetros de quorum e sharding do IBM Cloudant, depois que você os descobre, parecem opções tentadoras para alterar o comportamento do banco de dados.

Consistência mais forte, certamente eu posso configurar o quorum de gravação para a contagem de réplicas?

Não! Lembre-se de que não existe nenhuma maneira para fechar a janela de inconsistência em um cluster.

Não vá lá. O comportamento pode ser muito mais difícil de entender especialmente durante as partições da rede. Se você estiver usando o Cloudant-the-service, os valores padrão servirão bem para a maioria dos usuários.

Às vezes, ajustar a contagem de shard de um banco de dados é essencial para obter o melhor desempenho possível. Se você não puder dizer o porquê, provavelmente sua situação irá piorar.

IBM Cloudant tem limite de taxa - deixe que esse limite de taxa informe seu código

O Cloudant-the-service (ao contrário do CouchDB básico) é vendido em um modelo de "capacidade de rendimento reservada". Isso significa que você paga pelo direito de usar até uma determinada taxa de transferência, em vez da taxa de transferência que você acaba usando. O método direito de uso leva um tempo para ser absorvido. Uma comparação excêntrica pode ser a de um contrato de telefone celular em que você paga por um determinado número de minutos, independentemente de usá-los ou não.

Embora a comparação de contrato do celular não capture toda a situação, nenhuma restrição existe sobre a soma de solicitações que você pode fazer para IBM Cloudant em um mês. A restrição está na rapidez com que você faz as solicitações.

É realmente uma promessa que você faz para o IBM Cloudant, e não uma que o IBM Cloudant faz para você. Você promete não fazer mais solicitações por segundo do que você concordou antecipadamente. Um limite máximo de velocidade, se preferir. Se você transgredir, o IBM Cloudant fará suas solicitações falharem com um status de 429: Too Many Requests. É sua responsabilidade cuidar desse caso e lidar com ele, o que pode ser difícil quando existem vários servidores de aplicativos. Como eles podem se coordenar para garantir que permaneçam coletivamente abaixo do limite de solicitações por segundo?

IBM CloudantAs bibliotecas clientes oficiais possuem alguma disposição embutida para este caso de uso que pode ser ativado, seguindo uma estratégia de "back-off e retry".

Essa provisão integrada está desativada por padrão para forçar você a pensar sobre isso.

No entanto, se você contar apenas com essa facilidade, poderá eventualmente ficar desapontado. A estratégia de recuar e tentar novamente ajuda apenas em casos de transgressão temporária, não em uma resistência persistente com relação aos limites de capacidade de rendimento provisionados.

Sua lógica de negócios deve ser capaz de lidar com essa condição. Outra maneira de ver isso é que você recebe a alocação pela qual paga. Se essa alocação não for suficiente, a única solução é pagar por uma alocação maior.

A capacidade de rendimento provisionado é dividida em três depósitos diferentes: Consultas, Gravações e Consultas. Uma Consulta é uma leitura de "chave primária", buscando um documento com base em seu _id. Uma Gravação está armazenando um documento ou anexo em disco, e um Consulta está consultando documentos usando um índice secundário (qualquer terminal de API que tenha um _design ou _find nele).

Você obtém alocações diferentes de cada um deles e as proporções entre eles são fixas. Esse fato pode ser usado para otimizar o custo. Você fica com 20 Pesquisas para cada Consulta (por segundo). É possível descobrir que você está atingindo principalmente o limite de Consulta, mas você tem bastante espaço Pesquisas. Pode ser possível reduzir a dependência de Consultas por meio de alguma remodelação dos dados ou talvez fazendo mais trabalho do lado do cliente.

O resultado aqui, porém, é que você não pode presumir que qualquer biblioteca ou estrutura de terceiro otimizará o custo antes da conveniência. As estruturas do lado do cliente que suportam várias camadas de persistência usando plug-ins provavelmente não estão cientes dessa situação ou podem ser incapazes de fazer essas trocas.

Verificar a compatibilidade de biblioteca ou estrutura de terceiros antes de se comprometer com uma ferramenta específica é uma boa ideia.

Também vale a pena entender que as taxas não são diretamente equivalentes às chamadas de terminal da API HTTP. Deve-se esperar que, por exemplo, uma atualização em massa seja contada de acordo com suas gravações de documentos constituintes.

A criação de log ajuda a ver o que está acontecendo

os registros de IBM Cloudantque indicam cada chamada de API feita, o que foi solicitado e quanto tempo levou para ser respondido podem ser automaticamente transferidos para IBM Cloud Logs para análise e geração de relatórios para serviços IBM Cloud. Esses dados são úteis para manter um olho nos volumes de solicitação, no desempenho e se seu aplicativo está excedendo a capacidade provisionada para o serviço IBM Cloudant.

IBM Cloud Logs é um serviço medido que oferece uma variedade de períodos de retenção e níveis de consumo de registros. As camadas permitem que os dados sejam retidos para arquivamento no COS, pesquisados a frio ou a quente e alertados a custos variáveis. Fatias e agregações de seus dados podem ser criadas em painéis visuais para fornecer uma visão rápida do tráfego do IBM Cloudant. Para obter mais informações, veja a documentação a seguir:

Compacte seu tráfego HTTP

O IBM Cloudant compacta suas respostas JSON se você fornecer um cabeçalho HTTP na solicitação que indica que o seu código pode manipular dados neste formato:

Request:

> GET /cars/_all_docs?limit=5&include_docs=true HTTP/2
> Host: myhost.cloudant.com
> Accept: */*
> Accept-Encoding: deflate, gzip

Response:                                                                   

< HTTP/2 200
< content-type: application/json
< content-encoding: gzip

O conteúdo compactado ocupa uma fração do tamanho do equivalente descompactado, o que significa que leva menos tempo para transportar os dados dos servidores do IBM Cloudant para seu aplicativo.

Você também pode optar por compactar os corpos de solicitações HTTP usando o cabeçalho Content-encoding. Essa prática ajuda a reduzir o tempo de transferência de dados quando você grava documentos em IBM Cloudant.