Explore Message Brokers – Blog de rendimiento de base de datos de Percona

Agentes de mensajes no se cubren regularmente aquí, pero son, sin embargo, tecnologías importantes en la web. Hace algún tiempo, uno de nuestros clientes me pidió que revisara una selección de corredores de mensajes OSS y ofreciera un par de buenos candidatos. Los requisitos eran bastante simples: comportarse bien cuando hay una gran acumulación de mensajes, poder crear un clúster y, en caso de falla de un nodo en un clúster, tratar de proteger los datos, pero nunca bloquear a los editores, incluso si podría implicar. datos perdidos Nada bueno sobre la gestión de archivos y temas. Decidí escribir aquí mis hallazgos antes de que se me olvide…

No me considero un especialista en mensajería y solo dediqué uno o dos días a cada uno, por lo que podría haber cometido algunos errores de configuración importantes de manera inteligente. Asumo la culpa si algo está mal configurado o no se usa correctamente.

RabbitMQ es un corredor de mensajería muy conocido y popular y tiene muchas características poderosas. La documentación en el sitio web de RabbitMQ es excelente y hay varios libros disponibles. RabbitMQ está escrito en Erlang, un lenguaje de programación no muy utilizado, pero muy adecuado para este tipo de tareas. La empresa Pivotal desarrolla y mantiene RabbitMQ. He actualizado a la versión 3.2.2 en servidores CentOS 6.

La instalación fue fácil, instalé la versión Erlang R14B de epel y RabbitMQ rpm. El único problema que tuve fue que el servidor estaba esperando que se resolviera «127.0.0.1» en /etc/hosts y faltaban las máquinas virtuales openstack que usaba. Fácil de reparar. También instalé y activé el complemento de administración.

La configuración de RabbitMQ está instalada en el archivo rabbitmq.config y tiene toneladas de parámetros ajustables. Usé los valores predeterminados. En cuanto a la API del cliente, RabbitMQ admite una larga lista de idiomas y ciertos protocolos estándar, como STOMP, están disponibles con un complemento. Las colas y los temas se pueden crear desde la interfaz web o directamente a través de la API del cliente. Si tiene más de un nodo, se pueden agrupar y luego las filas y los temas se pueden replicar en otros servidores.

Creé la fila 4, escribí un cliente Ruby y comencé a insertar mensajes. Tuve una velocidad de liberación de alrededor de 20k/s con múltiples subprocesos, pero tuve algunas paradas causadas por vm_memory_high_watermark, según tengo entendido durante esas paradas escribiendo en el disco. No es exactamente fantástico dadas mis necesidades. Además, una parte aún se almacena en la memoria, incluso si una fila es duradera, por lo que, aunque tenía mucho espacio en el disco, el uso de la memoria aumentó y finalmente alcanzó el parámetro vm_memory_high_watermark. La carga de la CPU fue bastante alta durante la carga, entre un 40 % y un 50 % en una máquina virtual de 8 núcleos.

Aunque no se cumplieron mis necesidades, instalé una fila replicada en los nodos 2 e inserté algunos millones de objetos. Eliminé uno de los dos nodos y las inserciones fueron aún más rápidas, pero luego… cometí un error. Reinicié el nodo y pedí una resincronización. O no lo configuré correctamente o la resincronización está mal implementada, pero tardó una eternidad en resincronizarse y se ralentizó a medida que avanzaba. Con un 58 % de finalización, estuvo funcionando a las 5 p. m., un subproceso al 100 %. Mi paciencia se ha agotado.

Tantas características, rendimiento decente pero comportamiento no compatible con los requisitos.

Kafka fue concebido originalmente por LinkedIn, está escrito en Java y ahora está bajo el paraguas del proyecto Apache. A veces miras una tecnología y simplemente dices, wow, esto realmente se hace como debería ser. Al menos podría decir eso para el propósito que tenía. Lo que es tan especial de Kafka es la arquitectura, mantiene los mensajes en archivos planos y los consumidores exigen mensajes basados ​​en una compensación. Piense en esto como un servidor MySQL (productor) que guarda mensajes (actualiza SQL) en sus binlogs y los esclavos (consumidores) solicitan mensajes en función de una compensación. El servidor es bastante sencillo y no importa mucho a los consumidores. Esta simplicidad lo hace súper rápido y tiene pocos recursos. Los mensajes antiguos se pueden conservar en función del tiempo (como expire_logs_days) y/o en función del uso del almacenamiento.

