libmembase - uma interface C para o Membase

O Membase é compatível "on the wire" com qualquer servidor memcached se você se conectar ao servidor porta padrão do memcached (registrada por mim em 2009), de modo que você deve conseguir acessar o membase com qualquer cliente "memcapable". O suporte a essa porta é o nosso proxy de membase chamado moxi e, nos bastidores, ele fará a autenticação SASL e o proxy de suas solicitações para o servidor de membase correto que contém o item que você deseja. Um dos aspectos que diferem o Membase do Memcached é que armazenamos cada item em um determinado vbucket que é mapeado para um servidor. Quando você aumentar ou diminuir o cluster, o membase moverá os vbuckets para novos servidores.

Não existe almoço grátis, portanto, acessar o membase por meio do moxi "custa" mais do que falar diretamente com os nós individuais. Gostamos de nos referir a esses clientes como "clientes inteligentes". Como desenvolvedor do Memcached, preciso testar várias coisas, então fui em frente e criei um protótipo rápido dessa biblioteca para facilitar meus testes. Inicialmente, eu queria estender a libmemcached com essa funcionalidade, mas isso parecia ser uma mudança grande (e arriscada) que eu não tinha coragem de fazer naquele momento.

O estado atual da biblioteca está longe da qualidade de produção e com uma lista mínima de recursos compatíveis. Então, por que anunciá-la agora? Bem, acho que não terei tempo para implementar tudo sozinho, então espero que as pessoas se juntem a mim para adicionar recursos à biblioteca quando precisarem de algo que não esteja lá...

Projetei a biblioteca para ser baseada em callback 100% e integrada à libevent, facilitando a conexão com o seu aplicativo.

Então, digamos que você queira criar um fluxo TAP e ouvir todas as modificações que ocorrem em seu cluster. Tudo o que você precisa fazer é:

struct event_base *evbase = event_init();

libmembase_t instance = libmembase_create(host, username, passwd, bucket, evbase);
libmembase_connect(instance);

libmembase_tap_filter_t filter;
libmembase_callback_t callbacks = {
.tap_mutation = tap_mutation
};
libmembase_set_callbacks(instance, &callbacks);
libmembase_tap_cluster(instance, filter, true);

Em seguida, você implementaria a função de retorno de chamada do tap como:

static void tap_mutation(libmembase_t instance, const void *key, size_t nkey, const void
*data, size_t nbytes, uint32_t flags, uint32_t exp, const void *es, size_t nes)
{
// Faça o que quiser com o objeto
}

E isso é tudo o que você precisa fazer para acessar todo o seu cluster :-) Vamos estender o exemplo para o tap múltiplos do mesmo código.

struct event_base *evbase = event_init();

libmembase_t instance1 = libmembase_create(host, username, passwd, bucket1, evbase);
libmembase_t instance2 = libmembase_create(host, username, passwd, bucket2, evbase);
libmembase_connect(instance1);
libmembase_connect(instance2);

libmembase_tap_filter_t filter;
libmembase_callback_t callbacks = {
.tap_mutation = tap_mutation
};
libmembase_set_callbacks(instance1, &callbacks);
libmembase_set_callbacks(instance2, &callbacks);
libmembase_tap_cluster(instance1, filter, false);
libmembase_tap_cluster(instance2, filter, false);

event_base_loop(evbase, 0);

O identificador da instância é passado para a função de retorno de chamada, portanto, você deve ser capaz de saber a qual balde pertence cada evento de mutação.

Como eu disse, todas as funções da API são baseadas em callback, portanto, se você quiser recuperar um objeto, deverá registrar um callback para obter antes de chamar libmembase_mget. Ex:

libmembase_callback_t callbacks = {
.get = get_callback
};
libmembase_set_callbacks(instance, &callbacks);
libmembase_mget(instance, num_keys, (const void * const *)keys, nkey);// Se você não quiser executar seu próprio loop de eventos, poderá chamar o seguinte método
// que executará todos os comandos em spool e aguardará suas respostas antes de interromper
// do loop de eventos
libmembase_execute(instance);

A assinatura do retorno de chamada get tem a seguinte aparência:

void get_callback(libmembase_t instance, libmembase_error_t error, const void *key,
size_t nkey, const void *bytes, size_t nbytes, uint32_t flags, uint64_t cas)
{
// faça o que você quiser...
}

Então, o que está faltando na biblioteca neste momento?

- Tratamento adequado de erros. No momento, estou usando asserts e abort() para lidar com situações de erro, fazendo com que seu aplicativo trave... você não quer isso em produção ;-)
- Tempo limite. No momento, o tempo limite só será atingido em tempos limite de TCP.
- Muitas operações! Estou apoiando apenas o get/add/replace/set...
- Buscar réplicas.
- Tratar graciosamente as alterações na lista do vbucket
- +++

Você tem vontade de invadir alguns deles?

Para saber mais sobre onde obter e compilar a libmemcached, clique aqui.

Compartilhe este artigo
Receba atualizações do blog do Couchbase em sua caixa de entrada
Esse campo é obrigatório.

Autor

Postado por Trond Norbye, desenvolvedor sênior, Couchbase

Trond Norbye é arquiteto de software na Couchbase. Principal colaborador dos projetos Couchbase e Memcached. Criou as bibliotecas de clientes C/C++ e node.js do Couchbase.

Deixe um comentário

Pronto para começar a usar o Couchbase Capella?

Iniciar a construção

Confira nosso portal do desenvolvedor para explorar o NoSQL, procurar recursos e começar a usar os tutoriais.

Use o Capella gratuitamente

Comece a trabalhar com o Couchbase em apenas alguns cliques. O Capella DBaaS é a maneira mais fácil e rápida de começar.

Entre em contato

Deseja saber mais sobre as ofertas do Couchbase? Deixe-nos ajudar.