Couchbase Analytics está optimizado para realizar consultas analíticas ad-hoc, que normalmente procesan más datos de los que caben en la memoria. Emplea un motor de procesamiento paralelo masivo (MPP) que intenta utilizar al máximo la potencia de procesamiento disponible en cualquier nodo que esté ejecutando el servicio Analytics en un clúster Couchbase. Al mismo tiempo, el motor se asegura de operar dentro del presupuesto de memoria asignado al servicio Analytics en cada nodo. Para conseguirlo, el servicio Analytics tiene una función de control de admisión de consultas que decide qué consultas pueden ejecutarse concurrentemente. En este artículo, explicamos los fundamentos del funcionamiento del mecanismo de control de admisión de consultas de Analytics y ofrecemos algunos ejemplos.
El controlador de admisión de consultas de Analytics decide si una consulta recién recibida puede ejecutarse inmediatamente, debe ponerse en cola o debe rechazarse. Las decisiones se toman en función de 1) los recursos disponibles para el servicio Analytics y 2) los recursos requeridos por una consulta determinada. A continuación se explica cómo se calcula cada uno de ellos.
Recursos analíticos disponibles:
Analytics mantiene una reserva de recursos de los siguientes:
Memoria total disponible para el procesamiento de consultas:
Por defecto, Analytics dedica 50% de la memoria asignada al servicio Analytics en cada nodo al procesamiento de consultas. Los otros 50% se utilizan para otras áreas como su caché de búfer de almacenamiento y su pipeline de ingesta. Sumando los 50% de memoria en cada nodo obtendremos la memoria total disponible para el procesamiento de consultas en Analytics.
Por ejemplo, si un cluster tiene tres nodos ejecutando el servicio Analytics, cada uno con 16GB de memoria, entonces:
1 2 |
Memoria total disponible para el procesamiento de consultas = Suma(50% de memoria asignada en cada nodo) = 8 GB + 8 GB + 8 GB = 24GB |
Total de trabajadores de consulta:
Analytics utiliza el número de núcleos informado por el sistema operativo para determinar el número de núcleos en cada nodo de Analytics. Sumando el número de núcleos en cada nodo y luego multiplicando por el núcleosMultiplicador nos da el número total de query workers disponibles para el procesamiento de consultas. Dado que las consultas analíticas ad-hoc tienden a estar ligadas a IO, un núcleo de CPU puede participar en el procesamiento de otras consultas concurrentes mientras otra consulta está esperando IO. El multiplicador de núcleos, que es un parámetro configurable en el servicio Analytics que tiene un valor predeterminado de 3, le ofrece la posibilidad de especificar ese nivel de concurrencia por núcleo con el fin de garantizar que cada núcleo tenga suficiente trabajo para mantenerse ocupado.
Por ejemplo, si un clúster tiene tres nodos con el servicio Analytics y cada uno tiene 8 núcleos y coresMultiplier se establece en 3, entonces:
1 2 |
Total query workers = Sum(cores in each node) * coresMultiplier = (8 + 8 + 8) * 3 = 72 |
Consulta de recursos necesarios:
Cuando el procesador de consultas de Analytics recibe una nueva consulta, el compilador de consultas determina los recursos necesarios para procesar la consulta en términos de memoria y trabajadores de consulta:
Memoria necesaria:
La memoria necesaria para cada consulta varía en función de su naturaleza. Por ejemplo, una consulta que requiera ordenar el resultado necesitará normalmente más memoria que una consulta simple que sólo cuente el número de documentos de una colección o recupere documentos en un pequeño rango de valores para algún campo. El compilador de consultas de Analytics examina todas las operaciones implicadas en una consulta y determina la memoria máxima requerida por cada consulta.
Trabajadores de consulta requeridos:
Un despliegue típico de Analytics tiene una partición de datos (shard) por núcleo en cada nodo. Dado que Analytics intenta procesar datos en todas las particiones de datos de un clúster en paralelo, los trabajadores de consulta necesarios para cualquier consulta que requiera acceso a datos es igual al número de particiones de datos.
Por ejemplo, una consulta que intente contar todos los documentos de una colección en un cluster que tenga 24 particiones de datos requerirá el uso de 24 query workers.
Ejemplos:
En los ejemplos siguientes, suponemos un clúster Couchbase que tiene 3 nodos ejecutando el servicio Analytics con 16 GB de memoria y 8 núcleos en cada uno.
Ejemplo 1:
multiplicadorNúcleos = 3
Memoria total disponible = 48 GB
Total de trabajadores de consulta disponibles = (8 + 8 + 8) * 3 = 72 trabajadores
Número de consultas concurrentes recibidas = 5 (cada una requiere 2 GB de memoria y 24 trabajadores)
Analytics ejecutará 3 consultas simultáneamente y pondrá en cola las consultas 4 y 5, ya que el clúster sólo tiene 72 trabajadores de consulta disponibles y cada consulta requiere 24 trabajadores. Una vez finalizada una de las 3 primeras consultas, se ejecutará una de las consultas en cola. (Nota: No ayudaría al rendimiento admitir inmediatamente las consultas 4 y 5 en lugar de ponerlas en cola, ya que el sistema tiene suficiente trabajo para mantenerse ocupado con las tres primeras. Intentar hacer más de una vez no aceleraría las cosas y, de hecho, podría llevar a una contención de recursos contraproducente).
Ejemplo 2:
multiplicadorNúcleos = 3
Memoria total disponible = 48 GB
Total de trabajadores de consulta disponibles = (8 + 8 + 8) * 3 = 72 trabajadores
Número de consultas concurrentes recibidas = 3 (cada una requiere 20 GB de memoria y 24 trabajadores)
Analytics ejecutará dos consultas concurrentemente y pondrá en cola la tercera consulta ya que no tenemos suficiente memoria para ejecutar las tres concurrentemente. (Nota: Intentar hacer más reduciendo la memoria asignada a cada consulta probablemente conduciría a un mayor derrame de datos, un mayor coste de E/S y, por tanto, un menor rendimiento).
Ejemplo 3:
multiplicadorNúcleos = 3
Memoria total disponible = 48 GB
Total de trabajadores de consulta disponibles = (8 + 8 + 8) * 3 = 72 trabajadores
Número de consultas concurrentes recibidas = 1 (requiere 50 GB de memoria y 24 trabajadores)
Analytics rechazará la consulta ya que no dispone de memoria suficiente para ejecutarla. Tenga en cuenta que la adición de un nodo adicional de Analytics al clúster aumentará los recursos disponibles y podría hacer posible la ejecución de dicha consulta. (Nota: También se puede utilizar una sugerencia de consulta para indicar a una consulta que asigne menos memoria a los operadores de la consulta, permitiendo que la consulta se ejecute aunque con un mayor coste de E/S).
Ejemplo 4:
multiplicadorNúcleos = 5
Memoria total disponible = 48 GB
Total de trabajadores de consulta disponibles = (8 + 8 + 8) * 5 = 120 trabajadores
Número de consultas concurrentes recibidas = 5 (cada una requiere 2 GB de memoria y 24 trabajadores)
Analytics ejecutará las 5 consultas concurrentemente ya que tenemos suficiente memoria y query workers. Es importante tener en cuenta que, aunque aumentar el valor de coresMultiplier permitirá ejecutar más consultas de forma concurrente, podría dar lugar a un menor rendimiento general si el almacenamiento subyacente no puede gestionar las solicitudes de E/S concurrentes o si los núcleos de la CPU empiezan a fallar, como se ha mencionado anteriormente. Por lo tanto, al ajustar el parámetro coresMultiplier, puede ser necesario un cuidadoso ejercicio de ajuste basado en los recursos disponibles y la naturaleza de la carga de trabajo.
Conclusión:
En este artículo, hemos explicado cómo funciona la lógica de control de admisión de consultas del servicio Analytics y los factores que utiliza para tomar decisiones de admisión de consultas. También hemos explicado cómo se puede utilizar el parámetro coresMultiplier para permitir la ejecución concurrente de más consultas y las consecuencias de cambiar su valor.
blog muy bien escrito y muy bien articulado con ejemplos y matemáticas detrás de control de admisión de consultas! buen trabajo.