Entonces, si el servidor no realiza un seguimiento de lo que se ha consumido en cada tema, ¿cómo puede tener múltiples consumidores? El elemento que falta aquí es Zookeeper. El servidor Kafka usa Zookeeper para la agrupación y el enrutamiento, mientras que los consumidores también pueden usar Zookeeper u otra cosa para la sincronización. El cliente de muestra proporcionado con el servidor utiliza Zookeeper para poder iniciar varias instancias y sincronizarlas automáticamente. Para aquellos que no están familiarizados con Zookeeper, es un sistema de almacenamiento distribuido síncrono ampliamente disponible. Si conoce Corosync, proporciona algunas de las mismas funciones.

Característica sabia Kafka, no es tan bueno. No hay una interfaz web integrada, aunque algunas están disponibles en el ecosistema. El enrutamiento y las reglas no existen y las estadísticas son solo con JMX. Pero, el rendimiento… Alcancé una velocidad de 165k mensajes/s en un solo hilo, no me preocupé por sintonizar más. El consumo era esencialmente un disco atado al servidor, 3M mensajes/s… increíble. Fue sin la coordinación de Zookeeker. El uso de memoria y CPU fue modesto.

Para probar la agrupación en clústeres, creé una cola replicada, inserté algunos mensajes, firmé una réplica, inserté algunos millones de mensajes y reinicié la réplica. Solo me tomó unos segundos volver a sincronizar.

Por lo tanto, Kafka es muy adecuado para los requisitos, rendimiento estelar, bajo uso de recursos y agradable con los requisitos.

ActiveMQ es otro gran jugador en el campo con un impresionante conjunto de características. ActiveMQ está más en la liga RabbitMQ que Kafka y, como Kafka, está escrito en Java. Se puede proporcionar HA desde el backend de almacenamiento, levelDB admite la replicación, pero tuve algunos problemas. Mis requisitos no son que la alta disponibilidad esté completa, solo garantizar que los editores nunca se bloqueen, por lo que abandoné la replicación de back-end de almacenamiento en favor de una red de intermediarios.

Mi entendimiento de la red de corredores es que se conecta a uno de los miembros y publica o consume un mensaje. Si no sabe en qué nodo(s) se encuentra la cola, el intermediario que se conecta conoce y atiende su solicitud. Para obtener más ayuda, puede especificar todos los intermediarios en la cadena de conexión y la biblioteca del cliente solo se conecta a otro si el que está conectado falla. Se ve lo suficientemente bueno para las necesidades.

Con la configuración de malla de corredores, tuve una tasa de inserción de aproximadamente 5000 msg / s en 15 subprocesos y solo un consumidor pudo leer 2000 msg / s. Lo dejé correr por un tiempo y recibí 150 millones de mensajes. Sin embargo, en este punto, perdí la interfaz web y la velocidad de publicación fue mucho más lenta.

Entonces, una gran bestia, muchas funciones, un rendimiento decente, al final con los requisitos.

Kestrel es otro bróker interesante, esta vez más parecido a Kafka. Escrito en escala, el corredor Kestrel habla el protocolo memcached. En la parte inferior, la clave se convierte en el nombre de la fila y el asunto es el mensaje. Kestrel es muy simple, los archivos se definen en un archivo de configuración, pero puede especificar, por fila, límites de almacenamiento, caducidad y comportamiento cuando se alcanzan los límites. Con una configuración como «discardOldWhenFull = true», mi requisito de nunca bloquear editores se entiende fácilmente.

En términos de agrupamiento, Kestrel es un poco limitado, pero cualquiera puede publicar su disponibilidad en Zookeeper para que los editores y consumidores puedan estar informados de un servidor reparado y faltante. Por supuesto, si tiene varios servidores Kestrel con la misma cola definida, los consumidores deberán consultar a todos los corredores para transmitir el mensaje y el orden estricto puede ser un poco difícil.

En términos de rendimiento, algunos scripts bash simples que usan nc para publicar mensajes alcanzan fácilmente 10k mensajes/s, lo cual es muy bueno. La tarifa es estática en el tiempo y probablemente limitada por la reconexión de cada mensaje. La presencia de los consumidores reduce ligeramente la tarifa de publicación, pero nada drástico. El único problema que tuve fue cuando caducó una gran cantidad de mensajes, el servidor se congeló durante un tiempo, pero fue porque olvidé configurar maxExpireSweep en algo así como 100 y todos los mensajes se eliminaron en un solo paso.

Entonces, bastante buena impresión en Kestrel, simple pero funciona bien.

Conclusiones

Para las necesidades planteadas por el cliente, Kafka encajaba perfectamente. Ofrece una alta garantía de que el servicio estará disponible y de forma gratuita en cualquier circunstancia. Además, los mensajes se pueden replicar fácilmente para una mayor disponibilidad de datos. El desempeño de Kafka es excelente y su uso de recursos es modesto.

Author: Ing. Luis

A lo largo de conocer Windows y otros sistemas operativos me eh encontrado con diversos tipos de error, ahora brindo soluciones según mi experiencia-

Deja un comentario