Sin categoría

libmembase - interfaz en C para Membase

Membase es compatible "on the wire" con cualquier servidor memcached si te conectas a la aplicación puerto memcached estándar (registrado por mí en 2009), por lo que deberías poder acceder a membase con cualquier cliente "memcapable". Respaldando este puerto está nuestro proxy de membase llamado moxi, y detrás de escena hará la autenticación SASL y enviará tus peticiones al servidor de membase correcto que contenga el elemento que quieres. Una de las cosas que diferencia a Membase de Memcached es que almacenamos cada elemento en un determinado vbucket que se asigna a un servidor. Cuando crezca o se reduzca el clúster, membase moverá los vbuckets a los nuevos servidores.

No hay nada gratis, así que acceder a membase a través de moxi "cuesta" más que hablar directamente con los nodos individuales. Nos gusta referirnos a estos clientes como "clientes inteligentes". Como desarrollador en Memcached necesito probar varias cosas, así que me adelanté y hackeé un prototipo rápido de tal biblioteca para facilitar mis pruebas. Inicialmente quería extender libmemcached con esta funcionalidad, pero eso parecía ser un gran (y arriesgado) cambio que no tenía las agallas para hacer en ese momento.

El estado actual de la biblioteca está lejos de la calidad de producción, y con una lista mínima de funciones compatibles. ¿Por qué anunciarlo ahora? Bueno, no creo que encuentre tiempo para implementarlo todo yo mismo, así que espero que la gente se una a mí para añadir características a la biblioteca cuando necesiten algo que no esté ahí...

He diseñado la biblioteca para ser 100% callback basado e integrado con libevent, por lo que es fácil para usted para conectarlo a su aplicación.

Digamos que quieres crear un flujo TAP y escuchar todas las modificaciones que ocurran en tu cluster. Todo lo que necesitas hacer sería:

struct event_base *evbase = event_init();

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

libmembase_tap_filter_t filter;
libmembase_callback_t callbacks = {
.tap_mutation = tap_mutación
};
libmembase_set_callbacks(instancia, &callbacks);
libmembase_tap_cluster(instancia, filtro, true);

A continuación, se implementaría la función de devolución de llamada del grifo 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)
{
// Haz lo que quieras con el objeto
}

Y eso es todo lo que necesitas hacer para aprovechar todo tu cluster :-) Ampliemos el ejemplo para aprovechar varios cubos del mismo 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(instancia1);
libmembase_connect(instancia2);

libmembase_tap_filter_t filter;
libmembase_callback_t callbacks = {
.tap_mutation = tap_mutación
};
libmembase_set_callbacks(instancia1, &callbacks);
libmembase_set_callbacks(instancia2, &callbacks);
libmembase_tap_cluster(instancia1, filtro, falso);
libmembase_tap_cluster(instancia2, filtro, falso);

event_base_loop(evbase, 0);

El manejador de instancia se pasa a la función de llamada de retorno, por lo que deberías ser capaz de saber a qué cubo pertenece cada evento de mutación.

Como ya he dicho, todas las funciones de la API se basan en retrollamadas, por lo que si quieres recuperar un objeto tienes que registrar una retrollamada para consiga antes de llamar a libmembase_mget. Ex:

libmembase_callback_t callbacks = {
.get = get_callback
};
libmembase_set_callbacks(instancia, &callbacks);
libmembase_mget(instance, num_keys, (const void * const *)keys, nkey);// Si no desea ejecutar su propio bucle de eventos, puede llamar al siguiente método
// que ejecutará todos los comandos en cola y esperará sus respuestas antes de salir
// del bucle de eventos
libmembase_execute(instancia);

La firma para la llamada de retorno get tiene el siguiente aspecto:

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)
{
// haz lo que quieras...
}

¿Qué le falta a la biblioteca en estos momentos?

- Manejo adecuado de errores. Ahora mismo estoy usando asserts y abort() para manejar situaciones de error, causando que tu aplicación se cuelgue... no quieres eso en producción ;-)
- Tiempos de espera .. En este momento sólo se agotará el tiempo de espera TCP.../
- ¡Muchas operaciones! Sólo apoyo get/add/replace/set...
- Buscar réplicas ..
- Manejar con gracia el cambio en la lista vbucket
- +++

¿Te apetece hackear algunos de ellos?

Para más información sobre dónde obtener y compilar libmemcached, haga clic aquí.

Comparte este artículo
Recibe actualizaciones del blog de Couchbase en tu bandeja de entrada
Este campo es obligatorio.

Autor

Publicado por Trond Norbye

Trond Norbye es Arquitecto de Software en Couchbase. Colaborador principal de los proyectos Couchbase y Memcached. Creó las bibliotecas de cliente C/C++ y node.js de Couchbase.

Deja un comentario

¿Listo para empezar con Couchbase Capella?

Empezar a construir

Consulte nuestro portal para desarrolladores para explorar NoSQL, buscar recursos y empezar con tutoriales.

Utilizar Capella gratis

Ponte manos a la obra con Couchbase en unos pocos clics. Capella DBaaS es la forma más fácil y rápida de empezar.

Póngase en contacto

¿Quieres saber más sobre las ofertas de Couchbase? Permítanos ayudarle.