Primero, las noticias. Acabo de publicar un versión candidata de spymemcached 2.6. El actual versión preliminar del cliente Membase vbucket aware también se basa en ese código.
Así que novedades en 2.6? Hay una serie de mejoras en el rendimiento, el transcodificador y la gestión del tiempo de espera, pero el gran cambio está en la gestión del tiempo de espera.
Ha habido bastantes comentarios y publicaciones sobre el problema número 136 de spymemcached. De los informes de errores en el espía 136, varias personas están ejecutando aplicaciones y viendo una RuntimeException de la MemcachedClient get(). Esta es una llamada a un método muy sencillo para el consumidor y por lo tanto es muy común, pero hay algo de trabajo complejo por debajo para optimizar cómo se utiliza spymemcached. Permítanme explicar un poco más.
Técnicamente hablando, nada en spymemcached se hace de forma síncrona. Cuando se hace una llamada al método get() que parece ser síncrono, usamos las APIs de concurrencia de Java para hacer que su obtención parezca síncrona ejecutando la operación a través de las mismas colas de escritura asíncronas para una conexión dada usando un latch de cuenta atrás con un tiempo de espera por defecto para dejar que la operación fluya a través del sistema, sea atendida y respondida muy rápidamente. Siendo realistas, la mayoría de estas operaciones se realizan en cuestión de unos pocos milisegundos a un microsegundo.
Dicho esto, todavía hay algunas situaciones que pueden surgir cuando se ejecuta
a) como aplicación de espacio de usuario
b) en un sistema ocupado
c) en una red ocupada o wibbily
d) en una JVM, debido a la recolección de basura o a actividades JIT
Muchos de ellos pueden controlarse en gran medida con cierto esfuerzo, pero no pueden eliminarse por completo. Esto significa que el código debería estar siempre preparado para recibir timeouts ocasionales. De forma equivalente, spymemcached debería tratar de recuperarse lo más rápidamente posible de la condición de timeout.
Dicho esto, cuando estaba investigando el tema del espía 136, surgieron algunas cosas.
Mike Wiederhold había notado que a veces veía una retransmisión TCP. Investigando un poco más, descubrió que el tiempo por defecto antes de una retransmisión es de 1 segundo. Bueno, con nuestro tiempo de espera por defecto en el pestillo en 1 segundo, esto significaba que cualquier retransmisión TCP causaría un tiempo de espera. Con la nube y los despliegues virtualizados de hoy en día, algunos de los cuales se sabe que están en redes sobre-suscritas, es probable que surja de vez en cuando. La solución simple es aumentar el tiempo de espera por defecto. Esto no es algo que hice a la ligera, pero creo que es lo correcto.
Algunas de nuestras pruebas de carga con Membase golpea esto. En memcachetest (un probador de estrés de juguete, no un cliente real) Sé que Membase maneja fácilmente decenas de miles a cientos de miles de operaciones por segundo, dependiendo de los sistemas en uso.
Empecé a buscar cosas que impidieran la recuperación, dado que muchos de los informes de errores apuntaban a un fallo en la recuperación. Resulta que el mecanismo que implementa el tiempo de espera síncrono no hace nada para evitar que ese elemento se escriba en el objeto MemcachedNode al que está designado.
En otras palabras, nuestro hilo que se ocupaba del nodo no estaba prestando suficiente atención al tiempo de una operación determinada.
Pensándolo en términos de una sola operación en una circunstancia, si el buffer para enviar datos a la red está lleno porque está realmente ocupado o hay una interrupción momentánea, no hay nada que impida a otros hilos amontonar más operaciones en ese MemcachedNode. Esas operaciones expirarán en la hebra que las llama, pero seguirán siendo enviadas a través de la red. Esto extenderá el efecto de esa interrupción momentánea hasta que se trabaje en la acumulación de cosas que no se utilizarán. Con un servidor realmente saturado, puede que nunca se recupere.
Con los cambios de código en la versión candidata 2.6, ahora nos protegemos incluso contra el envío de una operación que ha expirado. Ya he recibido buenos comentarios y ha ayudado a limpiar las cosas para las pruebas de Membase, pero con proyectos tan ampliamente distribuidos como spymemcached, memcached y Membase, es bueno obtener algunos comentarios del mundo real. Si está utilizando spymemcached existente, por favor, darle una oportunidad y hágamelo saber.