Introdução

O Couchbase é capaz de atingir taxas de gravação muito altas, pode ser escalonado rapidamente e adicionar nós facilmente, mas um modelo de objeto ruim pode ser um obstáculo a essas qualidades. Em alguns bancos de dados, se você tiver taxas de gravação muito altas, sacrificará as taxas de leitura, mas o Couchbase tem alguns recursos bastante exclusivos no espaço NoSQL para oferecer suporte a ambos de maneira eficaz. Nesta postagem do blog, discutiremos o que é necessário para projetar um modelo de objeto que atenda a esses recursos para registro e dados de eventos, mas que também tenha fácil capacidade de pesquisa com N1QL.

O exemplo de caso de uso que encontrei recentemente em uma conversa é usar o Couchbase como banco de dados operacional para coletar vários tipos de eventos de sistemas externos, como equipamentos de rede, servidores ou até mesmo dados de registro. Em seguida, o serviço precisa ter a capacidade de ver rapidamente o número de eventos na interface do usuário, em uma espécie de rollup de hora em hora. A outra necessidade é poder clicar nesse número e fazer uma busca detalhada em uma lista desse tipo de evento. Por exemplo, mostrar todos os eventos RouterError em 22 de junho de 2015 para a hora de 16:00.

Outro aspecto a ser lembrado é que esta postagem do blog tem o objetivo de mostrar um conceito mais avançado e como você pode aplicá-lo. Obviamente, isso não significa que seja exatamente a maneira correta para o seu caso de uso, mesmo que seja semelhante ao que estou falando. Obviamente, isso não significa que seja exatamente a maneira correta para o seu caso de uso, mesmo que seja semelhante ao que estou falando. O objetivo é fazer você pensar sobre a modelagem avançada de objetos no Couchbase e como você pode usar seu poder de forma mais eficaz para obter o máximo dele de uma forma que pode não ser óbvia para todos.

Contador incremental para leitura de eventos e contagens por hora

Essa abordagem permitiria ler facilmente o último número N de eventos ou um tipo de evento por uma hora, em vez de fazer isso com uma consulta de exibição. Ou podemos ler todos os eventos de um determinado dia. Ela é otimizada para taxas de gravação muito altas e permite a pesquisa fácil de dados em um nível decente de granularidade. Explicarei isso em um nível mais alto e, em seguida, abordarei exemplos específicos para explicar melhor a ideia.

Precisaremos de dois tipos de objeto para isso em nosso bucket.

  1. O objeto Counter - Esse é um objeto de chave/valor e contém um número inteiro. Esse número inteiro representa a extremidade superior do número de objetos para esse tipo de evento e hora ou, em outras palavras, é a extremidade superior da matriz de eventos. É também o objeto que você lerá para mostrar quantos eventos existem para essa combinação de tipo/hora. Usaremos métodos especiais e específicos dos SDKs do Couchbase chamados Counter Operations. Cada SDK tem sua própria versão desses métodos, mas Aqui está a versão do node.js como um exemplo.
  2. O objeto Event - esse é um objeto de documento JSON e contém os dados reais sobre os eventos que queremos capturar.

O objeto contador

Você cria um objeto contador para cada combinação de tipo de evento e hora. Pense nisso como um objeto operacional sobre os documentos que criaremos. Isso pode parecer estranho, mas tenha paciência. Esse objeto contador será um objeto de chave/valor, não JSON, com o valor sendo um número inteiro. Há uma operação de contador nos SDKs do Couchbase especificamente para esse tipo de objeto, que é muito eficiente e oferece recursos rápidos de leitura e gravação para manter a consistência. É uma operação única e atômica nos SDKs do Couchbase, portanto é muito fácil e rápida de usar. Aqui está um exemplo da versão node.js na documentação. No nosso caso, esse contador será incrementado toda vez que adicionarmos um novo evento. Como cada tipo de evento e hora tem seu próprio contador, podemos ler facilmente quantos eventos existem e esse número se torna o limite superior de uma matriz se precisarmos ler todos os eventos desse tipo e hora.

A outra parte importante é a chave do objeto. Queremos escolher uma chave para que o aplicativo possa construir facilmente as chaves necessárias e, em seguida, coletar os dados por chave para exibir o número de eventos, mas também os eventos para o período de tempo determinado. A busca de objetos por chave sempre será mais rápida do que a consulta. É a diferença entre já saber a resposta e ter de fazer uma pergunta para recuperar os dados que são a resposta. Ao saber a chave, você simplesmente diz ao banco de dados para recuperar os dados. Simples, eficaz e muito rápido.

Aqui está um exemplo da chave/valor do contador:

Chave do objeto:

Um exemplo de ObjectID seria:
Valor: 293

Onde 293 é o valor do incremento mais recente do contador.

Para o registro de data e hora na chave, usei o ano de quatro dígitos, um mês de dois dígitos, o dia e, em seguida, a hora (em 24 horas). Não precisei ir até o nível do minuto ou do segundo, mas você poderia. Eu também poderia ter usado um carimbo de data/hora UNIX, o que também funcionaria, mas, novamente, isso era desnecessariamente granular para esse caso de uso específico.

No exemplo acima, 2015 é o ano, fevereiro é o mês, 20 é o dia e 4pm é a hora. Portanto, se você quisesse ler todos os contadores de um tipo de evento e de um dia específico, o aplicativo poderia facilmente reunir os objectIDs desses contadores e lê-los em massa.

