Nota de março de 2017: informações detalhadas sobre o ônibus do evento e a coleta de métricas podem ser encontradas no documentação oficial. Algumas informações deste artigo podem estar desatualizadas.
Enquanto a Europa estava derretendo no calor do verão, Simon (de Paris), Sergey (de Minsk) e I (de Viena) reutilizou o calor e preparou uma nova versão para você. É a segunda prévia para desenvolvedores da próxima versão 2.2.0. Além das correções de bugs (que também foram incluídas na versão 2.1.4), ela traz os seguintes aprimoramentos e novos recursos
- Suporte estendido para N1QL e escalonamento multidimensional (MDS)
- Aprimoramentos das APIs Sync e Async
- Aprimoramentos de suporte com métricas
- Diversas atualizações de dependências e alterações no DCP
Veja como você pode obtê-lo agora mesmo:
https://gist.github.com/daschl/5b32706a0a4fe50cfaa4.js
Suporte estendido a N1QL e MDS
A funcionalidade do N1QL DSL foi ampliada para suportar uma variedade de funções N1QL, incluindo (mas não se limitando a) funções de agregação, matriz, comparação, data, meta, correspondência de padrões e string. Todas essas funções estão localizadas no namespace "com.couchbase.client.java.query.dsl.functions" e devem ser importadas como métodos auxiliares estáticos por conveniência.
Como o Multi-Dimensional Scaling também afeta os buckets do Memcached (nem todo nó precisa ser um nó de dados), o SDK agora garante automaticamente que apenas esses nós de dados sejam usados no algoritmo de hashing ketama. Isso é totalmente transparente para o usuário, mas é importante escolher a versão 2.2.0 ou posterior se quiser usar o Couchbase Server 4.0 com MDS e buckets memcached. O SDK 1.4.x não é afetado e continuará funcionando sem problemas.
Por fim, para garantir que todas as APIs sejam consistentes, optamos por renomear as consultas "parametrizadas" para "parametrizadas", que é considerada a forma correta na documentação do Couchbase e nas APIs do SDK.
Aprimoramentos das APIs Sync e Async
Uma das armadilhas comuns da API assíncrona é que os Observables retornados eram "quentes" em vez de "frios". Isso tem implicações sutis na semântica de repetição e na reutilização. Especialmente se quiser usar o operador de repetição, você precisa "adiar" o observável retornado para que, a cada nova assinatura, um novo observável seja gerado. Na versão 2.2.0, decidimos tornar todas as chamadas de API frias, envolvendo-as para você imediatamente. O código existente continuará funcionando, e até mesmo os adiamentos duplos não causarão nenhum dano.
Compare esse código de repetição com 2.1.4:
https://gist.github.com/daschl/0666841cb2bd69e53d17.js
com o ligeiramente mais simples em relação ao 2.2.0:
https://gist.github.com/daschl/2b63c5193bac4dd11713.js
Como as chamadas getFromReplica servem como uma maneira de tratar a disponibilidade em detrimento da consistência, muitas vezes faz sentido pegar apenas os primeiros N documentos que são retornados. Embora isso seja muito fácil de fazer na API assíncrona com o operador "take()", a API síncrona só expunha uma versão em lista. Para torná-la mais flexível para os usuários que trabalham com a API de bloqueio, foram adicionadas novas sobrecargas que agora retornam um Iterator. Se você se importa apenas com o primeiro documento retornado, veja como fazer isso:
https://gist.github.com/daschl/0c7c92642d8c0af7dae3.js
Anteriormente, não era possível falhar em uma operação de contador se o documento não existisse - ele era sempre inicializado com 0. Como esse recurso estava disponível na série 1.x, decidimos trazê-lo de volta à sobrecarga do método em que nenhum valor padrão é especificado.
Portanto, na versão 2.2.0, essa sobrecarga de método "Observable counter(String id, long delta)" falhará com uma "DocumentDoesNotExistException" se o documento não existir. Se você quiser o comportamento anterior, basta usar a sobrecarga com o valor inicial e defini-lo como 0.
Por fim, o SDK agora oferece suporte a mais opções de configuração de ambiente (incluindo a configuração de TCP_NODELAY) e os documentos de design agora podem ser configurados com opções na criação. Veja como você pode criar um documento de design e alterar o intervalo mínimo de atualização padrão:
https://gist.github.com/daschl/ddec1089eed01285d0c4.js
Aprimoramentos de suporte com métricas
Uma pergunta comum que os desenvolvedores e os operadores se fazem é: o que está acontecendo no meu aplicativo? E também, muitas vezes, relacionada: por que recebo uma TimeoutException? Estamos depurando implantações de produção há alguns anos e aprendemos algumas coisas ao fazer isso. Uma das coisas mais importantes são as informações. Quanto mais informações você conseguir obter do seu aplicativo, melhor poderá entendê-lo.
Exatamente por esse motivo, adicionamos métricas de latência e tempo de execução sempre ativas ao SDK, que são publicadas no barramento de eventos e podem ser consumidas como mensagens. Há uma grande diferença entre apenas registrar coisas ou realmente expô-las em um barramento de eventos (mesmo que elas também sejam registradas posteriormente). Ele permite que você o consuma e, o que é mais importante, reaja a ele instantaneamente. Você pode pegar os dados e enviá-los ao seu sistema de monitoramento favorito, como nagios, graphite ou logstash. Não há necessidade de analisar os arquivos de log após uma interrupção do sistema que você tem uma equipe para analisar.
Por padrão, o SDK coletará de forma transparente as latências das operações executadas por ele e as gravará no barramento de eventos a cada hora. O intervalo de emissão, bem como muitas outras configurações, são totalmente personalizáveis por meio do ambiente. Aqui está um exemplo simples que escuta o barramento de eventos e imprime apenas eventos de métrica no stderr (estamos distribuindo muito mais eventos do que aqueles no barramento para oferecer o máximo de flexibilidade):
https://gist.github.com/daschl/51e5193a57d909fd072b.js
Você pode identificar dois eventos aqui. O primeiro imprime informações de tempo de execução, como estatísticas de GC, memória e uso de thread. O outro é um pouco maior e contém estatísticas de latência (e taxa de transferência) coletadas em histogramas internos. As informações impressas contêm latências mínimas e máximas, o número de operações, bem como percentis. Por baixo dos panos, estamos usando o excelente HdrHistograma e o pacote LatencyUtils relacionado.
Observe como ele não apenas imprime o resultado por operação, mas você pode identificar o nó de destino, bem como o código de status no retorno. Isso permite que você crie uma forma de árvore do estado do sistema e obtenha informações sobre o desempenho de nós ou serviços individuais (o nó A é mais lento do que os outros, a substituição é mais rápida do que a inserção, muitos erros contra o nó B,...).
Com base no feedback dos usuários, estamos pensando em adicionar consumidores prontos para registrar essas métricas e enviá-las ao graphite ou ao logstash. Além disso, adicionaremos formatos de saída mais sofisticados, incluindo JSON bem formatado, que pode ser analisado por humanos e máquinas. Informe-nos qual formato de destino você gostaria de ver incorporado ao driver.
Atualizações de dependências e alterações de DCP
Como estamos atualizando a versão secundária, também estamos atualizando as dependências para suas versões mais recentes de correção de bugs. Aqui está a lista completa de dependências, mas lembre-se de que, na verdade, só expomos o RxJava como uma dependência explícita; todas as outras são reempacotadas para não causar problemas em seu ambiente se houver possíveis versões conflitantes.
Aqui estão as alterações da versão 2.2.0-dp2 em relação à 2.1.4:
- RxJava da versão 1.0.4 para a 1.0.13
- Netty de 4.0.25.Final para 4.0.29.Final
- LMAX Disruptor 3.3.0 a 3.3.2
- Jackson da versão 2.4.2 para a 2.5.4
- LatencyUtils novo na versão 2.0.2
Além disso, Sergey está ocupado trabalhando na ampliação do Kafka Connector, o que também resultou em aprimoramentos do DCP na biblioteca core-io. Ele ainda é bastante experimental, mas estamos nos aproximando de um ponto em que pode ser consumido por um público mais amplo.
O caminho para a GA
Outro recurso do N1QL que ainda está em fase de incubação são as declarações preparadas (nomeadas). O código foi atualizado nesta segunda visualização para desenvolvedores, mas ainda está sujeito a alterações, por isso comentamos essa API por enquanto. Seja paciente até chegarmos ao GA para obter suporte completo e documentação abrangente.
Além disso, não há mais recursos importantes na lista de tarefas para a versão 2.2.0, portanto, estamos mudando a marcha para correções menores, aprimoramentos de estabilidade e, principalmente, documentação. Para que esta seja a melhor versão que já lançamos até agora, precisamos da sua opinião! Experimente e dê seu feedback, especialmente sobre os novos recursos e o suporte ao N1QL. Diga-nos o que está faltando ou quebrado por meio de um comentário aqui, nos fóruns ou no rastreador de bugs!