Outra coisa: eu uso dois pontos duplos como delimitador, mas você pode usar o que fizer sentido.

O objeto de evento

Para cada objeto de evento, a ID do objeto seria algo parecido com o seguinte:


Onde 293 é o valor do incremento mais recente do objeto contador para essa hora

Com esse esquema, para recuperar a contagem de itens para esse tipo de evento em uma hora específica, basta ler um objeto operacional e pronto.

Em termos simples, o valor do contador é o limite superior dos objetos desse tipo de evento. Se você quisesse os últimos 10 eventos desse tipo de evento por uma hora, leria esse contador, subtrairia 9 e, em seguida, faria uma leitura em massa paralela no Couchbase para os seguintes objetos:

Portanto, você pode ler todos os 10 desses eventos muito rapidamente e sem consultas, índices ou exibições, apenas com velocidade bruta por meio de leitura em massa paralelizada. Uma leitura em massa dos objetos listados seria MUITO rápida no Couchbase, mesmo que você tivesse mais de 300 deles.

O único pequeno problema com essa abordagem é que é possível, embora muito improvável, que essa contagem se torne inconsistente com o objeto de contagem real. Por exemplo, alguém poderia iterar o objeto contador, mas não criar um documento de evento com esse objeto. Dito isso, se você estiver usando operações em massa e elas solicitarem um objeto que não existe, elas simplesmente receberão uma falha e a operação inteira não sofrerá com isso. Na minha opinião, essa é uma boa troca, considerando o desempenho que um modelo como esse pode atingir. Se você descobrir uma maneira melhor, publique nos comentários, pois eu adoraria saber.

O código do aplicativo

Vamos dar uma olhada em como o código do aplicativo pode ser definido para ler e gravar esse modelo de objeto. Vou usar pseudocódigo para não entrar especificamente em uma linguagem específica. Deixarei os detalhes para a linguagem e o SDK do Couchbase de sua preferência.

Resumo

Ao usar a série de técnicas de modelagem de objetos descritas acima, é possível estruturar os dados de forma a maximizar a taxa de transferência e o desempenho. Embora talvez inicialmente não seja intuitivo, o uso de pesquisas adicionais de chave/valor em vez de consultas baseadas em índices secundários para a funcionalidade primária do aplicativo pode trazer benefícios significativos. Em muitos sistemas, uma pesquisa complexa baseada em índice pode levar uma ordem de magnitude a mais para ser concluída do que as pesquisas simples de chave-valor usadas neste projeto. Na arquitetura correta do sistema, o Couchbase pode facilmente fornecer um tempo de resposta consistente de menos de milissegundos para essas pesquisas. Então, quando você precisar de poder para realmente consultar, use o N1QL. Você pode escolher onde utilizar o poder que o Couchbase lhe oferece.

Além disso, devido à arquitetura de fragmentação automática do Couchbase, a carga das consultas e da ingestão será distribuída uniformemente pelo cluster. À medida que o uso do aplicativo e a demanda de operações aumentam ao longo do tempo, nós adicionais do Couchbase podem ser adicionados para expandir em uma operação on-line, atendendo à demanda sem nenhuma alteração na camada do aplicativo.

Post Script sobre consultas

Uma última coisa, se você chegou até aqui. Você pode estar dizendo, mas tudo isso e eu não estou consultando o banco de dados. Por que não está usando o N1QL? Eu não disse que, nesse caso de uso, eu não usaria o N1QL e nada nos impede de usar o N1QL nesses documentos. A maneira como vejo o N1QL é que ele é mais uma ferramenta na caixa de ferramentas para interagir com o Couchbase. O acesso a chave/valor SEMPRE será mais rápido. É assim que as coisas são. Portanto, o que eu promovo às pessoas é usar o poder e a flexibilidade que o Couchbase oferece para obter o desempenho e a funcionalidade de que preciso, onde e quando preciso. Isso será uma combinação de chave/valor, visualizações tradicionais do Couchbase, índices secundários globais (GSI) e N1QL.

Nesse caso de uso específico, preciso ser capaz de gravar dados em uma velocidade muito alta, ter uma maneira de procurar apenas alguns dos dados de uma forma muito específica e dimensionar a camada de dados linearmente para lidar com isso com complexidade mínima. Key/Value fez isso para mim com o padrão de chave de objeto correto. Nada me impede de usar o N1QL para consultar esses eventos ou registros de como projetamos esse esquema. Observe que eu não falei muito sobre a modelagem de objetos de documentos JSON em si. Para o que estou tentando mostrar, isso não importa e, quanto à consulta, eu simplesmente não precisava dessa ferramenta.

Dito isso, no próximo blog sobre esse modelo de objeto, vou me aprofundar em como podemos analisar esse mesmo evento com N1QL e GSI quando fizer sentido.

Autor

Postado por Kirk Kirkconnell, engenheiro de soluções sênior, Couchbase

Kirk Kirkconnell foi engenheiro de soluções sênior da Couchbase, trabalhando com clientes em várias capacidades para ajudá-los a arquitetar, implantar e gerenciar o Couchbase. Sua experiência é em operações, hospedagem e suporte de infraestruturas de aplicativos e bancos de dados em larga escala.

Deixar uma resposta